Additional Responses in OpenAPI and Mypy #12056
-
First Check
Commit to Help
Example Codefrom fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Message(BaseModel):
message: str
responses = {
403: {"model": Message, "description": "Not enough privileges"},
404: {"model": Message, "description": "Item not found"},
}
@app.get("/items/{item_id}", responses={**responses})
def read_item(item_id: int):
passDescriptionI don't think FastAPI is the root cause of the problem. I think it has to do with how Mypy handles dictionary unpacking. But I'd be glad the view of those familiar with Mypy. As per Additional Responses in OpenAPI, I often use this pattern: responses = {
403: {"model": Message, "description": "Not enough privileges"},
404: {"model": Message, "description": "Item not found"},
}
@app.get("/endpoint1/{item_id}", responses={**responses})
@app.get("/endpoint2/{item_id}", responses={**responses})
@app.get("/endpoint3/{item_id}", responses={**responses})Which is very convenient, as it allows to reuse same error responses across multiple endpoints. Problem is: it doesn't pass Mypy checking. $ mypy api.py
api.py:17: error: Unpacked dict entry 0 has incompatible type "dict[int, dict[str, object]]"; expected "SupportsKeysAndGetItem[int | str, dict[str, Any]]" [dict-item]
Found 1 error in 1 file (checked 1 source file)As a workaround, I am using: from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Message(BaseModel):
message: str
e403 = {"model": Message, "description": "Not enough privileges"}
e404 = {"model": Message, "description": "Item not found"}
@app.get("/items/{item_id}", responses={403: e403, 404: e404})
def read_item(item_id: int):
passWhich indeed passes Mypy checking: $ mypy api.py
Success: no issues found in 1 source fileBut it is less convenient to use. Are you aware of a better solution? Without ignoring faulty lines. Thanks! Operating SystemLinux Operating System DetailsNo response FastAPI Version0.112.1 Pydantic Version2.8.2 Python Version3.10.12 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
You can solve this by adding the explicit type annotation to from typing import Any
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
class Message(BaseModel):
message: str
responses: dict[int | str, dict[str, Any]] = {
403: {"model": Message, "description": "Not enough privileges"},
404: {"model": Message, "description": "Item not found"},
}
@app.get("/endpoint1/{item_id}", responses={**responses})
async def endpoint1(item_id: int):
return {"message": str(item_id)} |
Beta Was this translation helpful? Give feedback.
You can solve this by adding the explicit type annotation to
responses: