-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Description
First check
- I used the GitHub search to find a similar issue and didn't find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google "How to X in FastAPI" and didn't find any information.
Description
What's the best way to define a custom data type that works with both pydantic and JSON Schema?
To illustrate, let's say we want to implement a custom Arrow datetime type (this was also asked in #1186). Borrowing the approach from #452, we could implement the following:
class Arrow(datetime.datetime):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
return arrow.get(v)This is kind of weird for 2 reasons:
-
We have to inherit from
datetime.datetimein order for JSON Schema to recognize that this should be represented as a datetime-formatted string. This isn't entirely intuitive — someone could reasonably wonder why we're inherting fromdatetime.datetime, but then returning anArrowobject invalidate. -
This only lets us define how we want to decode from JSON. To handle encoding, I have to use
json_encodersin my model:
class TestModel(pydantic.BaseModel):
datetime: Arrow
class Config:
json_encoders = {arrow.Arrow: lambda obj: obj.isoformat()}Notice how the json_encoders entry references an arrow.Arrow object, and not the Arrow type that was defined earlier. This also seems suboptimal.
Is this the correct way to implement custom types? Or is there a better solution?
Ideally I'd love to be able to be able to define a custom type similar to the way marshmallow handles it (i.e., by overriding _serialize and _deserialize methods):
https://marshmallow.readthedocs.io/en/stable/custom_fields.html
Additional context
I recognize that the second point is more closely related to pydantic than it is to fastapi, and certainly there's been some discussion about it (see pydantic/pydantic#951). But that still doesn't address the first point around playing nicely with JSON schema.
I'm kind hoping fastapi can do something on top of pydantic to make this all a bit smoother.