Skip to content

Commit

Permalink
feat: enhance schema handling with new json schema generation
Browse files Browse the repository at this point in the history
- Updated `TypeIDType` in `typeid.py` to enhance JSON schema generation by overriding the `__get_pydantic_json_schema__` method.
- Modified the `pyproject.toml` to add new dependencies: `pydantic` and `fastapi`.
- Added new test files `fastapi_test.py` and `models.py` to verify functionality and model behaviors.
- Refactored `typeid_test.py` to utilize new model definitions, removing redundant class definitions.

Generated-by: aiautocommit
  • Loading branch information
iloveitaly committed Jan 13, 2025
1 parent 61d5849 commit 3ba47b6
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 16 deletions.
35 changes: 34 additions & 1 deletion activemodel/types/typeid.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,47 @@ def __get_pydantic_core_schema__(
# TODO not sure how this is different from the UUID schema, should try it out.
# core_schema.is_instance_schema(TypeID),
core_schema.uuid_schema(),
core_schema.no_info_plain_validator_function(TypeID.from_string),
core_schema.no_info_plain_validator_function(
TypeID.from_string,
json_schema_input_schema=core_schema.str_schema(),
),
]
)

return core_schema.json_or_python_schema(
json_schema=from_uuid_schema,
# metadata=core_schema.str_schema(
# pattern="^[0-9a-f]{24}$",
# min_length=24,
# max_length=24,
# ),
# metadata={
# "pydantic_js_input_core_schema": core_schema.str_schema(
# pattern="^[0-9a-f]{24}$",
# min_length=24,
# max_length=24,
# )
# },
python_schema=core_schema.union_schema([from_uuid_schema]),
serialization=core_schema.plain_serializer_function_ser_schema(
lambda x: str(x)
),
)

@classmethod
def __get_pydantic_json_schema__(
cls, schema: CoreSchema, handler: GetJsonSchemaHandler
):
"""
Called when generating the openapi schema. This overrides the `function-plain` type which
is generated by the `no_info_plain_validator_function`.
This logis seems to be a hot part of the codebase, so I'd expect this to break as pydantic
fastapi continue to evolve.
Note that this method can return multiple types. A return value can be as simple as:
{"type": "string"}
"""

return core_schema.uuid_schema()
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ dev = [
"pdbr>=0.8.9",
"psycopg[binary]>=3.2.3",
"pytest>=8.3.3",
"pydantic>=2.10.0",
"fastapi>=0.115.6",
]
18 changes: 18 additions & 0 deletions test/fastapi_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from fastapi import FastAPI

from test.models import ExampleWithId


def fake_app():
api_app = FastAPI() # type: ignore

@api_app.get("/typeid")
async def index() -> ExampleWithId:
return "hi"

return api_app


def test_openapi():
openapi = fake_app().openapi()
breakpoint()
15 changes: 15 additions & 0 deletions test/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from activemodel import BaseModel
from activemodel.mixins import TypeIDMixin
from activemodel.types.typeid import TypeIDType
from sqlmodel import Relationship

TYPEID_PREFIX = "myid"


class AnotherExample(BaseModel, TypeIDMixin("myotherid"), table=True):
pass


class ExampleWithId(BaseModel, TypeIDMixin(TYPEID_PREFIX), table=True):
another_example_id: TypeIDType = AnotherExample.foreign_key(nullable=True)
another_example: AnotherExample = Relationship()
16 changes: 1 addition & 15 deletions test/typeid_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
from pydantic import BaseModel as PydanticBaseModel
from typeid import TypeID

from test.models import TYPEID_PREFIX, ExampleWithId
from test.utils import temporary_tables

from activemodel import BaseModel
from activemodel.mixins import TypeIDMixin
from activemodel.types.typeid import TypeIDType
from sqlmodel import Relationship


def test_enforces_unique_prefixes():
Expand All @@ -24,18 +22,6 @@ def test_no_empty_prefixes_test():
TypeIDMixin("")


TYPEID_PREFIX = "myid"


class AnotherExample(BaseModel, TypeIDMixin("myotherid"), table=True):
pass


class ExampleWithId(BaseModel, TypeIDMixin(TYPEID_PREFIX), table=True):
another_example_id: TypeIDType = AnotherExample.foreign_key(nullable=True)
another_example: AnotherExample = Relationship()


def test_get_through_prefixed_uid():
type_uid = TypeID(prefix=TYPEID_PREFIX)

Expand Down

0 comments on commit 3ba47b6

Please sign in to comment.