redis-om-python icon indicating copy to clipboard operation
redis-om-python copied to clipboard

FastAPI (v0.100.0) / Pydantic v2 incompatibility

Open ninoseki opened this issue 2 years ago • 5 comments

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.

ninoseki avatar Jul 13 '23 00:07 ninoseki

Appreciate the honesty. What's the most recent working version of FastAPI? Will 0.1.4 still work with pydantic v1?

Update: I checked pydantic v1 with FastAPI 0.100.0 Everything, seems to work fine. I think the problem is just with v2.

XChikuX avatar Jul 14 '23 03:07 XChikuX

Yes you can use the latest FastAPI (v0.100.0) with Pydantic v1. The latest redis-om can handle Pydantic v1 too. So the following dependencies are safe to use.

fastapi = "0.100.0"
pydantaic = ">=1.10.2,<2.0"
redis-om = "0.1.3"

ninoseki avatar Jul 14 '23 04:07 ninoseki

I got similar error @ninoseki How can i handle if i use post method it gives me save is not working it's my first time of using redis plz help

PARKER-X avatar Aug 16 '23 06:08 PARKER-X

I got similar error @ninoseki How can i handle if i use post method it gives me save is not working it's my first time of using redis plz help

pip install pydantic==1.10.13 should solve your problem

dgtlmonk avatar Sep 30 '23 07:09 dgtlmonk

thanks @dgtlmonk ! It worked for me

valentina-buoro avatar Nov 01 '23 13:11 valentina-buoro