最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - How to display both applicationjson and applicationoctet-stream content types in Swagger UI autodocs in FastAPI? - Stac

programmeradmin2浏览0评论

I have an endpoint that can return JSON or a file (xlsx):

class ReportItemSerializer(BaseModel):
    id: int
    werks: Annotated[WerkSerializerWithNetwork, Field(validation_alias="werk")]
    plu: Annotated[str, Field(description="Название PLU")]
    start_date: Annotated[date, None, Field(description="Дата начала периода в формате")]
    end_date: Annotated[date | None, Field(description="Дата окончания периода")]
    anfmenge: Annotated[int | None, Field(des cription="Запас на начало периода")]
    endmenge: Annotated[int | None, Field(description="Остаток по PLU в разрезе поставщика на конец периода")]
    soll: Annotated[int, None, Field(description="Поступило за период")]
    haben: Annotated[
        int | None, Field(description="Количество по PLU, которое было возвращено поставщику за указанный период")]
    model_config = ConfigDict(from_attributes=True)


class PaginatedReportItemsSerializer(BaseModel):
    count: int
    results: list[ReportItemSerializer]


@router.get(
    "/orders/report",
    responses={
        200: {
            "description": "Return report",
            "content": {
                "application/json": {
                    "schema": PaginatedReportItemsSerializer.schema(ref_template="#/components/schemas/{model}")
                },
                "application/octet-stream": {}
            },
        },
    }
)
async def get_report():
    pass

With this I have a problem with swagger. With configuration above there is problem:

Nested ReportItemSerializer is not being displayed (string is instead displayed).

How can I fix it?

I have an endpoint that can return JSON or a file (xlsx):

class ReportItemSerializer(BaseModel):
    id: int
    werks: Annotated[WerkSerializerWithNetwork, Field(validation_alias="werk")]
    plu: Annotated[str, Field(description="Название PLU")]
    start_date: Annotated[date, None, Field(description="Дата начала периода в формате")]
    end_date: Annotated[date | None, Field(description="Дата окончания периода")]
    anfmenge: Annotated[int | None, Field(des cription="Запас на начало периода")]
    endmenge: Annotated[int | None, Field(description="Остаток по PLU в разрезе поставщика на конец периода")]
    soll: Annotated[int, None, Field(description="Поступило за период")]
    haben: Annotated[
        int | None, Field(description="Количество по PLU, которое было возвращено поставщику за указанный период")]
    model_config = ConfigDict(from_attributes=True)


class PaginatedReportItemsSerializer(BaseModel):
    count: int
    results: list[ReportItemSerializer]


@router.get(
    "/orders/report",
    responses={
        200: {
            "description": "Return report",
            "content": {
                "application/json": {
                    "schema": PaginatedReportItemsSerializer.schema(ref_template="#/components/schemas/{model}")
                },
                "application/octet-stream": {}
            },
        },
    }
)
async def get_report():
    pass

With this I have a problem with swagger. With configuration above there is problem:

Nested ReportItemSerializer is not being displayed (string is instead displayed).

How can I fix it?

Share Improve this question edited Mar 29 at 8:31 Chris 35.5k10 gold badges104 silver badges250 bronze badges asked Mar 25 at 13:48 Альберт АлександровАльберт Александров 9472 gold badges20 silver badges44 bronze badges 2
  • 1 Does this answer your question? – Chris Commented Mar 25 at 17:21
  • @Chris I couldn't find out what you mean – Альберт Александров Commented Mar 28 at 5:43
Add a comment  | 

1 Answer 1

Reset to default 1 +50

Here is a working example, heavily based on this answer—hence, please have a look at that answer for more details.

The example below will correctly display the example value/schema in Swagger UI autodocs, under the 200 response's description. Using the drop down menu, one could switch between the various media types; in this case, that is application/json and application/octet-stream.

Working Example

from fastapi import FastAPI
from fastapi.openapi.constants import REF_PREFIX
from pydantic import BaseModel
from datetime import datetime


class SubMessage(BaseModel):
    msg: str
    dt: datetime = None


class Message(BaseModel):
    msg: str
    sub: SubMessage


def get_200_schema():
    return {
        'model': Message,
        'content': {
            'application/json': {
                'schema': {'$ref': REF_PREFIX + Message.__name__}
            },
            'application/octet-stream': {
                'schema': {} # whatever
            }
        },
    }


app = FastAPI()


@app.get('/', responses={200: get_200_schema()})
async def get_msg():
    return Message(msg='main msg', sub=SubMessage(msg='sub msg', dt=datetime.now()))

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论