Как добавить множественные примеры запросов и ответов в FastAPI

Из этой статьи вы узнаете, как расширить документацию FastAPI для включения нескольких экземпляров запроса и ответа: при работе как со Swagger UI, так и с ReDoc.

К примеру, в ReDoc вам будет доступен следующий результат:

И то же самое для Swagger UI:

Раньше для добавления экземпляров вам приходилось полагаться на объект Field() от pydantic или на внутренние классы extra_schema, унаследованные от BaseModel. Кроме того, вам было доступно только по одному экземпляру на каждый запрос и ответ.

Начиная с версии 0.64.0 FastApi официально поддерживает аргументы example и examples для следующих объектов:

  • Body()
  • Path()
  • Query()
  • Cookie()
  • Header()

Согласно официальной документации:

“Существует более новая версия OpenAPI: 3.1.0. Она основана на актуальной JSON-схеме, и большинство модификаций пользовательской версии JSON-схемы удалены из OpenAPI в обмен на функции из последних версий JSON-схемы, так что небольшие различия сведены к минимуму. Тем не менее, пользовательский интерфейс Swagger в настоящее время не поддерживает OpenAPI 3.1.0”.

Разработчики FastAPI решают проблему с помощью некоторых хитростей как для обеспечения совместимости, так и для обработки несовместимостей между OpenAPI, JSON-схемой и пользовательской версией JSON-схемы для 3.0.x OpenAPI.

Теперь перейдем к следующему разделу и начнем установку необходимых модулей Python.


Настройка

Прежде, чем начинать установку, крайне рекомендуется создать новую виртуальную среду.

FastAPI

Активируйте ее и запустите следующую команду для установки FastAPI:

pip install fastapi

Убедитесь, что устанавливаете версию 0.65.1+, так как в нее входит стабильная версия pydantic, устраняющая критическую ошибку безопасности.

Uvicorn

Следом установите стандартный пакет Uvicorn:

pip install uvicorn[standard]

Реализация

Взглянем на следующий экземпляр простого сервера FastAPI:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Number(BaseModel):
value: int


class Response(BaseModel):
code: int
message: str
result: bool


@app.post("/odd", response_model=Response)
def odd(number: Number):
return Response(code=200, message="Success", result=number.value % 2)

Он содержит два класса, унаследованных от BaseModel:

  • Number —  параметры ввода.
  • Response —  результат вывода.

Также здесь есть эндпоинт под названием odd, который определяет, является ли ввод нечетным числом и возвращает результат пользователю.

Чтобы добавить примеры запросов к эндпоинту, вам потребуется только создать подходящий объект словаря, соответствующий JSON-схема для одного из следующих объектов:

  • Body()
  • Path()
  • Query()
  • Cookie()
  • Header()

В нашем случае лучше всего подойдет объект Body().

Добавление примеров запросов

Каждый элемент в объекте словаря должен содержать следующие поля:

  • summary —  Имя, которое будет отображаться в раскрывающемся списке как часть параметров.
  • description —  Необязательное поле, которое содержит краткое вспомогательное описание при выборе пользователем опции. Поддерживает текст в разметке Markdown.
  • value —  Пример схемы, представляющей полезную нагрузку или результат.

Например, вы можете определить объект словаря, как показано ниже:

odd_examples = {
"odd": {
"summary": "Odd number",
"value": {
"value": 1111
}
},
"even": {
"summary": "Even number",
"value": {
"value": 322
}
},
"alphabet": {
"summary": "Example using alphabet",
"description": "Using invalid, non-number input. Will raise `Error: Unprocessable Entity` message.",
"value": {
"value": "abc"
}
},
}

После этого просто модифицируйте код:

def odd(number: Number):

До следующего вида:

def odd(number: Number = Body(..., examples=odd_examples)):

Добавление примеров ответов

С другой стороны, добавление примеров в ответы немного отличается. Главным образом дело в том, что ответы привязаны к кодам состояния HTTP, хотя в большинстве случаев примеры предназначены только для кода состояния 200.

Создайте новый объект словаря:

odd_responses = {
200: {
"description": "Success",
"content": {
"application/json": {
"examples": {
"odd": {
"summary": "Odd Number",
"value": {"code": 0, "message": "Success", "result": True}
},
"even": {
"summary": "Even Number",
"value": {"code": 0, "message": "Success", "result": False}
},
}
}
}
},
}

Затем модифицируйте код:

@app.post("/odd", response_model=Response)

До вида:

@app.post("/odd", response_model=Response, responses=odd_responses)

Тестирование документации FastAPI

Как только вы закончите, сохраните файл как myapp.py и выполните следующие действия в командной строке для запуска сервера FastAPI:

uvicorn myapp:app

Измените имя, если ваш файл или переменная называются по-другому:

uvicorn <file_name>:<variable_name>

По умолчанию сервер запускается на порту 8000. Перейдите по следующему URL-адресу:

http://localhost:8000/docs

Вы должны увидеть раскрывающийся список в разделе Example как для запроса, так и для ответа. Например:

В случае ReDoc вам нужно воспользоваться немного другим адресом:

http://localhost:8000/redoc

Результат будет выглядеть так:

Полный код можете найти здесь: gist.

from fastapi import FastAPI, Body
from pydantic import BaseModel

app = FastAPI()


class Number(BaseModel):
value: int


class Response(BaseModel):
code: int
message: str
result: bool


odd_examples = {
"odd": {
"summary": "Odd number",
"value": {
"value": 1111
}
},
"even": {
"summary": "Even number",
"value": {
"value": 322
}
},
"alphabet": {
"summary": "Example using alphabet",
"description": "Using invalid, non-number input. Will raise `Error: Unprocessable Entity` message.",
"value": {
"value": "abc"
}
},
}

odd_responses = {
200: {
"description": "Success",
"content": {
"application/json": {
"examples": {
"odd": {
"summary": "Odd Number",
"value": {"code": 0, "message": "Success", "result": True}
},
"even": {
"summary": "Even Number",
"value": {"code": 0, "message": "Success", "result": False}
},
}
}
}
},
}


@app.post("/odd", response_model=Response, responses=odd_responses)
def odd(number: Number = Body(..., examples=odd_examples)):
return Response(code=200, message="Success", result=number.value % 2)

Заключение

Это руководство началось с краткого объяснения того, как FastAPI поддерживает несколько возможных примеров как для запросов, так и для ответов.

Потом мы перешли к процессу установки, в котором произвели установку пакетов fast api и uvicorn.

В следующем разделе мы рассмотрели весь процесс как для запросов, так и для ответов. В качестве примеров реализации были предоставлены фрагменты кода. Заключительная часть была посвящена запуску сервера и доступу к документации для проверки результата.


Ссылки

  1. FastAPI — Schema Extra Examples
  2. FastAPI — Additional Responses

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Ng Wai Foong: How To Add Multiple Request and Response Examples in FastAPI

Предыдущая статьяСоздание дашбордов в Dash
Следующая статьяБыстро о главном: визуализация с D3.js