Pydantic dice que puede crear clases personalizadas simplemente definiendo el método __get_validators__ . Esto es útil si desea analizar una clase con su propia metaclase o por alguna otra razón no desea heredar de BaseModel .
Sin embargo, esto falla en lugares extraños en FastAPI. Por ejemplo, FastAPI no detecta una clase como un parámetro de cuerpo, pero siempre piensa que es un parámetro de consulta.
from fastapi import FastAPI, Body from fastapi.testclient import TestClient app = FastAPI() class NastyMetaClass(type): pass class Foo(metaclass=NastyMetaClass): @classmethod def __get_validators__(cls): yield lambda value: True @app.post("/implicit") def foo(foo: Foo): # This is supposed to work, but does not return "It worked" @app.post("/explicit") def foo_body(foo: Foo = Body(...)): # The `= Body(...)` fixes it return "It worked" client = TestClient(app) response = client.post("/implicit", json={}) print(response.json()) # {'detail': [{'loc': ['query', 'foo'], 'msg': 'field required', 'type': 'value_error.missing'}]} response = client.post("/explicit", json={}) print(response.json()) # It worked¿Cómo puedo hacer que FastAPI reconozca las clases Pydantic personalizadas?
Según la documentación de FastAPI , cuando usa Body(...) le indica a FastAPI que trate un parámetro como una clave de body . Por lo tanto, usar foo: Foo = Body(...) es una forma de decirle a su terminal que espere un cuerpo JSON con los atributos de Foo .
Alternativamente, puede definir el parámetro Foo usando Dependencies , como se muestra a continuación:
from fastapi import Depends @app.post("/implicit") def foo(foo: Foo = Depends(Foo)): # This should work return "It worked" Incluso podría simplemente usar Depends() (es decir, foo: Foo = Depends() ) como atajo para evitar la repetición del código.