Skip to content

Commit

Permalink
Outline of comilation flow
Browse files Browse the repository at this point in the history
  • Loading branch information
daquinteroflex committed Oct 18, 2024
1 parent 65d0b95 commit 3a06893
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 39 deletions.
4 changes: 2 additions & 2 deletions autoflex/constructors/parameter_table.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""
This file contains the structure of a ParameterTable.
"""
from autoflex.types import AutoflexPropertyTypes
from autoflex.types import PropertyTypes

def extract_class_to_parameter_table(physcial_parameter: AutoflexPropertyTypes) -> ParameterTable:
def extract_class_to_parameter_table(physcial_parameter: PropertyTypes) -> ParameterTable:
"""
This method converts from a given class or schema declaration into a container of data required for a ParameterTable
in its intended implementation.
Expand Down
4 changes: 2 additions & 2 deletions autoflex/descriptors/field.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from dataclasses import field
from typing import Any, Optional
from pydantic import Field
from autoflex.types import AutoflexFieldInfo, AutoflexPropertyTypes
from autoflex.types import AutoflexFieldInfo, PropertyTypes


def AutoflexField(
default: Any = ...,
*,
autoflex_parameters: Optional[AutoflexPropertyTypes] = None,
autoflex_parameters: Optional[PropertyTypes] = None,
**kwargs
) -> AutoflexFieldInfo:
"""
Expand Down
50 changes: 34 additions & 16 deletions autoflex/extractors.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
from pydantic import BaseModel
from autoflex.types import AutoflexPropertyTypes
"""
Note that the compilation flow is as follows:
def determine_pydantic_version_from_base_model(model: BaseModel):
"""Determine if a BaseModel is from Pydantic v1 or v2."""
if hasattr(model, 'model_fields'):
return 2
elif hasattr(model, '__fields__'):
return 1
else:
raise ValueError("Unknown Pydantic version or incompatible BaseModel class.")
.. code::
FieldTypes -> PropertyTypes
PhysicalFieldInfo -> PhysicalProperty
pd.FieldInfo -> Property
def get_field_infos(model: BaseModel):
Then, this automated flow can be run for a given BaseModel and the properties can be extracted accordingly.
"""
import pydantic as pd
from autoflex.types import PropertyTypes, FieldTypes, PhysicalProperty, PhysicalFieldInfo, Property
from autoflex.version_manager import determine_pydantic_version_from_base_model

def get_field_infos(model: pd.BaseModel):
"""Get all FieldInfo instances from a Pydantic model, compatible with v1 and v2."""
version = determine_pydantic_version_from_base_model(model)

Expand All @@ -30,11 +32,27 @@ def get_field_infos(model: BaseModel):
return field_infos


def get_all_property_annotations(model: BaseModel) -> list[AutoflexPropertyTypes]:
def physical_field_info_to_physical_property(field: PhysicalFieldInfo) -> PhysicalProperty:
"""
"""
pass


def field_info_to_property(field: pd.fields.FieldInfo) -> Property:
"""
"""
pass


def auto_field_to_property_type(field: FieldTypes) -> PropertyTypes:

pass


def extract_property_list_from_model(model: pd.BaseModel) -> list[PropertyTypes]:
"""
This function will analyse all the properties within a BaseModel. It will extract the annotation and FieldInformation
from the given class encoding. This will create a list of PropertyTypes with all the relevant documentation information
accordingly.
The selected compiled Property depends on the existing fields within the Field.
"""
pass
4 changes: 2 additions & 2 deletions autoflex/types/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from autoflex.types.property import PhysicalProperty, Property, AutoflexPropertyTypes
from autoflex.types.property import PhysicalProperty, Property, PropertyTypes
from autoflex.types.descriptors import Symbolic, SymbolicTypes, Unit, UnitTypes
from autoflex.types.field import AutoflexFieldInfo, FieldTypes
from autoflex.types.field import PhysicalFieldInfo, FieldTypes
18 changes: 12 additions & 6 deletions autoflex/types/field.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import pydantic as pd
from autoflex.types.property import AutoflexPropertyTypes
from autoflex.types.descriptors import UnitTypes, SymbolicTypes

class AutoflexFieldInfo(pd.fields.FieldInfo):
class PhysicalFieldInfo(pd.fields.FieldInfo):
"""
Each field should correspond to an individual parameter field that can represent it completely within the documentation.
Each field should correspond to an individual physical property field that can represent it completely within the documentation.
Note that this compiles into a PhysicalProperty accordingly.
"""

unit: UnitTypes = None
"""
json_schema_extra: dict = None
"""
TODO overwrite this with the supported attributes from the given properties.

math: SymbolicTypes = None
"""
"""


FieldTypes = AutoflexFieldInfo | pd.fields.FieldInfo
FieldTypes = PhysicalFieldInfo | pd.fields.FieldInfo
2 changes: 1 addition & 1 deletion autoflex/types/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ class PhysicalProperty(Property):
unit: UnitTypes = Field(..., description="The unit of the physical parameter")


AutoflexPropertyTypes = PhysicalProperty | Property
PropertyTypes = PhysicalProperty | Property
4 changes: 2 additions & 2 deletions autoflex/types/structures.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from autoflex.types import AutoflexPropertyTypes
from autoflex.types import PropertyTypes

PropertyCollectionTable = list[AutoflexPropertyTypes]
PropertyCollectionTable = list[PropertyTypes]
"""
A property table can be compiled from a list of compiled AutoflexProperties in a standard data type format.
"""
10 changes: 10 additions & 0 deletions autoflex/version_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import pydantic as pd

def determine_pydantic_version_from_base_model(model: pd.BaseModel):
"""Determine if a BaseModel is from Pydantic v1 or v2."""
if hasattr(model, 'model_fields'):
return 2
elif hasattr(model, '__fields__'):
return 1
else:
raise ValueError("Unknown Pydantic version or incompatible BaseModel class.")
5 changes: 5 additions & 0 deletions docs/api/fields.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


.. code::
16 changes: 9 additions & 7 deletions docs/examples/usage_performance.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -413,27 +413,29 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 31,
"id": "a7c5de53-46e1-45aa-b4ec-43d03bb9b582",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"FieldInfo(annotation=NoneType, required=True, json_schema_extra={'extra': {'unit': 'ms', 'math': 's + 1'}})"
"FieldInfo(annotation=NoneType, required=True, json_schema_extra={'unit': 'ms', 'math': 's + 1'})"
]
},
"execution_count": 22,
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# help(pd.fields.Field)\n",
"pd.fields.Field(extra={\n",
" \"unit\": \"ms\",\n",
" \"math\": \"s + 1\"\n",
"})"
"pd.fields.Field(\n",
" json_schema_extra={\n",
" \"unit\": \"ms\",\n",
" \"math\": \"s + 1\"\n",
"}\n",
")"
]
},
{
Expand Down
28 changes: 27 additions & 1 deletion tests/extractors/test_field_extractors.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import demo
import autoflex

def test_get_field_infos():
import demo

basic_class = demo.BasicClass()
basic_mixed_class = demo.BasicMixedAnnotatedClass()

Expand All @@ -13,3 +14,28 @@ def test_get_field_infos():
assert len(basic_mixed_class_fields) == 4, f"Expected 4 fields, found {len(basic_mixed_class_fields)}"


def test_automatic_field_to_property_extractor():
import pydantic as pd

# help(pd.fields.Field)
field_json_schema_extras = pd.fields.Field(
json_schema_extra={
"unit": "ms",
"math": "s + 1"
}
)

field_extra = pd.fields.Field(
extra={
"unit": "ms",
"math": "s + 1"
}
)


aufoflex_physical_field_extra = pd.fields.Field(
json_schema_extra={
"unit": "ms",
"math": "s + 1"
}
)

0 comments on commit 3a06893

Please sign in to comment.