typing.Type field breaks Swagger #8866
-
Examplefrom typing import Type
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
class Container(BaseModel):
T: Type
app = FastAPI()
@app.get("/", response_model=Container)
def index(container: Container):
return container
if __name__ == "__main__":
uvicorn.run("app:app")Description
Environment
Additional contextStack trace from the server: The functionality that I want in my use case works correctly: I tested the API and custom (de)serialization logic is OK, I get what I want from it, but both I wanted to use generic models for this (and they worked wonderfully), but I also need to send type information to the frontend, and there's no (officially supported, reliable) way to get this in runtime. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
|
What about using |
Beta Was this translation helpful? Give feedback.
-
|
|
Beta Was this translation helpful? Give feedback.
-
|
FastAPI doesn't know how to deal with such type of field. So, you need to manually define schema, validator and serializer for it. Something like this: from typing import Type, Annotated
from fastapi import FastAPI
from pydantic import BaseModel, field_serializer, field_validator
from pydantic.json_schema import WithJsonSchema
class MyType(BaseModel):
a: str
class Container(BaseModel):
T: Annotated[Type, WithJsonSchema({"type": "string"})]
@field_validator("T", mode="plain")
@classmethod
def validate_type(cls, value: Type) -> Type:
if isinstance(value, type):
return value
elif isinstance(value, str):
try:
return globals()[value]
except KeyError:
raise ValueError(f"Type '{value}' not found in globals.")
return value
@field_serializer("T")
def serialize_type(self, value: Type) -> str:
return value.__name__
app = FastAPI()
@app.post("/", response_model=Container)
def index(container: Container):
return container
from fastapi.testclient import TestClient
def test_success():
client = TestClient(app)
response = client.post("/", json={"T": "MyType"})
assert response.status_code == 200
assert response.json() == {"T": "MyType"}
def test_failure():
client = TestClient(app)
response = client.post("/", json={"T": "NonExistentType"})
assert response.status_code == 422
assert "Type 'NonExistentType' not found in globals." in response.text |
Beta Was this translation helpful? Give feedback.

FastAPI doesn't know how to deal with such type of field. So, you need to manually define schema, validator and serializer for it.
Something like this: