OpenAPI examples not working when embed is set to true #10600
-
First Check
Commit to Help
Example Codefrom fastapi import FastAPI, Body
from typing import Annotated
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str | None = None
@app.post("/items/{item_id}")
async def create_item(
item_id: int,
item: Annotated[
Item,
Body(
# embed=True,
openapi_examples={
"normal": {
"summary": "A normal example",
"description": "A **normal** item works correctly.",
"value": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
"converted": {
"summary": "An example with converted data",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"name": "Bar",
"price": "35.4",
},
},
"invalid": {
"summary": "Invalid data is rejected with an error",
"value": {
"name": "Baz",
"price": "thirty five point four",
},
},
},
),
],
):
return {"item_id": item_id, "item": item}DescriptionWhen I tried to embed the JSON in the Body with embed=True property I cannot use openapi_examples section in the SwaggerUI. Is it the expected behavior? Operating SystemLinux Operating System DetailsNo response FastAPI Version0.104.1 Pydantic Version2.4.2 Python Version3.10.12 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
Yes, this is expected behavior. Examples that you see in Swagger UI are the examples of request body object. When you don't specify But when you specify Every example should be now: Notice, values are inside I think it's possible to implement logic so that FastAPI would be able to add examples if the request body consists of only one object. But it would still get broken as soon as you add one more model or single body parameter. You can specify parameters for the whole request body manually using from fastapi import FastAPI, Body
from typing import Annotated
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str | None = None
@app.post(
"/items/{item_id}",
openapi_extra={
"requestBody": {
"required": True,
"content": {
"application/json": {
"examples": {
"normal": {
"summary": "A normal example",
"description": "A **normal** item works correctly.",
"value": {
"item": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
},
"converted": {
"summary": "An example with converted data",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"item": {
"name": "Bar",
"price": "35.4",
},
},
},
"invalid": {
"summary": "Invalid data is rejected with an error",
"value": {
"item": {
"name": "Baz",
"price": "thirty five point four",
},
},
},
}
}
},
}
},
)
async def create_item(
item_id: int,
item: Annotated[Item, Body(embed=True)],
):
return {"item_id": item_id, "item": item} |
Beta Was this translation helpful? Give feedback.
Yes, this is expected behavior.
Examples that you see in Swagger UI are the examples of request body object.
When you don't specify
embed=Trueand this model is only one body parameter you are using, then the whole request body equals to this model. So, FastAPI can use examples of this model for this request body object.But when you specify
embed=Trueor you are using other body parameters along with this model, the whole request body is not equal to your model. It should be a combination of all models and single parameters. FastAPI can't just use examples of one model as examples of whole request body.Every example should be now: