Skip to content

Commit

Permalink
Consolidated classes a bit more
Browse files Browse the repository at this point in the history
  • Loading branch information
daquinteroflex committed Oct 11, 2024
1 parent 37b76d0 commit e267a9d
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 107 deletions.
29 changes: 29 additions & 0 deletions autoflex/extractors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from pydantic import BaseModel

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.")


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

field_infos = []

# Handle Pydantic v2
if version == 2:
for field_name, field in model.model_fields.items():
field_infos.append(field)

# Handle Pydantic v1
elif version == 1:
for field_name, field in model.__fields__.items():
field_infos.append(field)

return field_infos
Empty file added autoflex/types/__init__.py
Empty file.
8 changes: 8 additions & 0 deletions autoflex/types/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from pydantic import BaseModel

class AutoflexBaseModel(BaseModel):
"""
A base class that can be used for any model within the system.
It inherits from Pydantic's BaseModel to leverage data validation
and parsing features.
"""
44 changes: 12 additions & 32 deletions autoflex/types.py → autoflex/types/descriptors.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
"""
This contains all the relevant types used for the documentation constructors and base definition.
"""

from pydantic import BaseModel, validator, Field
import pydantic.fields
from pydantic import Field
from typing import Union
from autoflex.types.core import AutoflexBaseModel


class AutoflexBaseClass(BaseModel):
"""
A base class that can be used for any model within the system.
It inherits from Pydantic's BaseModel to leverage data validation
and parsing features.
"""


class Symbolic(AutoflexBaseClass):
class Symbolic(AutoflexBaseModel):
"""
A class representing a symbolic representation of a label and math formula.
Expand All @@ -25,7 +20,8 @@ class Symbolic(AutoflexBaseClass):
label: str = Field(..., description="Label of the symbolic representation")
math: str = Field(..., description="Mathematical representation or equation")

class Unit(AutoflexBaseClass):

class Unit(AutoflexBaseModel):
"""
A class representing a physical unit.
Expand All @@ -38,8 +34,7 @@ class Unit(AutoflexBaseClass):
symbol: str | Symbolic = Field(..., description="Symbol for the unit")
description: str = Field(None, description="Optional description of the unit")


class PhysicalParameter(AutoflexBaseClass):
class PhysicalParameter(AutoflexBaseModel):
"""
A class representing a physical parameter, which includes both
the unit and its defining mathematical representation.
Expand All @@ -51,23 +46,8 @@ class PhysicalParameter(AutoflexBaseClass):
unit: Union[str, Symbolic, Unit] = Field(..., description="The unit of the physical parameter")
math: Union[str, Symbolic] = Field(..., description="The mathematical representation defining the physical parameter in latex")

#
# class AttributeDocumentation(AutoflexBaseClass):
# name: str
# units: Unit
# types: pydantic.BaseModel
#
# class MethodDocumentationSchema(AutoflexBaseClass):
# name: str
# description: str
#
#
# class ClassDocumentation(AutoflexBaseClass):
# """
#
# """
# attribute_list = list[AttributeDocumentation]
# method_list = list[MethodDocumentationSchema]
#
# class ParameterTable(AutoflexBaseClass):
# pass
AutoflexParameterTypes = PhysicalParameter


class AutoflexFieldInfo(pydantic.fields.FieldInfo):
autoflex: AutoflexParameterTypes
9 changes: 9 additions & 0 deletions autoflex/types/structures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from autoflex.types.core import AutoflexBaseModel
from autoflex.types.descriptors import AutoflexParameterTypes


class ParameterTable(AutoflexBaseModel):
name: str
types: str
description: str
special_parameters: AutoflexParameterTypes
31 changes: 0 additions & 31 deletions autoflex/validators.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,5 @@
from pydantic.fields import FieldInfo
from pydantic import BaseModel

def check_json_schema_extra(field: FieldInfo) -> bool:
"""Check if the FieldInfo contains a 'json_schema_extra' parameter."""
return hasattr(field, 'json_schema_extra') and field.json_schema_extra is not None



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.")


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

field_infos = []

# Handle Pydantic v2
if version == 2:
for field_name, field in model.model_fields.items():
field_infos.append(field)

# Handle Pydantic v1
elif version == 1:
for field_name, field in model.__fields__.items():
field_infos.append(field)

return field_infos
140 changes: 96 additions & 44 deletions docs/examples/usage_performance.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 18,
"id": "b4a9de07-0f79-4fc3-b3e2-a33187e66142",
"metadata": {},
"outputs": [],
Expand All @@ -375,10 +375,22 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 15,
"id": "5f6541f0-7ee6-47a2-97d0-a7a6574d9e0e",
"metadata": {},
"outputs": [],
"outputs": [
{
"ename": "NameError",
"evalue": "name 'PhysicalParameter' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[15], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# help(pd.fields.Field)\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m pd\u001b[38;5;241m.\u001b[39mfields\u001b[38;5;241m.\u001b[39mField(extra\u001b[38;5;241m=\u001b[39m\u001b[43mPhysicalParameter\u001b[49m())\n",
"\u001b[0;31mNameError\u001b[0m: name 'PhysicalParameter' is not defined"
]
}
],
"source": [
"# help(pd.fields.Field)\n",
"pd.fields.Field(extra=PhysicalParameter())"
Expand All @@ -391,70 +403,110 @@
"metadata": {},
"outputs": [],
"source": [
"from pydantic.fields import FieldInfo\n",
"from pydantic import BaseModel\n",
"\n",
"def check_json_schema_extra(field: FieldInfo) -> bool:\n",
" \"\"\"Check if the FieldInfo contains a 'json_schema_extra' parameter.\"\"\"\n",
" return hasattr(field, 'json_schema_extra') and field.json_schema_extra is not None\n",
"\n",
"\n",
"\n",
"def determine_pydantic_version_from_base_model(model: BaseModel):\n",
" \"\"\"Determine if a BaseModel is from Pydantic v1 or v2.\"\"\"\n",
" if hasattr(model, 'model_fields'):\n",
" return 2\n",
" elif hasattr(model, '__fields__'):\n",
" return 1\n",
" else:\n",
" raise ValueError(\"Unknown Pydantic version or incompatible BaseModel class.\")\n",
"\n",
"\n",
"def get_field_infos(model: BaseModel):\n",
" \"\"\"Get all FieldInfo instances from a Pydantic model, compatible with v1 and v2.\"\"\"\n",
" version = determine_pydantic_version_from_base_model(model)\n",
"\n",
" field_infos = []\n",
"\n",
" # Handle Pydantic v2\n",
" if version == 2:\n",
" for field_name, field in model.model_fields.items():\n",
" field_infos.append(field)\n",
"\n",
" # Handle Pydantic v1\n",
" elif version == 1:\n",
" for field_name, field in model.__fields__.items():\n",
" field_infos.append(field)\n",
"\n",
" return field_infos\n"
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 16,
"id": "46d6cbba-f04a-424e-afa6-8db0fe85fc4c",
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"[ModelField(name='units', type=str, required=False, default='')]"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"get_field_infos(PhysicalParameterV1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 17,
"id": "d47f14ff-3aaf-4654-9f2d-969c6ab27162",
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/plain": [
"[FieldInfo(annotation=str, required=False, default='')]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"get_field_infos(PhysicalParameterV2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 23,
"id": "3f60ed00-d8b6-4d27-93bb-bbb7b72f2392",
"metadata": {},
"outputs": [],
"source": [
"class PhysicalFieldInfo(pd.fields.FieldInfo):\n",
" a: PhysicalParameterV1"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "1f9660a7-358b-4b79-9362-a6f58b5b1bd8",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"PhysicalFieldInfo(annotation=NoneType, required=True)"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"PhysicalFieldInfo()"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "bd8c92de-8168-490f-a368-8b2c12e2ebef",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"PhysicalFieldInfo(annotation=NoneType, required=True)"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"PhysicalFieldInfo()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "357d5275-e6ad-48bc-8727-fcc6e09a3e55",
"metadata": {},
"outputs": [],
"source": []
}
],
Expand Down

0 comments on commit e267a9d

Please sign in to comment.