Skip to content

FastAPI (v0.100.0) / Pydantic v2 incompatibility #539

Closed
@ninoseki

Description

@ninoseki

I'm sorry I think I made a mistake in #533.
I misunderstood that FastAPI (v0.100.0) has a compatibility in Pydantic v1 & v2 and it can use both versions as a response model & response body. But it doesn't.

For example, the following code fails because the latest FastAPI does not allow using Pydantic v1 as a response model & body class.

# test.py
import datetime
from typing import Optional

from fastapi import FastAPI
from redis_om import HashModel, get_redis_connection

REDIS_DATA_URL = "redis://localhost:6380"


class Customer(HashModel):
    first_name: str
    last_name: str
    email: str
    join_date: datetime.date
    age: int
    bio: Optional[str]


app = FastAPI()


@app.post("/customer")
async def save_customer(customer: Customer):
    return customer.save()


@app.get("/customers")
async def list_customers():
    return {"customers": Customer.all_pks()}


@app.on_event("startup")
async def startup():
    Customer.Meta.database = get_redis_connection(
        url=REDIS_DATA_URL, decode_responses=True
    )
  File "/Users/foo/test.py", line 32, in <module>
    @app.post("/customer")
  File "/Users/foo/ib/python3.11/site-packages/fastapi/routing.py", line 706, in decorator
  self.add_api_route(
  File "/Users/foo/ib/python3.11/site-packages/fastapi/routing.py", line 645, in add_api_route
  route = route_class(
  ^^^^^^^^^^^^
  File "/Users/foo/ib/python3.11/site-packages/fastapi/routing.py", line 491, in **init**
  self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foo/ib/python3.11/site-packages/fastapi/dependencies/utils.py", line 261, in get_dependant
  type_annotation, depends, param_field = analyze_param(
  ^^^^^^^^^^^^^^
  File "/Users/foo/ib/python3.11/site-packages/fastapi/dependencies/utils.py", line 429, in analyze_param
  field = create_response_field(
  ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/foo/ib/python3.11/site-packages/fastapi/utils.py", line 101, in create_response_field
  raise fastapi.exceptions.FastAPIError(
  fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'test.Customer'> is a valid Pydantic field type. If you are using a return type annotation that is not a valid Pydantic field (e.g. Union[Response, dict, None]) you can disable generating the response model from the type annotation with the path operation decorator parameter response_model=None. Read more: https://fastapi.tiangolo.com/tutorial/response-model/

There is a workaround like the following.

# Pydantic v2
class CustomerWrapper(BaseModel):
    first_name: str
    last_name: str
    email: str
    join_date: datetime.date
    age: int
    bio: Optional[str]


app = FastAPI()


@app.post("/customer")
async def save_customer(customer: CustomerWrapper):
    db_obj = Customer.parse_obj(customer.model_dump())
    return db_obj.save()

But I think it's not good.

So it will be better to revert #533 if the FastAPI support has the high priority in this library. Again, sorry for my careless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions