Если вы явно не укажете другой тип содержимого в параметре `responses`, FastAPI будет считать, что ответ имеет тот же тип содержимого, что и основной класс ответа (по умолчанию `application/json`).
Здесь функция-обработчик события `shutdown` запишет строку текста `"Application shutdown"` в файл `log.txt`.
/// info | Информация
/// note | Примечание
В функции `open()` параметр `mode="a"` означает «добавление» (append), то есть строка будет добавлена в конец файла, без перезаписи предыдущего содержимого.
@ -152,7 +152,7 @@ async with lifespan(app):
Под капотом, в ASGI-технической спецификации, это часть [Протокола Lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), и он определяет события `startup` и `shutdown`.
/// info | Информация
/// note | Примечание
Вы можете прочитать больше про обработчики `lifespan` в Starlette в [документации Starlette по Lifespan](https://www.starlette.dev/lifespan/).
Некоторые из этих решений также могут быть open source или иметь бесплатные тарифы, так что вы сможете попробовать их без финансовых затрат. Другие коммерческие генераторы SDK доступны и их можно найти онлайн. 🤓
* Данных запроса — в теле запроса, query‑параметрах и т.д.
* Данных ответа.
У вас также будут **ошибки прямо в редакторе** для всего.
У вас также будут **ошибки прямо в редакторе кода** для всего.
И каждый раз, когда вы обновляете код бэкенда и **перегенерируете** фронтенд, в нём появятся новые *операции пути* как методы, старые будут удалены, а любые другие изменения отразятся в сгенерированном коде. 🤓
К этому моменту у вас есть необходимые *операции пути* обратного вызова (те, которые *внешний разработчик* должен реализовать во *внешнем API*) в созданном выше маршрутизаторе обратных вызовов.
Теперь используйте параметр `callbacks` в *декораторе операции пути вашего API*, чтобы передать атрибут `.routes`(это, по сути, просто `list` маршрутов/*операций пути*) из этого маршрутизатора обратных вызовов:
Теперь используйте параметр `callbacks` в *декораторе операции пути вашего API*, чтобы передать атрибут `.routes` из этого маршрутизатора обратных вызовов:
Обратите внимание, что вы передаёте не сам маршрутизатор (`invoices_callback_router`) в `callback=`, а его атрибут `.routes`, то есть `invoices_callback_router.routes`.
Обратите внимание, что вы передаёте не сам маршрутизатор (`invoices_callback_router`) в `callback=`, а его атрибут `.routes`, то есть `invoices_callback_router.routes`. FastAPI будет использовать эти маршруты для генерации документации OpenAPI для обратных вызовов.
Это значительно упростит вашим пользователям реализацию их API для приема ваших вебхук-запросов; возможно, они даже смогут автоматически сгенерировать часть кода своего API.
/// info | Информация
/// note | Примечание
Вебхуки доступны в OpenAPI 3.1.0 и выше, поддерживаются в FastAPI `0.99.0` и новее.
@ -36,7 +36,7 @@
Определенные вами вебхуки попадут в схему **OpenAPI** и в автоматический **интерфейс документации**.
/// info | Информация
/// note | Примечание
Объект `app.webhooks` на самом деле — это обычный `APIRouter`, тот же тип, который вы используете при структурировании приложения по нескольким файлам.
### Использование имени *функции-обработчика пути* как operationId { #using-the-path-operation-function-name-as-the-operationid }
Если вы хотите использовать имена функций ваших API в качестве `operationId`, вы можете пройти по всем из них и переопределить `operation_id` каждой *операции пути* с помощью их `APIRoute.name`.
Если вы хотите использовать имена функций ваших API в качестве `operationId`, вы можете передать пользовательскую `generate_unique_id_function` в `FastAPI`.
Делать это следует после добавления всех *операций пути*.
Эта функция получает каждый `APIRoute` и возвращает `operationId`, который нужно использовать для этой операции пути.
Но если вы хотите передавать в потоке чистые бинарные данные или строки, ниже показано, как это сделать.
/// info | Информация
/// note | Примечание
Добавлено в FastAPI 0.134.0.
@ -90,7 +90,7 @@ FastAPI будет передавать каждый чанк данных в `S
И во многих случаях чтение таких объектов будет блокирующей операцией (которая может заблокировать цикл событий), потому что данные читаются с диска или из сети.
/// info | Информация
/// note | Примечание
Приведённый выше пример — исключение, потому что объект `io.BytesIO` уже находится в памяти, поэтому чтение ничего не блокирует.
С этой настройкой запросы без заголовка `Content-Type` будут иметь тело запроса, обработанное как JSON — это такое же поведение, как в более старых версиях FastAPI.
/// info | Информация
/// note | Примечание
Это поведение и настройка были добавлены в FastAPI 0.132.0.
Если у вас **несколько контейнеров**, и, вероятно, каждый запускает **один процесс** (например, в кластере **Kubernetes**), то вы, скорее всего, захотите иметь **отдельный контейнер**, выполняющий **предварительные шаги** в одном контейнере и одном процессе **до** запуска реплицированных контейнеров-воркеров.
/// info | Информация
/// note | Заметка
Если вы используете Kubernetes, это, вероятно, будет [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
Вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com) одной командой, присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
## Вход { #login }
Убедитесь, что у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉).
Затем выполните вход:
<divclass="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
## Деплой { #deploy }
Теперь разверните приложение одной командой:
Вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com) всего **одной командой**. 🚀
<divclass="termy">
@ -36,6 +16,8 @@ Deploying to FastAPI Cloud...
</div>
CLI автоматически определит ваше приложение FastAPI и развернёт его в облаке. Если вы не вошли в аккаунт, откроется браузер для завершения процесса аутентификации.
Вот и всё! Теперь вы можете открыть своё приложение по этому URL. ✨
@ -46,7 +46,7 @@ $ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid
Давайте немного углубимся в детали.
FastAPI использует стандарт для построения Python‑веб‑фреймворков и серверов под названием <abbrtitle="Asynchronous Server Gateway Interface – Асинхронный шлюзовый интерфейс сервера">ASGI</abbr>. FastAPI — ASGI-веб‑фреймворк.
FastAPI использует стандарт для построения Python‑веб‑фреймворков и серверов под названием <abbrtitle="Asynchronous Server Gateway Interface - Асинхронный шлюзовый интерфейс сервера">ASGI</abbr>. FastAPI — ASGI-веб‑фреймворк.
Главное, что вам нужно, чтобы запустить приложение **FastAPI** (или любое другое ASGI‑приложение) на удалённой серверной машине, — это программа ASGI‑сервера, такая как **Uvicorn**; именно он используется по умолчанию в команде `fastapi`.
@ -56,7 +56,6 @@ FastAPI использует стандарт для построения Python
* [Hypercorn](https://hypercorn.readthedocs.io/): ASGI‑сервер, среди прочего совместимый с HTTP/2 и Trio.
* [Daphne](https://github.com/django/daphne): ASGI‑сервер, созданный для Django Channels.
* [Granian](https://github.com/emmett-framework/granian): HTTP‑сервер на Rust для Python‑приложений.
* [NGINX Unit](https://unit.nginx.org/howto/fastapi/): NGINX Unit — лёгкая и многофункциональная среда выполнения веб‑приложений.
## Сервер как машина и сервер как программа { #server-machine-and-server-program }
Здесь я покажу, как использовать **Uvicorn** с **воркер-процессами** через команду `fastapi` или напрямую через команду `uvicorn`.
/// info | Информация
/// note | Примечание
Если вы используете контейнеры, например Docker или Kubernetes, я расскажу об этом подробнее в следующей главе: [FastAPI в контейнерах — Docker](docker.md).
* `openapi_version`: Версия используемой спецификации OpenAPI. По умолчанию — последняя: `3.1.0`.
* `summary`: Краткое описание API.
* `description`: Описание вашего API; может включать Markdown и будет отображаться в документации.
* `routes`: Список маршрутов — это каждая зарегистрированная *операция пути*. Берутся из `app.routes`.
* `routes`: Список маршрутов — это каждая зарегистрированная *операция пути*. Берутся из `app.routes`. FastAPI использует их, чтобы собрать зарегистрированные *операции пути*, включая те из подключённых роутеров.
/// info | Информация
/// tip | Технические детали
Параметр `summary` доступен в OpenAPI 3.1.0 и выше, поддерживается FastAPI версии 0.99.0 и выше.
`app.routes` — это более низкоуровневое дерево маршрутов. Оно может включать кандидаты маршрутов, которые FastAPI использует внутренне для подключённых роутеров, а не только конечные объекты `APIRoute`.
Вы всё равно можете передать `app.routes` в `get_openapi()`. FastAPI обойдёт это дерево маршрутов, чтобы собрать фактические операции пути.
///
/// note | Примечание
Параметр `summary` доступен в OpenAPI 3.1.0 и выше, поддерживается FastAPI 0.99.0 и выше.
При желании вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com), присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
Если у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉), вы можете развернуть ваше приложение одной командой.
При желании вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com) одной командой. 🚀
<divclass="termy">
@ -510,6 +508,8 @@ Deploying to FastAPI Cloud...
</div>
CLI автоматически определит ваше приложение FastAPI и развернёт его в облаке. Если вы не вошли в систему, откроется браузер для завершения процесса аутентификации.
Вот и всё! Теперь вы можете открыть ваше приложение по этой ссылке. ✨
@ -396,9 +396,9 @@ from .routers.users import router
/// note | Технические детали
Фактически, внутри он создаст *операцию пути* для каждой *операции пути*, объявленной в `APIRouter`.
FastAPI сохраняет исходный `APIRouter` и его `APIRoute` активными, когда маршрутизатор включается в основное приложение.
Так что под капотом всё будет работать так, как будто всё было одним приложением.
Это означает, что пользовательские подклассы `APIRouter` и `APIRoute` по-прежнему участвуют после подключения маршрутизатора.
///
@ -406,7 +406,7 @@ from .routers.users import router
При подключении маршрутизаторов не нужно беспокоиться о производительности.
Это займёт микросекунды и произойдёт только при старте.
Это сделано максимально лёгким и не добавляет накладных расходов на каждый запрос.
Так что это не повлияет на производительность. ⚡
@ -459,9 +459,9 @@ from .routers.users import router
`APIRouter` не «монтируются», они не изолированы от остального приложения.
Это потому, что мы хотим включить их *операции пути* в OpenAPI-схему и пользовательские интерфейсы.
Это потому, что мы хотим включить их *операции пути* в схему OpenAPI и пользовательские интерфейсы.
Так как мы не можем просто изолировать их и «смонтировать» независимо от остального, *операции пути* «клонируются» (пересоздаются), а не включаются напрямую.
FastAPI сохраняет исходные маршрутизаторы и операции пути активными и комбинирует префиксы маршрутизаторов, зависимости, теги, ответы и другие метаданные при обработке запросов и генерации OpenAPI.
///
@ -524,7 +524,7 @@ $ fastapi dev
Это продвинутое использование, которое вам может и не понадобиться, но оно есть на случай, если понадобится.
## Подключение `APIRouter` в другой `APIRouter` { #include-an-apirouter-in-another }
## Подключение `APIRouter` в другой `APIRouter` { #include-an-apirouter-in-another }
Точно так же, как вы можете подключить `APIRouter` к приложению `FastAPI`, вы можете подключить `APIRouter` к другому `APIRouter`, используя:
@ -532,4 +532,16 @@ $ fastapi dev
router.include_router(other_router)
```
Убедитесь, что вы сделали это до подключения `router` к приложению `FastAPI`, чтобы *операции пути* из `other_router` также были подключены.
Вы можете сделать это до или после подключения `router` к приложению `FastAPI`. FastAPI всё равно включит *операции пути* из `other_router` в маршрутизацию и OpenAPI.
То же относится к *операциям пути*, добавленным позже в маршрутизаторы. Они также будут видны через более раннее включение.
/// warning | Технические детали
Избегайте прямой мутации `router.routes` после включения маршрутизатора. FastAPI рассматривает включение маршрутизатора как «живое», поэтому исходный маршрутизатор и его маршруты остаются частью маршрутизации и генерации OpenAPI.
Используйте документированные API, такие как декораторы операций пути и `.include_router()`, чтобы добавлять маршруты и маршрутизаторы.
Считайте `router.routes` низкоуровневым деревом маршрутов, которое может содержать определения маршрутов и включённые маршрутизаторы, и избегайте воспринимать его как плоский список итоговых операций пути.
`Body` также имеет все те же дополнительные параметры валидации и метаданных, как у `Query`, `Path` и других, которые вы увидите позже.
@ -123,7 +123,7 @@ q: str | None = None
Но если вы хотите чтобы он ожидал JSON с ключом `item` с содержимым модели внутри, также как это происходит при объявлении дополнительных body-параметров, вы можете использовать специальный параметр `embed` у типа `Body`:
### Объявите `list` с параметром типа { #declare-a-list-with-a-type-parameter }
Для объявления типов, у которых есть параметры типа (внутренние типы), таких как `list`, `dict`, `tuple`, передайте внутренний(ие) тип(ы) как «параметры типа», используя квадратные скобки: `[` и `]`
Для объявления типов, у которых есть параметры типа (внутренние типы), таких как `list`, `dict`, `tuple`,
передайте внутренний(ие) тип(ы) как «параметры типа», используя квадратные скобки: `[` и `]`
```Python
my_list: list[str]
@ -135,7 +136,7 @@ my_list: list[str]
}
```
/// info | Информация
/// note | Примечание
Заметьте, что теперь у ключа `images` есть список объектов изображений.
Имейте в виду, что, поскольку **браузеры обрабатывают cookies** особым образом и под капотом, они **не** позволят **JavaScript** легко получить доступ к ним.
Для объявления cookies, вам нужно использовать `Cookie`, иначе параметры будут интерпретированы как параметры запроса.
///
/// info | Дополнительная информация
/// note | Примечание
Имейте в виду, что, поскольку **браузеры обрабатывают cookies** особым образом и «за кулисами», они **не** позволяют **JavaScript** просто так получать к ним доступ.
Таким образом, вы пишете общий код один раз, а **FastAPI** позаботится о его вызове для ваших *операций пути*.
/// check | Проверка
/// tip | Подсказка
Обратите внимание, что вам не нужно создавать специальный класс и передавать его куда-то в **FastAPI**, чтобы «зарегистрировать» его или что-то подобное.
### `fastapi dev` с путём { #fastapi-dev-with-path }
### `fastapi dev` с путём или с опцией CLI `--entrypoint`{ #fastapi-dev-with-path-or-with-entrypoint-cli-option }
Вы также можете передать путь к файлу в команду `fastapi dev`, и она попытается определить объект приложения FastAPI для использования:
@ -188,29 +188,19 @@ from backend.main import app
$ fastapi dev main.py
```
Но в этом случае вам придётся каждый раз помнить о передаче корректного пути при вызове команды `fastapi`.
Кроме того, другие инструменты могут его не найти, например [Расширение VS Code](../editor-support.md) или [FastAPI Cloud](https://fastapicloud.com), поэтому рекомендуется использовать `entrypoint` в `pyproject.toml`.
При желании вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com), перейдите и присоединитесь к списку ожидания, если ещё не сделали этого. 🚀
Если у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉), вы можете развернуть приложение одной командой.
Перед развертыванием убедитесь, что вы вошли в систему:
<divclass="termy">
Или вы можете передать опцию `--entrypoint` команде `fastapi dev`:
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
$ fastapi dev --entrypoint main:app
```
</div>
Но в этом случае вам придётся каждый раз помнить о передаче корректного пути/entrypoint при вызове команды `fastapi`.
Кроме того, другие инструменты могут его не найти, например [Расширение VS Code](../editor-support.md) или [FastAPI Cloud](https://fastapicloud.com), поэтому рекомендуется использовать `entrypoint` в `pyproject.toml`.
При желании вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com) одной командой. 🚀
<divclass="termy">
@ -226,6 +216,8 @@ Deploying to FastAPI Cloud...
</div>
CLI автоматически определит ваше приложение FastAPI и развернёт его в облаке. Если вы не вошли в систему, откроется браузер для завершения процесса аутентификации.
Готово! Теперь вы можете открыть своё приложение по этому URL. ✨
## Рассмотрим поэтапно { #recap-step-by-step }
@ -270,7 +262,7 @@ https://example.com/items/foo
/items/foo
```
/// info | Информация
/// note | Примечание
«Путь» также часто называют «эндпоинт» или «маршрут».
@ -322,7 +314,7 @@ https://example.com/items/foo
* по пути `/`
* с использованием <dfntitle="метод HTTP GET"><code>get</code> операции</dfn>
/// info | Информация о `@decorator`
/// note | Информация о `@decorator`
Синтаксис `@something` в Python называется «декоратор».
В этом случае, параметр `q` будет не обязательным и будет иметь значение `None` по умолчанию.
/// check | Важно
/// tip | Подсказка
Также обратите внимание, что **FastAPI** достаточно умён чтобы заметить, что параметр `item_id` является path-параметром, а `q` нет, поэтому, это параметр запроса.
Когда вам нужно получить поля формы вместо JSON, вы можете использовать `Form`.
/// info | Дополнительная информация
/// note | Примечание
Чтобы использовать формы, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
@ -32,7 +32,7 @@ $ pip install python-multipart
С помощью `Form` вы можете объявить те же настройки, что и с `Body` (и `Query`, `Path`, `Cookie`), включая валидацию, примеры, псевдоним (например, `user-name` вместо `username`) и т.д.
/// info | Дополнительная информация
/// note | Примечание
`Form` — это класс, который наследуется непосредственно от `Body`.
Чтобы использовать `EmailStr`, сначала установите [`email-validator`](https://github.com/JoshData/python-email-validator).
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установите пакет, например:
Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
```console
$ pip install email-validator
@ -178,7 +178,7 @@ FastAPI делает несколько вещей внутри вместе с
## Другие аннотации возвращаемых типов { #other-return-type-annotations }
Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор кода, mypy и т.д.).
Бывают случаи, когда вы возвращаете что-то, что не является валидным полем Pydantic, и аннотируете это в функции только ради поддержки инструментов (редактор коды, mypy и т.д.).
Параметр `status_code` принимает число, обозначающее HTTP статус-код.
/// info | Информация
/// note | Примечание
В качестве значения параметра `status_code` также может использоваться `IntEnum`, например, из библиотеки [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus) в Python.
OpenAPI 3.1.0 (используется начиная с FastAPI 0.99.0) добавил поддержку `examples`, который является частью стандарта **JSON Schema**.
@ -155,7 +155,7 @@ OpenAPI также добавила поля `example` и `examples` в друг
* `File()`
* `Form()`
/// info | Информация
/// note | Примечание
Этот старый специфичный для OpenAPI параметр `examples` теперь называется `openapi_examples`, начиная с FastAPI `0.103.0`.
@ -171,7 +171,7 @@ OpenAPI также добавила поля `example` и `examples` в друг
Это новое поле `examples` в JSON Schema — это **просто `list`** примеров, а не dict с дополнительными метаданными, как в других местах OpenAPI (описанных выше).
/// info | Информация
/// note | Примечание
Даже после того как OpenAPI 3.1.0 была выпущена с этой новой, более простой интеграцией с JSON Schema, какое‑то время Swagger UI, инструмент, предоставляющий автоматическую документацию, не поддерживал OpenAPI 3.1.0 (поддержка появилась начиная с версии 5.0.0 🎉).
Пакет [`python-multipart`](https://github.com/Kludex/python-multipart) автоматически устанавливается вместе с **FastAPI**, если вы запускаете команду `pip install "fastapi[standard]"`.
@ -60,7 +60,7 @@ $ fastapi dev
<imgsrc="/img/tutorial/security/image01.png">
/// check | Кнопка авторизации!
/// tip | Кнопка авторизации!
У вас уже появилась новая кнопка «Authorize».
@ -118,7 +118,7 @@ OAuth2 был спроектирован так, чтобы бэкенд или
В этом примере мы будем использовать **OAuth2**, с потоком **Password**, используя токен **Bearer**. Для этого мы используем класс `OAuth2PasswordBearer`.
/// info | Дополнительная информация
/// note | Примечание
Токен «bearer» — не единственный вариант.
@ -148,7 +148,7 @@ OAuth2 был спроектирован так, чтобы бэкенд или
Скоро мы также создадим и саму операцию пути.
/// info | Дополнительная информация
/// note | Примечание
Если вы очень строгий «питонист», вам может не понравиться стиль имени параметра `tokenUrl` вместо `token_url`.
**FastAPI** будет знать, что может использовать эту зависимость для определения «схемы безопасности» в схеме OpenAPI (и в автоматической документации по API).
/// info | Технические детали
/// note | Технические детали
**FastAPI** будет знать, что может использовать класс `OAuth2PasswordBearer` (объявленный в зависимости) для определения схемы безопасности в OpenAPI, потому что он наследуется от `fastapi.security.oauth2.OAuth2`, который, в свою очередь, наследуется от `fastapi.security.base.SecurityBase`.
Он будет искать в запросе заголовок `Authorization`, проверять, что его значение — это `Bearer ` плюс некоторый токен, и вернет токен как `str`.
Он будет искать в запросе HTTP-заголовок `Authorization`, проверять, что его значение — это `Bearer ` плюс некоторый токен, и вернет токен как `str`.
Если заголовок `Authorization` отсутствует или его значение не содержит токен `Bearer `, он сразу ответит ошибкой со статус-кодом 401 (`UNAUTHORIZED`).
`get_current_user` будет использовать созданную нами (ненастоящую) служебную функцию, которая принимает токен типа `str` и возвращает нашу Pydantic-модель `User`:
`get_current_user` будет использовать созданную нами (ненастоящую) вспомогательную функцию, которая принимает токен типа `str` и возвращает нашу Pydantic-модель `User`:
То, как устроена эта система зависимостей, позволяет иметь разные зависимости, которые возвращают модель `User`.
@ -78,7 +78,7 @@
## Размер кода { #code-size }
Этот пример может показаться многословным. Имейте в виду, что в одном файле мы смешиваем безопасность, модели данных, служебные функции и *операции пути*.
Этот пример может показаться многословным. Имейте в виду, что в одном файле мы смешиваем безопасность, модели данных, вспомогательные функции и *операции пути*.
Если вы планируете использовать алгоритмы цифровой подписи, такие как RSA или ECDSA, вам следует установить зависимость библиотеки криптографии `pyjwt[crypto]`.
@ -213,7 +213,7 @@ JWT может использоваться и для других целей,
Username: `johndoe`
Password: `secret`
/// check | Проверка
/// tip | Подсказка
Обратите внимание, что нигде в коде не используется открытый текст пароля "`secret`", мы используем только его хэшированную версию.
Это похоже на [Стриминг JSON Lines](stream-json-lines.md), но использует формат `text/event-stream`, который нативно поддерживается браузерами через [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
/// info | Информация
/// note | Примечание
Добавлено в FastAPI 0.135.0.
@ -29,7 +29,7 @@ SSE часто используют для стриминга ответов И
/// tip | Совет
Если вам нужно стримить бинарные данные, например видео или аудио, посмотрите расширенное руководство: [Stream Data](../advanced/stream-data.md).
Если вам нужно стримить бинарные данные, например видео или аудио, посмотрите расширенное руководство: [Потоковая передача данных](../advanced/stream-data.md).
///
@ -113,7 +113,7 @@ SSE работает с любым HTTP-методом, не только с `GE
FastAPI из коробки реализует некоторые лучшие практики для SSE.
- Отправлять комментарий «ping» для поддержания соединения («keep alive») каждые 15 секунд, когда нет сообщений, чтобы предотвратить закрытие соединения некоторыми прокси, как рекомендовано в [HTML specification: Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes).
- Отправлять комментарий «ping» для поддержания соединения («keep alive») каждые 15 секунд, когда нет сообщений, чтобы предотвратить закрытие соединения некоторыми прокси, как рекомендовано в [Спецификация HTML: Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes).
- Устанавливать заголовок `Cache-Control: no-cache`, чтобы предотвратить кэширование потока.
- Устанавливать специальный заголовок `X-Accel-Buffering: no`, чтобы предотвратить буферизацию в некоторых прокси, например Nginx.
У вас может быть последовательность данных, которую вы хотите отправлять в «**потоке**». Это можно сделать с помощью **JSON Lines**.
/// info | Информация
/// note | Примечание
Добавлено в FastAPI 0.134.0.
@ -48,7 +48,7 @@ sequenceDiagram
Это очень похоже на JSON-массив (эквивалент списка Python), но вместо того чтобы быть обернутым в `[]` и иметь `,` между элементами, здесь **один JSON-объект на строку**, они разделены символом новой строки.
/// info | Информация
/// note | Примечание
Важный момент в том, что ваше приложение сможет по очереди производить каждую строку, пока клиент потребляет предыдущие строки.
## Использование класса `TestClient` { #using-testclient }
/// info | Информация
/// note | Примечание
Для использования класса `TestClient` сначала установите [`httpx`](https://www.python-httpx.org).
@ -144,7 +144,7 @@ $ pip install httpx
Для получения дополнительной информации о передаче данных на бэкенд с помощью `httpx` или `TestClient` ознакомьтесь с [документацией HTTPX](https://www.python-httpx.org).
/// info | Информация
/// note | Примечание
Обратите внимание, что `TestClient` принимает данные, которые можно конвертировать в JSON, но не модели Pydantic.