* Проверьте, всё ли в порядке в переводе.
* При необходимости улучшите ваш языковой специфичный промпт, общий промпт или английский документ.
* Затем вручную исправьте оставшиеся проблемы в переводе, чтобы он был хорошим.
-* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт настолько хороши, насколько это возможно (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">LLM — недетерминированные алгоритмы</a>).
+* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт настолько хороши, насколько это возможно (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что [LLM — недетерминированные алгоритмы](https://doublespeak.chat/#/handbook#deterministic-output)).
Тесты:
Текст ссылок должен переводиться, адрес ссылки не должен изменяться:
* [Ссылка на заголовок выше](#code-snippets)
-* [Внутренняя ссылка](index.md#installation){.internal-link target=_blank}
-* <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">Внешняя ссылка</a>
-* <a href="https://fastapi.tiangolo.com/css/styles.css" class="external-link" target="_blank">Ссылка на стиль</a>
-* <a href="https://fastapi.tiangolo.com/js/logic.js" class="external-link" target="_blank">Ссылка на скрипт</a>
-* <a href="https://fastapi.tiangolo.com/img/foo.jpg" class="external-link" target="_blank">Ссылка на изображение</a>
+* [Внутренняя ссылка](index.md#installation)
+* [Внешняя ссылка](https://sqlmodel.tiangolo.com/)
+* [Ссылка на стиль](https://fastapi.tiangolo.com/css/styles.css)
+* [Ссылка на скрипт](https://fastapi.tiangolo.com/js/logic.js)
+* [Ссылка на изображение](https://fastapi.tiangolo.com/img/foo.jpg)
Текст ссылок должен переводиться, адрес ссылки должен указывать на перевод:
-* <a href="https://fastapi.tiangolo.com/ru/" class="external-link" target="_blank">Ссылка на FastAPI</a>
+* [Ссылка на FastAPI](https://fastapi.tiangolo.com/ru/)
////
* чувствительный к регистру
* нечувствительный к регистру
-* обслуживать приложение
+* отдавать приложение
* отдавать страницу
* приложение
Чтобы увидеть, что именно можно включать в ответы, посмотрите эти разделы спецификации OpenAPI:
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object" class="external-link" target="_blank">Объект Responses OpenAPI</a>, он включает `Response Object`.
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object" class="external-link" target="_blank">Объект Response OpenAPI</a>, вы можете включить всё из этого объекта напрямую в каждый ответ внутри вашего параметра `responses`. Включая `description`, `headers`, `content` (внутри него вы объявляете разные типы содержимого и JSON‑схемы) и `links`.
+* [Объект Responses OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object), он включает `Response Object`.
+* [Объект Response OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object), вы можете включить всё из этого объекта напрямую в каждый ответ внутри вашего параметра `responses`. Включая `description`, `headers`, `content` (внутри него вы объявляете разные типы содержимого и JSON‑схемы) и `links`.
Если вы возвращаете дополнительные статус-коды и ответы напрямую, они не будут включены в схему OpenAPI (документацию API), потому что у FastAPI нет способа заранее знать, что вы собираетесь вернуть.
-Но вы можете задокументировать это в своём коде, используя: [Дополнительные ответы](additional-responses.md){.internal-link target=_blank}.
+Но вы можете задокументировать это в своём коде, используя: [Дополнительные ответы](additional-responses.md).
checker(q="somequery")
```
-…и передаст возвращённое значение как значение зависимости в параметр `fixed_content_included` нашей *функции-обработчика пути*:
+…и передаст возвращённое значение как значение зависимости в параметр `fixed_content_included` нашей *функции-обработчику пути*:
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
Так сессия освободит подключение к базе данных, и другие запросы смогут его использовать.
-Если у вас есть другой сценарий, где нужно раннее завершение зависимости с `yield`, пожалуйста, создайте <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">вопрос в GitHub Discussions</a> с описанием конкретного кейса и почему вам было бы полезно иметь раннее закрытие для зависимостей с `yield`.
+Если у вас есть другой сценарий, где нужно раннее завершение зависимости с `yield`, пожалуйста, создайте [вопрос в GitHub Discussions](https://github.com/fastapi/fastapi/discussions/new?category=questions) с описанием конкретного кейса и почему вам было бы полезно иметь раннее закрытие для зависимостей с `yield`.
Если появятся веские причины для раннего закрытия в зависимостях с `yield`, я рассмотрю добавление нового способа опционально включать раннее закрытие.
### Фоновые задачи и зависимости с `yield`, технические детали { #background-tasks-and-dependencies-with-yield-technical-details }
-До FastAPI 0.106.0 вызывать исключения после `yield` было невозможно: код после `yield` в зависимостях выполнялся уже после отправки ответа, поэтому [Обработчики исключений](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} к тому моменту уже отработали.
+До FastAPI 0.106.0 вызывать исключения после `yield` было невозможно: код после `yield` в зависимостях выполнялся уже после отправки ответа, поэтому [Обработчики исключений](../tutorial/handling-errors.md#install-custom-exception-handlers) к тому моменту уже отработали.
Так было сделано в основном для того, чтобы можно было использовать те же объекты, «отданные» зависимостями через `yield`, внутри фоновых задач, потому что код после `yield` выполнялся после завершения фоновых задач.
Чтобы работать с асинхронным FastAPI приложением в ваших обычных тестовых функциях `def`, используя стандартный pytest, `TestClient` внутри себя делает некоторую магию. Но эта магия перестает работать, когда мы используем его внутри асинхронных функций. Запуская наши тесты асинхронно, мы больше не можем использовать `TestClient` внутри наших тестовых функций.
-`TestClient` основан на <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>, и, к счастью, мы можем использовать его (`HTTPX`) напрямую для тестирования API.
+`TestClient` основан на [HTTPX](https://www.python-httpx.org), и, к счастью, мы можем использовать его (`HTTPX`) напрямую для тестирования API.
## Пример { #example }
-В качестве простого примера, давайте рассмотрим файловую структуру, схожую с описанной в [Большие приложения](../tutorial/bigger-applications.md){.internal-link target=_blank} и [Тестирование](../tutorial/testing.md){.internal-link target=_blank}:
+В качестве простого примера, давайте рассмотрим файловую структуру, схожую с описанной в [Большие приложения](../tutorial/bigger-applications.md) и [Тестирование](../tutorial/testing.md):
```
.
/// warning | Внимание
-Если ваше приложение полагается на lifespan события, то `AsyncClient` не запустит эти события. Чтобы обеспечить их срабатывание используйте `LifespanManager` из <a href="https://github.com/florimondmanca/asgi-lifespan#usage" class="external-link" target="_blank">florimondmanca/asgi-lifespan</a>.
+Если ваше приложение полагается на lifespan события, то `AsyncClient` не запустит эти события. Чтобы обеспечить их срабатывание используйте `LifespanManager` из [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage).
///
/// tip | Подсказка
-Если вы столкнулись с `RuntimeError: Task attached to a different loop` при вызове асинхронных функций в ваших тестах (например, при использовании <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB's MotorClient</a>), то не забывайте инициализировать объекты, которым нужен цикл событий (event loop), только внутри асинхронных функций, например, в `@app.on_event("startup")` callback.
+Если вы столкнулись с `RuntimeError: Task attached to a different loop` при вызове асинхронных функций в ваших тестах (например, при использовании [MongoDB's MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)), то не забывайте создавать экземпляры объектов, которым нужен цикл событий (event loop), только внутри асинхронных функций, например, в `@app.on_event("startup")` callback.
///
Заголовки прокси:
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
+* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
+* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
+* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
///
/// tip | Совет
-Если хотите узнать больше об HTTPS, смотрите руководство [О HTTPS](../deployment/https.md){.internal-link target=_blank}.
+Если хотите узнать больше об HTTPS, смотрите руководство [О HTTPS](../deployment/https.md).
///
Учтите, что сервер (Uvicorn) не использует `root_path` ни для чего, кроме как передать его в приложение.
-Если вы откроете в браузере <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>, вы увидите обычный ответ:
+Если вы откроете в браузере [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), вы увидите обычный ответ:
```JSON
{
## Локальное тестирование с Traefik { #testing-locally-with-traefik }
-Вы можете легко поэкспериментировать локально с функцией удаления префикса пути, используя <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>.
+Вы можете легко поэкспериментировать локально с функцией удаления префикса пути, используя [Traefik](https://docs.traefik.io/).
-<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">Скачайте Traefik</a> — это один бинарный файл; распакуйте архив и запустите его прямо из терминала.
+[Скачайте Traefik](https://github.com/containous/traefik/releases) — это один бинарный файл; распакуйте архив и запустите его прямо из терминала.
Затем создайте файл `traefik.toml` со следующим содержимым:
### Проверьте ответы { #check-the-responses }
-Теперь, если вы перейдёте на URL с портом Uvicorn: <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>, вы увидите обычный ответ:
+Теперь, если вы перейдёте на URL с портом Uvicorn: [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app), вы увидите обычный ответ:
```JSON
{
///
-А теперь откройте URL с портом Traefik и префиксом пути: <a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>.
+А теперь откройте URL с портом Traefik и префиксом пути: [http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app).
Мы получим тот же ответ:
«Официальный» способ доступа к приложению — через прокси с заданным префиксом пути. Поэтому, как и ожидается, если открыть интерфейс документации, отдаваемый напрямую Uvicorn, без префикса пути в URL, он не будет работать, так как предполагается доступ через прокси.
-Проверьте по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>:
+Проверьте по адресу [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs):
<img src="/img/tutorial/behind-a-proxy/image01.png">
А вот если открыть интерфейс документации по «официальному» URL через прокси на порту `9999`, по `/api/v1/docs`, всё работает корректно! 🎉
-Проверьте по адресу <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a>:
+Проверьте по адресу [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs):
<img src="/img/tutorial/behind-a-proxy/image02.png">
///
-В интерфейсе документации по адресу <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> это будет выглядеть так:
+В интерфейсе документации по адресу [http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs) это будет выглядеть так:
<img src="/img/tutorial/behind-a-proxy/image03.png">
## Монтирование вложенного приложения { #mounting-a-sub-application }
-Если вам нужно смонтировать вложенное приложение (как описано в [Вложенные приложения — монтирование](sub-applications.md){.internal-link target=_blank}), и при этом вы используете прокси с `root_path`, делайте это обычным образом — всё будет работать, как ожидается.
+Если вам нужно смонтировать вложенное приложение (как описано в [Вложенные приложения — монтирование](sub-applications.md)), и при этом вы используете прокси с `root_path`, делайте это обычным образом — всё будет работать, как ожидается.
FastAPI умно использует `root_path` внутри, так что всё просто работает. ✨
# Кастомные ответы — HTML, поток, файл и другие { #custom-response-html-stream-file-others }
-По умолчанию **FastAPI** возвращает ответы с помощью `JSONResponse`.
+По умолчанию **FastAPI** возвращает ответы в формате JSON.
-Вы можете переопределить это, вернув `Response` напрямую, как показано в разделе [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}.
+Вы можете переопределить это, вернув `Response` напрямую, как показано в разделе [Вернуть Response напрямую](response-directly.md).
Но если вы возвращаете `Response` напрямую (или любой его подкласс, например `JSONResponse`), данные не будут автоматически преобразованы (даже если вы объявили `response_model`), и документация не будет автоматически сгенерирована (например, со специфичным «типом содержимого» в HTTP-заголовке `Content-Type` как частью сгенерированного OpenAPI).
-Но вы можете также объявить `Response`, который хотите использовать (например, любой подкласс `Response`), в декораторе операции пути, используя параметр `response_class`.
+Но вы также можете объявить `Response`, который хотите использовать (например, любой подкласс `Response`), в декораторе операции пути, указав параметр `response_class`.
Содержимое, которое вы возвращаете из своей функции-обработчика пути, будет помещено внутрь этого `Response`.
-И если у этого `Response` тип содержимого JSON (`application/json`), как в случае с `JSONResponse` и `UJSONResponse`, данные, которые вы возвращаете, будут автоматически преобразованы (и отфильтрованы) любым объявленным вами в декораторе операции пути Pydantic `response_model`.
-
/// note | Примечание
Если вы используете класс ответа без типа содержимого, FastAPI будет ожидать, что у вашего ответа нет содержимого, поэтому он не будет документировать формат ответа в сгенерированной документации OpenAPI.
///
-## Используйте `ORJSONResponse` { #use-orjsonresponse }
-
-Например, если вы выжимаете максимум производительности, вы можете установить и использовать <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> и задать ответ как `ORJSONResponse`.
-
-Импортируйте класс (подкласс) `Response`, который вы хотите использовать, и объявите его в декораторе операции пути.
-
-Для больших ответов возвращать `Response` напрямую значительно быстрее, чем возвращать словарь.
-
-Это потому, что по умолчанию FastAPI проверяет каждый элемент внутри и убеждается, что он сериализуем в JSON, используя тот же [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}, объяснённый в руководстве. Это позволяет возвращать **произвольные объекты**, например модели из базы данных.
-
-Но если вы уверены, что содержимое, которое вы возвращаете, **сериализуемо в JSON**, вы можете передать его напрямую в класс ответа и избежать дополнительных накладных расходов, которые FastAPI понёс бы, пропуская возвращаемое содержимое через `jsonable_encoder` перед передачей в класс ответа.
+## JSON-ответы { #json-responses }
-{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
+По умолчанию FastAPI возвращает ответы в формате JSON.
-/// info | Информация
-
-Параметр `response_class` также используется для указания «типа содержимого» ответа.
+Если вы объявите [Модель ответа](../tutorial/response-model.md), FastAPI использует её для сериализации данных в JSON с помощью Pydantic.
-Ð\92 Ñ\8dÑ\82ом Ñ\81лÑ\83Ñ\87ае HTTP-заголовок `Content-Type` бÑ\83деÑ\82 Ñ\83Ñ\81Ñ\82ановлен в `application/json`.
+Ð\95Ñ\81ли вÑ\8b не обÑ\8aÑ\8fвиÑ\82е моделÑ\8c оÑ\82веÑ\82а, FastAPI иÑ\81полÑ\8cзÑ\83еÑ\82 `jsonable_encoder`, опиÑ\81аннÑ\8bй в Ñ\80азделе [JSON-Ñ\81овмеÑ\81Ñ\82имÑ\8bй Ñ\8dнкодеÑ\80](../tutorial/encoder.md), и помеÑ\81Ñ\82иÑ\82 Ñ\80езÑ\83лÑ\8cÑ\82аÑ\82 в `JSONResponse`.
-Ð\98 Ñ\8dÑ\82о бÑ\83деÑ\82 задокÑ\83менÑ\82иÑ\80овано как Ñ\82аковое в OpenAPI.
+Ð\95Ñ\81ли вÑ\8b обÑ\8aÑ\8fвиÑ\82е `response_class` Ñ\81 JSON Ñ\82ипом Ñ\81одеÑ\80жимого (`application/json`), как в Ñ\81лÑ\83Ñ\87ае Ñ\81 `JSONResponse`, даннÑ\8bе, коÑ\82оÑ\80Ñ\8bе вÑ\8b возвÑ\80аÑ\89аеÑ\82е, бÑ\83дÑ\83Ñ\82 авÑ\82омаÑ\82иÑ\87еÑ\81ки пÑ\80еобÑ\80азованÑ\8b (и оÑ\82Ñ\84илÑ\8cÑ\82Ñ\80ованÑ\8b) лÑ\8eбой Pydantic-моделÑ\8cÑ\8e оÑ\82веÑ\82а (`response_model`), обÑ\8aÑ\8fвленной вами в декоÑ\80аÑ\82оÑ\80е опеÑ\80аÑ\86ии пÑ\83Ñ\82и. Ð\9dо даннÑ\8bе не бÑ\83дÑ\83Ñ\82 Ñ\81еÑ\80иализованÑ\8b в JSON-байÑ\82Ñ\8b Ñ\87еÑ\80ез Pydantic; вмеÑ\81Ñ\82о Ñ\8dÑ\82ого они бÑ\83дÑ\83Ñ\82 пÑ\80еобÑ\80азованÑ\8b Ñ\81 помоÑ\89Ñ\8cÑ\8e `jsonable_encoder`, а заÑ\82ем пеÑ\80еданÑ\8b в клаÑ\81Ñ\81 `JSONResponse`, коÑ\82оÑ\80Ñ\8bй Ñ\81еÑ\80иализÑ\83еÑ\82 иÑ\85 в байÑ\82Ñ\8b, иÑ\81полÑ\8cзÑ\83Ñ\8f Ñ\81Ñ\82андаÑ\80Ñ\82нÑ\83Ñ\8e JSON-библиоÑ\82екÑ\83 Python.
-///
+### Производительность JSON { #json-performance }
-/// tip | Совет
+Коротко: если вам нужна максимальная производительность, используйте [Модель ответа](../tutorial/response-model.md) и не объявляйте `response_class` в декораторе операции пути.
-`ORJSONResponse` доступен только в FastAPI, а не в Starlette.
-
-///
+{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
## HTML-ответ { #html-response }
### Вернуть `Response` { #return-a-response }
-Как показано в разделе [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}, вы также можете переопределить ответ прямо в своей операции пути, просто вернув его.
+Как показано в разделе [Вернуть Response напрямую](response-directly.md), вы также можете переопределить ответ прямо в своей операции пути, просто вернув его.
Тот же пример сверху, возвращающий `HTMLResponse`, может выглядеть так:
Это ответ по умолчанию, используемый в **FastAPI**, как было сказано выше.
-### `ORJSONResponse` { #orjsonresponse }
-
-Быстрая альтернативная реализация JSON-ответа с использованием <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, как было сказано выше.
-
-/// info | Информация
-
-Требуется установка `orjson`, например командой `pip install orjson`.
-
-///
-
-### `UJSONResponse` { #ujsonresponse }
-
-Альтернативная реализация JSON-ответа с использованием <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>.
-
-/// info | Информация
-
-Требуется установка `ujson`, например командой `pip install ujson`.
-
-///
-
-/// warning | Предупреждение
-
-`ujson` менее аккуратен, чем встроенная реализация Python, в обработке некоторых крайних случаев.
-
-///
-
-{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
+/// note | Технические детали
-/// tip | Совет
+Но если вы объявите модель ответа или тип возвращаемого значения, они будут использованы напрямую для сериализации данных в JSON, и ответ с корректным типом содержимого для JSON будет возвращён напрямую, без использования класса `JSONResponse`.
-Ð\92озможно, `ORJSONResponse` окажеÑ\82Ñ\81Ñ\8f более бÑ\8bÑ\81Ñ\82Ñ\80Ñ\8bм ваÑ\80ианÑ\82ом.
+ÐÑ\82о идеалÑ\8cнÑ\8bй Ñ\81поÑ\81об полÑ\83Ñ\87иÑ\82Ñ\8c наилÑ\83Ñ\87Ñ\88Ñ\83Ñ\8e пÑ\80оизводиÑ\82елÑ\8cноÑ\81Ñ\82Ñ\8c.
///
### `StreamingResponse` { #streamingresponse }
-Принимает асинхронный генератор или обычный генератор/итератор и отправляет тело ответа потоково.
-
-{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
-
-#### Использование `StreamingResponse` с файлоподобными объектами { #using-streamingresponse-with-file-like-objects }
+Принимает асинхронный генератор или обычный генератор/итератор (функцию с `yield`) и отправляет тело ответа потоково.
-Если у вас есть <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">файлоподобный</a> объект (например, объект, возвращаемый `open()`), вы можете создать функцию-генератор для итерации по этому файлоподобному объекту.
+{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}
-Таким образом, вам не нужно сначала читать всё в память, вы можете передать эту функцию-генератор в `StreamingResponse` и вернуть его.
-
-Это включает многие библиотеки для работы с облачным хранилищем, обработки видео и т.д.
+/// note | Технические детали
-{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
+Задача `async` может быть отменена только при достижении `await`. Если `await` отсутствует, генератор (функция с `yield`) не может быть корректно отменён и может продолжить работу даже после запроса на отмену.
-1. Это функция-генератор. Она является «функцией-генератором», потому что содержит оператор(ы) `yield` внутри.
-2. Используя блок `with`, мы гарантируем, что файлоподобный объект будет закрыт после завершения работы функции-генератора. То есть после того, как она закончит отправку ответа.
-3. Этот `yield from` говорит функции итерироваться по объекту с именем `file_like`. И затем, для каждой итерации, отдавать эту часть как исходящую из этой функции-генератора (`iterfile`).
+Так как этому небольшому примеру не нужны операторы `await`, мы добавляем `await anyio.sleep(0)`, чтобы дать циклу событий возможность обработать отмену.
- Таким образом, это функция-генератор, которая внутренне передаёт работу по «генерации» чему-то другому.
+Это ещё более важно для больших или бесконечных потоков.
- Делая это таким образом, мы можем поместить её в блок `with` и тем самым гарантировать, что файлоподобный объект будет закрыт после завершения.
+///
/// tip | Совет
-Заметьте, что здесь мы используем стандартный `open()`, который не поддерживает `async` и `await`, поэтому объявляем операцию пути обычной `def`.
+Вместо того чтобы возвращать `StreamingResponse` напрямую, вероятно, лучше следовать стилю из раздела [Передача данных потоком](./stream-data.md) - так гораздо удобнее, и отмена обрабатывается «за кулисами».
+
+Если вы передаёте JSON Lines потоком, следуйте руководству [Поток JSON Lines](../tutorial/stream-json-lines.md).
///
Вы можете создать собственный класс ответа, унаследовавшись от `Response`, и использовать его.
-Например, предположим, что вы хотите использовать <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, но с некоторыми пользовательскими настройками, которые не используются во встроенном классе `ORJSONResponse`.
+Например, предположим, что вы хотите использовать [`orjson`](https://github.com/ijl/orjson) с некоторыми настройками.
Скажем, вы хотите, чтобы возвращался отформатированный JSON с отступами, то есть хотите использовать опцию orjson `orjson.OPT_INDENT_2`.
Разумеется, вы наверняка найдёте гораздо более полезные способы воспользоваться этим, чем просто форматирование JSON. 😉
+### `orjson` или Модель ответа { #orjson-or-response-model }
+
+Если вы стремитесь увеличить производительность, вероятно, лучше использовать [Модель ответа](../tutorial/response-model.md), чем ответ на базе `orjson`.
+
+С моделью ответа FastAPI использует Pydantic для сериализации данных в JSON, без промежуточных шагов, таких как преобразование через `jsonable_encoder`, которое происходило бы в любом другом случае.
+
+А под капотом Pydantic использует те же базовые механизмы на Rust, что и `orjson`, для сериализации в JSON, так что с моделью ответа вы и так получите лучшую производительность.
+
## Класс ответа по умолчанию { #default-response-class }
При создании экземпляра класса **FastAPI** или `APIRouter` вы можете указать, какой класс ответа использовать по умолчанию.
Параметр, который это определяет, — `default_response_class`.
-В примере ниже **FastAPI** будет использовать `ORJSONResponse` по умолчанию во всех операциях пути вместо `JSONResponse`.
+В примере ниже **FastAPI** будет использовать `HTMLResponse` по умолчанию во всех операциях пути, вместо JSON.
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
## Дополнительная документация { #additional-documentation }
-Вы также можете объявить тип содержимого и многие другие детали в OpenAPI с помощью `responses`: [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Вы также можете объявить тип содержимого и многие другие детали в OpenAPI с помощью `responses`: [Дополнительные ответы в OpenAPI](additional-responses.md).
FastAPI построен поверх **Pydantic**, и я показывал вам, как использовать Pydantic-модели для объявления HTTP-запросов и HTTP-ответов.
-Но FastAPI также поддерживает использование <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> тем же способом:
+Но FastAPI также поддерживает использование [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) тем же способом:
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
-Это по-прежнему поддерживается благодаря **Pydantic**, так как в нём есть <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">встроенная поддержка `dataclasses`</a>.
+Это по-прежнему поддерживается благодаря **Pydantic**, так как в нём есть [встроенная поддержка `dataclasses`](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel).
Так что даже если в коде выше Pydantic не используется явно, FastAPI использует Pydantic, чтобы конвертировать стандартные dataclasses в собственный вариант dataclasses от Pydantic.
Как и всегда в FastAPI, вы можете сочетать `def` и `async def` по необходимости.
- Если хотите освежить в памяти, когда что использовать, посмотрите раздел _"Нет времени?"_ в документации про [`async` и `await`](../async.md#in-a-hurry){.internal-link target=_blank}.
+ Если хотите освежить в памяти, когда что использовать, посмотрите раздел _"Нет времени?"_ в документации про [`async` и `await`](../async.md#in-a-hurry).
9. Эта *функция-обработчик пути* возвращает не dataclasses (хотя могла бы), а список словарей с внутренними данными.
Вы также можете комбинировать `dataclasses` с другими Pydantic-моделями, наследоваться от них, включать их в свои модели и т.д.
-Чтобы узнать больше, посмотрите <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">документацию Pydantic о dataclasses</a>.
+Чтобы узнать больше, посмотрите [документацию Pydantic о dataclasses](https://docs.pydantic.dev/latest/concepts/dataclasses/).
## Версия { #version }
Немного технических подробностей для любопытных умников. 🤓
-Под капотом, в ASGI-технической спецификации, это часть <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Протокола Lifespan</a>, и он определяет события `startup` и `shutdown`.
+Под капотом, в ASGI-технической спецификации, это часть [Протокола Lifespan](https://asgi.readthedocs.io/en/latest/specs/lifespan.html), и он определяет события `startup` и `shutdown`.
/// info | Информация
-Вы можете прочитать больше про обработчики `lifespan` в Starlette в <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">документации Starlette по Lifespan</a>.
+Вы можете прочитать больше про обработчики `lifespan` в Starlette в [документации Starlette по Lifespan](https://www.starlette.dev/lifespan/).
Включая то, как работать с состоянием lifespan, которое можно использовать в других частях вашего кода.
## Подприложения { #sub-applications }
-🚨 Имейте в виду, что эти события lifespan (startup и shutdown) будут выполнены только для основного приложения, а не для [Подприложения — Mounts](sub-applications.md){.internal-link target=_blank}.
+🚨 Имейте в виду, что эти события lifespan (startup и shutdown) будут выполнены только для основного приложения, а не для [Подприложения — Mounts](sub-applications.md).
## Генераторы SDK с открытым исходным кодом { #open-source-sdk-generators }
-Гибкий вариант — <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>, который поддерживает **многие языки программирования** и умеет генерировать SDK из вашей спецификации OpenAPI.
+Гибкий вариант — [OpenAPI Generator](https://openapi-generator.tech/), который поддерживает **многие языки программирования** и умеет генерировать SDK из вашей спецификации OpenAPI.
-Для **TypeScript‑клиентов** <a href="https://heyapi.dev/" class="external-link" target="_blank">Hey API</a> — специализированное решение, обеспечивающее оптимальный опыт для экосистемы TypeScript.
+Для **TypeScript‑клиентов** [Hey API](https://heyapi.dev/) — специализированное решение, обеспечивающее оптимальный опыт для экосистемы TypeScript.
-Больше генераторов SDK можно найти на <a href="https://openapi.tools/#sdk" class="external-link" target="_blank">OpenAPI.Tools</a>.
+Больше генераторов SDK можно найти на [OpenAPI.Tools](https://openapi.tools/#sdk).
/// tip | Совет
В этом разделе представлены решения с **венчурной поддержкой** и **поддержкой компаний** от компаний, которые спонсируют FastAPI. Эти продукты предоставляют **дополнительные возможности** и **интеграции** сверх высококачественно генерируемых SDK.
-Благодаря ✨ [**спонсорству FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ эти компании помогают обеспечивать, чтобы фреймворк и его **экосистема** оставались здоровыми и **устойчивыми**.
+Благодаря ✨ [**спонсорству FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ эти компании помогают обеспечивать, чтобы фреймворк и его **экосистема** оставались здоровыми и **устойчивыми**.
Их спонсорство также демонстрирует серьёзную приверженность **сообществу** FastAPI (вам), показывая, что им важно не только предоставлять **отличный сервис**, но и поддерживать **надёжный и процветающий фреймворк** FastAPI. 🙇
Например, вы можете попробовать:
-* <a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a>
-* <a href="https://www.stainless.com/?utm_source=fastapi&utm_medium=referral" class="external-link" target="_blank">Stainless</a>
-* <a href="https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi" class="external-link" target="_blank">liblab</a>
+* [Speakeasy](https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship)
+* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
+* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
Некоторые из этих решений также могут быть open source или иметь бесплатные тарифы, так что вы сможете попробовать их без финансовых затрат. Другие коммерческие генераторы SDK доступны и их можно найти онлайн. 🤓
Это сгенерирует TypeScript SDK в `./src/client`.
-Вы можете узнать, как <a href="https://heyapi.dev/openapi-ts/get-started" class="external-link" target="_blank">установить `@hey-api/openapi-ts`</a> и почитать о <a href="https://heyapi.dev/openapi-ts/output" class="external-link" target="_blank">сгенерированном результате</a> на их сайте.
+Вы можете узнать, как [установить `@hey-api/openapi-ts`](https://heyapi.dev/openapi-ts/get-started) и почитать о [сгенерированном результате](https://heyapi.dev/openapi-ts/output) на их сайте.
### Использование SDK { #using-the-sdk }
-Теперь вы можете импортировать и использовать клиентский код. Это может выглядеть так, обратите внимание, что вы получаете автозавершение для методoв:
+Теперь вы можете импортировать и использовать клиентский код. Это может выглядеть так, обратите внимание, что вы получаете автозавершение для методов:
<img src="/img/tutorial/generate-clients/image02.png">
## Дополнительные возможности { #additional-features }
-Основное [Учебник - Руководство пользователя](../tutorial/index.md){.internal-link target=_blank} должно быть достаточно, чтобы познакомить вас со всеми основными функциями **FastAPI**.
+Основное [Учебник - Руководство пользователя](../tutorial/index.md) должно быть достаточно, чтобы познакомить вас со всеми основными функциями **FastAPI**.
В следующих разделах вы увидите другие варианты, конфигурации и дополнительные возможности.
## Сначала прочитайте Учебник - Руководство пользователя { #read-the-tutorial-first }
-Вы все еще можете использовать большинство функций **FastAPI** со знаниями из [Учебник - Руководство пользователя](../tutorial/index.md){.internal-link target=_blank}.
+Вы все еще можете использовать большинство функций **FastAPI** со знаниями из [Учебник - Руководство пользователя](../tutorial/index.md).
И следующие разделы предполагают, что вы уже прочитали его, и предполагают, что вы знаете эти основные идеи.
--- /dev/null
+# JSON с байтами в Base64 { #json-with-bytes-as-base64 }
+
+Если вашему приложению нужно принимать и отправлять JSON-данные, но при этом необходимо включать в них бинарные данные, вы можете кодировать их в base64.
+
+## Base64 и файлы { #base64-vs-files }
+
+Сначала рассмотрите возможность использовать [Файлы в запросе](../tutorial/request-files.md) для загрузки бинарных данных и [Пользовательский HTTP-ответ — FileResponse](./custom-response.md#fileresponse--fileresponse-) для отправки бинарных данных вместо кодирования их в JSON.
+
+JSON может содержать только строки в кодировке UTF-8, поэтому он не может содержать «сырые» байты.
+
+Base64 может кодировать бинарные данные в строки, но для этого используется больше символов, чем в исходных бинарных данных, поэтому обычно это менее эффективно, чем обычные файлы.
+
+Используйте base64 только если вам действительно нужно включать бинарные данные в JSON и вы не можете использовать файлы для этого.
+
+## Pydantic `bytes` { #pydantic-bytes }
+
+Вы можете объявить Pydantic-модель с полями `bytes`, а затем использовать `val_json_bytes` в конфиге модели, чтобы указать использовать base64 для валидации входящих JSON-данных; как часть этой валидации строка base64 будет декодирована в байты.
+
+{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:9,29:35] hl[9] *}
+
+Если вы откроете `/docs`, вы увидите, что поле `data` ожидает байты, закодированные в base64:
+
+<div class="screenshot">
+<img src="/img/tutorial/json-base64-bytes/image01.png">
+</div>
+
+Вы можете отправить такой HTTP-запрос:
+
+```json
+{
+ "description": "Some data",
+ "data": "aGVsbG8="
+}
+```
+
+/// tip | Совет
+
+`aGVsbG8=` — это base64-кодирование строки `hello`.
+
+///
+
+Затем Pydantic декодирует строку base64 и передаст вам исходные байты в поле `data` модели.
+
+Вы получите такой HTTP-ответ:
+
+```json
+{
+ "description": "Some data",
+ "content": "hello"
+}
+```
+
+## Pydantic `bytes` для выходных данных { #pydantic-bytes-for-output-data }
+
+Вы также можете использовать поля `bytes` с `ser_json_bytes` в конфиге модели для выходных данных, и Pydantic будет сериализовать байты в base64 при формировании JSON-ответа.
+
+{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,12:16,29,38:41] hl[16] *}
+
+## Pydantic `bytes` для входных и выходных данных { #pydantic-bytes-for-input-and-output-data }
+
+И, конечно, вы можете использовать одну и ту же модель, настроенную на использование base64, чтобы обрабатывать и входящие данные (валидация) с `val_json_bytes`, и исходящие данные (сериализация) с `ser_json_bytes` при приеме и отправке JSON-данных.
+
+{* ../../docs_src/json_base64_bytes/tutorial001_py310.py ln[1:2,19:26,29,44:46] hl[23:26] *}
# Расширенное использование middleware { #advanced-middleware }
-В основном руководстве вы читали, как добавить [пользовательское middleware](../tutorial/middleware.md){.internal-link target=_blank} в ваше приложение.
+В основном руководстве вы читали, как добавить [пользовательское middleware](../tutorial/middleware.md) в ваше приложение.
-А затем — как работать с [CORS с помощью `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
+А затем — как работать с [CORS с помощью `CORSMiddleware`](../tutorial/cors.md).
В этом разделе посмотрим, как использовать другие middleware.
Например:
-- <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">`ProxyHeadersMiddleware` от Uvicorn</a>
-- <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>
+- [`ProxyHeadersMiddleware` от Uvicorn](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
+- [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
-Чтобы увидеть другие доступные middleware, посмотрите <a href="https://www.starlette.dev/middleware/" class="external-link" target="_blank">документацию по middleware в Starlette</a> и <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">список ASGI Awesome</a>.
+Чтобы увидеть другие доступные middleware, посмотрите [документацию по middleware в Starlette](https://www.starlette.dev/middleware/) и [список ASGI Awesome](https://github.com/florimondmanca/awesome-asgi).
/// tip | Совет
-Query-параметр `callback_url` использует тип Pydantic <a href="https://docs.pydantic.dev/latest/api/networks/" class="external-link" target="_blank">Url</a>.
+Query-параметр `callback_url` использует тип Pydantic [Url](https://docs.pydantic.dev/latest/api/networks/).
///
Сам обратный вызов — это всего лишь HTTP-запрос.
-Реализуя обратный вызов, вы можете использовать, например, <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a> или <a href="https://requests.readthedocs.io/" class="external-link" target="_blank">Requests</a>.
+Реализуя обратный вызов, вы можете использовать, например, [HTTPX](https://www.python-httpx.org) или [Requests](https://requests.readthedocs.io/).
///
Есть 2 основных отличия от обычной *операции пути*:
* Ей не нужен реальный код, потому что ваше приложение никогда не будет вызывать эту функцию. Она используется только для документирования *внешнего API*. Поэтому в функции может быть просто `pass`.
-* *Путь* может содержать <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">выражение OpenAPI 3</a> (подробнее ниже), где можно использовать переменные с параметрами и части исходного HTTP-запроса, отправленного *вашему API*.
+* *Путь* может содержать [выражение OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression) (подробнее ниже), где можно использовать переменные с параметрами и части исходного HTTP-запроса, отправленного *вашему API*.
### Выражение пути для обратного вызова { #the-callback-path-expression }
-*Путь* обратного вызова может содержать <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">выражение OpenAPI 3</a>, которое может включать части исходного запроса, отправленного *вашему API*.
+*Путь* обратного вызова может содержать [выражение OpenAPI 3](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression), которое может включать части исходного запроса, отправленного *вашему API*.
В нашем случае это `str`:
### Проверьте документацию { #check-the-docs }
-Теперь вы можете запустить приложение и перейти по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Теперь вы можете запустить приложение и перейти по адресу [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Вы увидите документацию, включающую раздел «Callbacks» для вашей *операции пути*, который показывает, как должен выглядеть *внешний API*:
Обычно процесс таков: вы определяете в своем коде, какое сообщение вы будете отправлять, то есть тело запроса.
-Вы также определяете, в какие моменты (при каких событиях) ваше приложение будет отправлять эти запросы.
+Вы также определяете, в какие моменты (при каких событиях) ваше приложение будет отправлять эти запросы (события).
А ваши пользователи каким-то образом (например, в веб‑панели) указывают URL-адрес, на который ваше приложение должно отправлять эти запросы.
### Посмотрите документацию { #check-the-docs }
-Теперь вы можете запустить приложение и перейти по ссылке <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Теперь вы можете запустить приложение и перейти по ссылке [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Вы увидите, что в документации есть обычные операции пути, а также появились вебхуки:
Также можно объявлять дополнительные ответы с их моделями, статус-кодами и т.д.
-В документации есть целая глава об этом — [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+В документации есть целая глава об этом — [Дополнительные ответы в OpenAPI](additional-responses.md).
## Дополнительные данные OpenAPI { #openapi-extra }
/// note | Технические детали
-В спецификации OpenAPI это называется <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Объект операции</a>.
+В спецификации OpenAPI это называется [Объект операции](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object).
///
Это низкоуровневая возможность расширения.
-Если вам нужно лишь объявить дополнительные ответы, удобнее сделать это через [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Если вам нужно лишь объявить дополнительные ответы, удобнее сделать это через [Дополнительные ответы в OpenAPI](additional-responses.md).
///
# Response - Изменение статус-кода { #response-change-status-code }
-Вы, вероятно, уже читали о том, что можно установить [статус-код ответа по умолчанию](../tutorial/response-status-code.md){.internal-link target=_blank}.
+Вы, вероятно, уже читали о том, что можно установить [статус-код ответа по умолчанию](../tutorial/response-status-code.md).
Но в некоторых случаях нужно вернуть другой статус-код, отличный от значения по умолчанию.
Вы также можете установить Cookies, если возвращаете `Response` напрямую в вашем коде.
-Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md){.internal-link target=_blank}.
+Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md).
Затем установите cookies и верните этот объект:
///
-Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с <a href="https://www.starlette.dev/responses/#set-cookie" class="external-link" target="_blank">документацией Starlette</a>.
+Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с [документацией Starlette](https://www.starlette.dev/responses/#set-cookie).
Когда вы создаёте **FastAPI** *операцию пути*, вы можете возвращать из неё любые данные: `dict`, `list`, Pydantic-модель, модель базы данных и т.д.
-Ð\9fо Ñ\83молÑ\87аниÑ\8e **FastAPI** авÑ\82омаÑ\82иÑ\87еÑ\81ки пÑ\80еобÑ\80азÑ\83еÑ\82 возвÑ\80аÑ\89аемое знаÑ\87ение в JSON Ñ\81 помоÑ\89Ñ\8cÑ\8e `jsonable_encoder`, как опиÑ\81ано в [JSON кодиÑ\80овÑ\89ик](../tutorial/encoder.md){.internal-link target=_blank}.
+Ð\95Ñ\81ли вÑ\8b обÑ\8aÑ\8fвиÑ\82е [Ð\9cоделÑ\8c оÑ\82веÑ\82а](../tutorial/response-model.md), FastAPI бÑ\83деÑ\82 иÑ\81полÑ\8cзоваÑ\82Ñ\8c еÑ\91 длÑ\8f Ñ\81еÑ\80иализаÑ\86ии даннÑ\8bÑ\85 в JSON Ñ\81 помоÑ\89Ñ\8cÑ\8e Pydantic.
-Ð\97аÑ\82ем "под капоÑ\82ом" Ñ\8dÑ\82и даннÑ\8bе, Ñ\81овмеÑ\81Ñ\82имÑ\8bе Ñ\81 JSON (напÑ\80имеÑ\80 `dict`), помеÑ\89аÑ\8eÑ\82Ñ\81Ñ\8f в `JSONResponse`, коÑ\82оÑ\80Ñ\8bй иÑ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f длÑ\8f оÑ\82пÑ\80авки оÑ\82веÑ\82а клиенÑ\82Ñ\83.
+Ð\95Ñ\81ли вÑ\8b не обÑ\8aÑ\8fвиÑ\82е моделÑ\8c оÑ\82веÑ\82а, FastAPI иÑ\81полÑ\8cзÑ\83еÑ\82 `jsonable_encoder`, как опиÑ\81ано в [JSON кодиÑ\80овÑ\89ик](../tutorial/encoder.md), и помеÑ\81Ñ\82иÑ\82 Ñ\80езÑ\83лÑ\8cÑ\82аÑ\82 в `JSONResponse`.
-Ð\9dо вÑ\8b можеÑ\82е возвÑ\80аÑ\89аÑ\82Ñ\8c `JSONResponse` напÑ\80Ñ\8fмÑ\83Ñ\8e из ваÑ\88иÑ\85 *опеÑ\80аÑ\86ий пÑ\83Ñ\82и*.
+Также вÑ\8b можеÑ\82е Ñ\81оздаÑ\82Ñ\8c `JSONResponse` напÑ\80Ñ\8fмÑ\83Ñ\8e и веÑ\80нÑ\83Ñ\82Ñ\8c его.
-Это может быть полезно, например, если нужно вернуть пользовательские HTTP-заголовки или cookie.
+/// tip | Подсказка
+
+Обычно вы получите значительно лучшую производительность, если будете использовать [Модель ответа](../tutorial/response-model.md), а не возвращать `JSONResponse` напрямую, так как в этом случае сериализация данных с помощью Pydantic происходит на стороне Rust.
+
+///
## Возврат `Response` { #return-a-response }
-Ð\9dа Ñ\81амом деле, вÑ\8b можеÑ\82е возвÑ\80аÑ\89аÑ\82Ñ\8c лÑ\8eбой обÑ\8aекÑ\82 `Response` или его подкласс.
+Ð\92Ñ\8b можеÑ\82е возвÑ\80аÑ\89аÑ\82Ñ\8c `Response` или лÑ\8eбой его подкласс.
-/// tip | Подсказка
+/// info | Информация
`JSONResponse` сам по себе является подклассом `Response`.
Это даёт вам большую гибкость. Вы можете возвращать любые типы данных, переопределять любые объявления или валидацию данных и т.д.
+Это также накладывает на вас ответственность. Вам нужно удостовериться, что возвращаемые данные корректны, в правильном формате, что их можно сериализовать и т.д.
+
## Использование `jsonable_encoder` в `Response` { #using-the-jsonable-encoder-in-a-response }
Поскольку **FastAPI** не изменяет объект `Response`, который вы возвращаете, вы должны убедиться, что его содержимое готово к отправке.
Теперь давайте посмотрим, как можно использовать это для возврата пользовательского ответа.
-Допустим, вы хотите вернуть ответ в формате <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a>.
+Допустим, вы хотите вернуть ответ в формате [XML](https://en.wikipedia.org/wiki/XML).
Вы можете поместить ваш XML-контент в строку, поместить её в `Response` и вернуть:
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
+## Как работает модель ответа { #how-a-response-model-works }
+
+Когда вы объявляете [Модель ответа - возвращаемый тип](../tutorial/response-model.md) в операции пути, **FastAPI** будет использовать её для сериализации данных в JSON с помощью Pydantic.
+
+{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
+
+Поскольку это происходит на стороне Rust, производительность будет значительно выше, чем если бы это выполнялось обычным Python и классом `JSONResponse`.
+
+При использовании `response_model` или возвращаемого типа FastAPI не будет использовать `jsonable_encoder` для преобразования данных (что было бы медленнее) и не будет использовать класс `JSONResponse`.
+
+Вместо этого он берёт JSON-байты, сгенерированные Pydantic с использованием модели ответа (или возвращаемого типа), и возвращает `Response` с правильным типом содержимого для JSON (`application/json`) напрямую.
+
## Примечания { #notes }
Когда вы возвращаете объект `Response` напрямую, его данные не валидируются, не преобразуются (не сериализуются) и не документируются автоматически.
-Но вы всё равно можете задокументировать это, как описано в [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Но вы всё равно можете задокументировать это, как описано в [Дополнительные ответы в OpenAPI](additional-responses.md).
В следующих разделах вы увидите, как использовать/объявлять такие кастомные `Response`, при этом сохраняя автоматическое преобразование данных, документацию и т.д.
Вы также можете добавить HTTP-заголовки, когда возвращаете `Response` напрямую.
-Создайте ответ, как описано в [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}, и передайте заголовки как дополнительный параметр:
+Создайте ответ, как описано в [Вернуть Response напрямую](response-directly.md), и передайте заголовки как дополнительный параметр:
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
## Пользовательские HTTP-заголовки { #custom-headers }
-Помните, что собственные проприетарные заголовки можно добавлять, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">используя префикс `X-`</a>.
+Помните, что собственные проприетарные заголовки можно добавлять, [используя префикс `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
-Но если у вас есть пользовательские заголовки, которые вы хотите показывать клиенту в браузере, вам нужно добавить их в настройки CORS (подробнее см. в [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), используя параметр `expose_headers`, описанный в <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">документации Starlette по CORS</a>.
+Но если у вас есть пользовательские заголовки, которые вы хотите показывать клиенту в браузере, вам нужно добавить их в настройки CORS (подробнее см. в [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)), используя параметр `expose_headers`, описанный в [документации Starlette по CORS](https://www.starlette.dev/middleware/#corsmiddleware).
Используйте зависимость, чтобы проверить, корректны ли имя пользователя и пароль.
-Для этого используйте стандартный модуль Python <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a> для проверки имени пользователя и пароля.
+Для этого используйте стандартный модуль Python [`secrets`](https://docs.python.org/3/library/secrets.html) для проверки имени пользователя и пароля.
`secrets.compare_digest()` должен получать `bytes` или `str`, который содержит только символы ASCII (английские символы). Это значит, что он не будет работать с символами вроде `á`, как в `Sebastián`.
## Дополнительные возможности { #additional-features }
-Есть дополнительные возможности для работы с безопасностью помимо тех, что описаны в [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md){.internal-link target=_blank}.
+Есть дополнительные возможности для работы с безопасностью помимо тех, что описаны в [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md).
/// tip | Совет
-Следующие разделы **не обязательно являются «продвинутыми»**.
+Следующие разделы не обязательно являются «продвинутыми».
И возможно, что решение для вашего варианта использования находится в одном из них.
## Сначала прочитайте руководство { #read-the-tutorial-first }
-В следующих разделах предполагается, что вы уже прочитали основной [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md){.internal-link target=_blank}.
+В следующих разделах предполагается, что вы уже прочитали основной [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md).
Все они основаны на тех же концепциях, но предоставляют дополнительные возможности.
# OAuth2 scopes { #oauth2-scopes }
-Вы можете использовать OAuth2 scopes (scope - область, рамки) напрямую с **FastAPI** — они интегрированы и работают бесшовно.
+Вы можете использовать OAuth2 scopes напрямую с **FastAPI** — они интегрированы и работают бесшовно.
Это позволит вам иметь более детальную систему разрешений по стандарту OAuth2, интегрированную в ваше OpenAPI‑приложение (и документацию API).
## Взгляд издалека { #global-view }
-Сначала быстро посмотрим, что изменилось по сравнению с примерами из основного раздела **Учебник - Руководство пользователя** — [OAuth2 с паролем (и хешированием), Bearer с JWT-токенами](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Теперь — с использованием OAuth2 scopes:
+Сначала быстро посмотрим, что изменилось по сравнению с примерами из основного раздела **Учебник - Руководство пользователя** — [OAuth2 с паролем (и хешированием), Bearer с JWT-токенами](../../tutorial/security/oauth2-jwt.md). Теперь — с использованием OAuth2 scopes:
{* ../../docs_src/security/tutorial005_an_py310.py hl[5,9,13,47,65,106,108:116,122:126,130:136,141,157] *}
///
-FastAPI включает утилиты для всех этих OAuth2‑flows в `fastapi.security.oauth2`.
+**FastAPI** включает утилиты для всех этих OAuth2‑flows в `fastapi.security.oauth2`.
## `Security` в параметре `dependencies` декоратора { #security-in-decorator-dependencies }
-Точно так же, как вы можете определить `list` из `Depends` в параметре `dependencies` декоратора (см. [Зависимости в декораторах операции пути](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), вы можете использовать там и `Security` со `scopes`.
+Точно так же, как вы можете определить `list` из `Depends` в параметре `dependencies` декоратора (см. [Зависимости в декораторах операции пути](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md)), вы можете использовать там и `Security` со `scopes`.
/// tip | Совет
-Чтобы понять, что такое переменные окружения, вы можете прочитать [Переменные окружения](../environment-variables.md){.internal-link target=_blank}.
+Чтобы понять, что такое переменные окружения, вы можете прочитать [Переменные окружения](../environment-variables.md).
///
## Pydantic `Settings` { #pydantic-settings }
-К счастью, Pydantic предоставляет отличную утилиту для работы с этими настройками, поступающими из переменных окружения, — <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" class="external-link" target="_blank">Pydantic: управление настройками</a>.
+К счастью, Pydantic предоставляет отличную утилиту для работы с этими настройками, поступающими из переменных окружения, — [Pydantic: управление настройками](https://docs.pydantic.dev/latest/concepts/pydantic_settings/).
### Установка `pydantic-settings` { #install-pydantic-settings }
-Сначала убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установили пакет `pydantic-settings`:
+Сначала убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет `pydantic-settings`:
<div class="termy">
## Настройки в другом модуле { #settings-in-another-module }
-Вы можете вынести эти настройки в другой модуль, как показано в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+Вы можете вынести эти настройки в другой модуль, как показано в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md).
Например, у вас может быть файл `config.py` со следующим содержимым:
/// tip | Совет
-Вам также понадобится файл `__init__.py`, как в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+Вам также понадобится файл `__init__.py`, как в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md).
///
///
-Pydantic поддерживает чтение таких файлов с помощью внешней библиотеки. Подробнее вы можете прочитать здесь: <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic Settings: поддержка Dotenv (.env)</a>.
+Pydantic поддерживает чтение таких файлов с помощью внешней библиотеки. Подробнее вы можете прочитать здесь: [Pydantic Settings: поддержка Dotenv (.env)](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support).
/// tip | Совет
/// tip | Совет
-Атрибут `model_config` используется только для конфигурации Pydantic. Подробнее см. <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a>.
+Атрибут `model_config` используется только для конфигурации Pydantic. Подробнее см. [Pydantic: Concepts: Configuration](https://docs.pydantic.dev/latest/concepts/config/).
///
Таким образом, она ведет себя почти как глобальная переменная. Но так как используется функция‑зависимость, мы можем легко переопределить ее для тестирования.
-`@lru_cache` — часть `functools`, что входит в стандартную библиотеку Python. Подробнее можно прочитать в <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">документации Python по `@lru_cache`</a>.
+`@lru_cache` — часть `functools`, что входит в стандартную библиотеку Python. Подробнее можно прочитать в [документации Python по `@lru_cache`](https://docs.python.org/3/library/functools.html#functools.lru_cache).
## Итоги { #recap }
--- /dev/null
+# Потоковая передача данных { #stream-data }
+
+Если вам нужно передавать потоковые данные, которые можно представить как JSON, воспользуйтесь [стримингом JSON Lines](../tutorial/stream-json-lines.md).
+
+Но если вы хотите передавать в потоке чистые бинарные данные или строки, ниже показано, как это сделать.
+
+/// info | Информация
+
+Добавлено в FastAPI 0.134.0.
+
+///
+
+## Варианты использования { #use-cases }
+
+Это можно использовать, если вы хотите стримить чистые строки, например, напрямую из вывода сервиса **AI LLM**.
+
+Также вы можете стримить **большие бинарные файлы**, передавая каждый чанк данных по мере чтения, без необходимости загружать всё в память сразу.
+
+Аналогично можно стримить **видео** или **аудио** — данные могут даже генерироваться по мере обработки и отправки.
+
+## «`StreamingResponse` с `yield`» { #a-streamingresponse-with-yield }
+
+Если вы укажете `response_class=StreamingResponse` в своей *функции-обработчике пути*, вы можете использовать `yield`, чтобы по очереди отправлять каждый чанк данных.
+
+{* ../../docs_src/stream_data/tutorial001_py310.py ln[1:23] hl[20,23] *}
+
+FastAPI будет передавать каждый чанк данных в `StreamingResponse` как есть, не пытаясь конвертировать его в JSON или что-то подобное.
+
+### Не-async *функции-обработчики пути* { #non-async-path-operation-functions }
+
+Можно использовать и обычные функции `def` (без `async`) и точно так же применять `yield`.
+
+{* ../../docs_src/stream_data/tutorial001_py310.py ln[26:29] hl[27] *}
+
+### Без аннотации { #no-annotation }
+
+Для потоковой передачи бинарных данных вам не нужно указывать аннотацию типа возвращаемого значения.
+
+Поскольку FastAPI не будет пытаться конвертировать данные в JSON с помощью Pydantic или сериализовать их каким-либо образом, в данном случае аннотация типа нужна только для вашего редактора кода и инструментов, FastAPI её использовать не будет.
+
+{* ../../docs_src/stream_data/tutorial001_py310.py ln[32:35] hl[33] *}
+
+Это также означает, что с `StreamingResponse` у вас есть и свобода, и ответственность — производить и кодировать байты данных ровно в том виде, в котором они должны быть отправлены, независимо от аннотаций типов. 🤓
+
+### Потоковая передача байтов { #stream-bytes }
+
+Один из основных сценариев — стримить `bytes` вместо строк, и, конечно, это можно сделать.
+
+{* ../../docs_src/stream_data/tutorial001_py310.py ln[44:47] hl[47] *}
+
+## Пользовательский `PNGStreamingResponse` { #a-custom-pngstreamingresponse }
+
+В примерах выше байты данных передавались потоком, но в ответе не было HTTP-заголовка `Content-Type`, поэтому клиент не знал, какой тип данных он получает.
+
+Вы можете создать пользовательский подкласс `StreamingResponse`, который устанавливает HTTP-заголовок `Content-Type` в тип данных, которые вы стримите.
+
+Например, вы можете создать `PNGStreamingResponse`, который устанавливает HTTP-заголовок `Content-Type` в `image/png` с помощью атрибута `media_type`:
+
+{* ../../docs_src/stream_data/tutorial002_py310.py ln[6,19:20] hl[20] *}
+
+Затем вы можете использовать этот новый класс в `response_class=PNGStreamingResponse` в своей *функции-обработчике пути*:
+
+{* ../../docs_src/stream_data/tutorial002_py310.py ln[23:27] hl[23] *}
+
+### Симулировать файл { #simulate-a-file }
+
+В этом примере мы симулируем файл с помощью `io.BytesIO` — это «файлоподобный» объект, который существует только в памяти, но позволяет использовать тот же интерфейс.
+
+Например, мы можем итерироваться по нему, чтобы потреблять его содержимое, как и по обычному файлу.
+
+{* ../../docs_src/stream_data/tutorial002_py310.py ln[1:27] hl[3,12:13,25] *}
+
+/// note | Технические детали
+
+Две другие переменные, `image_base64` и `binary_image`, — это изображение, закодированное в Base64, а затем преобразованное в байты, после чего переданное в `io.BytesIO`.
+
+Только для того, чтобы всё помещалось в одном файле для этого примера, и вы могли скопировать код и запустить его как есть. 🥚
+
+///
+
+Используя блок `with`, мы гарантируем, что объект, ведущий себя как файл, будет закрыт после завершения работы функции‑генератора (функции с `yield`). То есть после того, как она закончит отправку ответа.
+
+В этом конкретном примере это не столь важно, потому что это «фейковый» файл в памяти (`io.BytesIO`), но для реального файла важно удостовериться, что файл закрыт после завершения работы с ним.
+
+### Файлы и async { #files-and-async }
+
+В большинстве случаев «файлоподобные» объекты по умолчанию не совместимы с async и await.
+
+Например, у них нет `await file.read()` или `async for chunk in file`.
+
+И во многих случаях чтение таких объектов будет блокирующей операцией (которая может заблокировать цикл событий), потому что данные читаются с диска или из сети.
+
+/// info | Информация
+
+Приведённый выше пример — исключение, потому что объект `io.BytesIO` уже находится в памяти, поэтому чтение ничего не блокирует.
+
+Но во многих случаях чтение файла или «файлоподобного» объекта будет блокировать.
+
+///
+
+Чтобы не блокировать цикл событий, вы можете просто объявить *функцию-обработчик пути* обычной `def` вместо `async def`. Тогда FastAPI выполнит её в воркере из пула потоков (threadpool), чтобы не блокировать основной цикл.
+
+{* ../../docs_src/stream_data/tutorial002_py310.py ln[30:34] hl[31] *}
+
+/// tip | Совет
+
+Если вам нужно вызвать блокирующий код изнутри async-функции, или async-функцию изнутри блокирующей функции, вы можете использовать [Asyncer](https://asyncer.tiangolo.com), родственную библиотеку к FastAPI.
+
+///
+
+### `yield from` { #yield-from }
+
+Когда вы итерируетесь по чему‑то, например, по «файлоподобному» объекту, и делаете `yield` для каждого элемента, вы можете также использовать `yield from`, чтобы отдавать каждый элемент напрямую и не писать цикл `for`.
+
+Это не специфично для FastAPI, это просто Python, но полезный приём. 😎
+
+{* ../../docs_src/stream_data/tutorial002_py310.py ln[37:40] hl[40] *}
--- /dev/null
+# Строгая проверка HTTP-заголовка Content-Type { #strict-content-type-checking }
+
+По умолчанию **FastAPI** использует строгую проверку HTTP-заголовка `Content-Type` для JSON-тел запросов. Это означает, что JSON-запросы должны включать корректный заголовок `Content-Type` (например, `application/json`), чтобы тело запроса было обработано как JSON.
+
+## Риск CSRF { #csrf-risk }
+
+Такое поведение по умолчанию обеспечивает защиту от класса атак **Cross-Site Request Forgery (CSRF)** в очень специфическом сценарии.
+
+Эти атаки используют то, что браузеры позволяют скриптам отправлять запросы без выполнения CORS preflight, когда они:
+
+- не имеют заголовка `Content-Type` (например, при использовании `fetch()` с телом `Blob`)
+- и не отправляют никаких учетных данных аутентификации.
+
+Этот тип атак в основном актуален, когда:
+
+- приложение запускается локально (например, на `localhost`) или во внутренней сети
+- и в приложении нет аутентификации, оно предполагает, что любому запросу из той же сети можно доверять.
+
+## Пример атаки { #example-attack }
+
+Представьте, что вы сделали способ запускать локального ИИ-агента.
+
+Он предоставляет API по адресу
+
+```
+http://localhost:8000/v1/agents/multivac
+```
+
+Есть также фронтенд по адресу
+
+```
+http://localhost:8000
+```
+
+/// tip | Совет
+
+Обратите внимание, что у обоих один и тот же хост.
+
+///
+
+Через фронтенд вы можете заставлять ИИ-агента выполнять действия от вашего имени.
+
+Так как он работает локально и не в открытом интернете, вы решаете не настраивать аутентификацию, полагаясь на доступ к локальной сети.
+
+Затем один из ваших пользователей может установить это и запускать локально.
+
+Потом он может открыть вредоносный сайт, например что-то вроде
+
+```
+https://evilhackers.example.com
+```
+
+И этот вредоносный сайт отправит запросы с помощью `fetch()` с телом `Blob` к локальному API по адресу
+
+```
+http://localhost:8000/v1/agents/multivac
+```
+
+Несмотря на то, что хост вредоносного сайта и локального приложения различается, браузер не запустит CORS preflight-запрос, потому что:
+
+- Приложение работает без аутентификации, ему не нужно отправлять какие-либо учетные данные.
+- Браузер «считает», что он не отправляет JSON (из-за отсутствия заголовка `Content-Type`).
+
+В итоге вредоносный сайт может заставить локального ИИ-агента отправить злые сообщения бывшему начальнику пользователя... или что-то похуже. 😅
+
+## Открытый интернет { #open-internet }
+
+Если ваше приложение доступно в открытом интернете, вы не будете «доверять сети» и позволять кому угодно отправлять привилегированные запросы без аутентификации.
+
+Злоумышленники могут просто запустить скрипт и слать запросы к вашему API, без участия браузера, так что вы, вероятно, уже защищаете любые привилегированные эндпоинты.
+
+В этом случае эта атака/риск на вас не распространяется.
+
+Этот риск и атака в основном актуальны, когда приложение работает в локальной сети и это единственная предполагаемая защита.
+
+## Разрешение запросов без Content-Type { #allowing-requests-without-content-type }
+
+Если вам нужно поддерживать клиентов, которые не отправляют заголовок `Content-Type`, вы можете отключить строгую проверку, установив `strict_content_type=False`:
+
+{* ../../docs_src/strict_content_type/tutorial001_py310.py hl[4] *}
+
+С этой настройкой запросы без заголовка `Content-Type` будут иметь тело запроса, обработанное как JSON — это такое же поведение, как в более старых версиях FastAPI.
+
+/// info | Информация
+
+Это поведение и настройка были добавлены в FastAPI 0.132.0.
+
+///
### Проверьте автоматическую документацию API { #check-the-automatic-api-docs }
-Теперь запустите команду `fastapi` с вашим файлом:
+Теперь запустите команду `fastapi`:
<div class="termy">
```console
-$ fastapi dev main.py
+$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
-И откройте документацию по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+И откройте документацию по адресу [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Вы увидите автоматическую документацию API для основного приложения, включающую только его собственные _операции пути_:
<img src="/img/tutorial/sub-applications/image01.png">
-Затем откройте документацию для подприложения по адресу <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>.
+Затем откройте документацию для подприложения по адресу [http://127.0.0.1:8000/subapi/docs](http://127.0.0.1:8000/subapi/docs).
Вы увидите автоматическую документацию API для подприложения, включающую только его собственные _операции пути_, все под корректным префиксом подпути `/subapi`:
У подприложения также могут быть свои собственные смонтированные подприложения, и всё будет работать корректно, потому что FastAPI автоматически обрабатывает все эти `root_path`.
-Вы узнаете больше о `root_path` и о том, как использовать его явно, в разделе [За прокси](behind-a-proxy.md){.internal-link target=_blank}.
+Вы узнаете больше о `root_path` и о том, как использовать его явно, в разделе [За прокси](behind-a-proxy.md).
## Установка зависимостей { #install-dependencies }
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его и установили `jinja2`:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его и установили `jinja2`:
<div class="termy">
## Подробнее { #more-details }
-Больше подробностей, включая то, как тестировать шаблоны, смотрите в <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">документации Starlette по шаблонам</a>.
+Больше подробностей, включая то, как тестировать шаблоны, смотрите в [документации Starlette по шаблонам](https://www.starlette.dev/templates/).
/// note | Примечание
-Подробности смотрите в документации Starlette по <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">тестированию WebSocket</a>.
+Подробности смотрите в документации Starlette по [тестированию WebSocket](https://www.starlette.dev/testclient/#testing-websocket-sessions).
///
## Подробности об объекте `Request` { #details-about-the-request-object }
-Так как под капотом **FastAPI** — это **Starlette** с дополнительным слоем инструментов, вы можете при необходимости напрямую использовать объект <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`</a> из Starlette.
+Так как под капотом **FastAPI** — это **Starlette** с дополнительным слоем инструментов, вы можете при необходимости напрямую использовать объект [`Request`](https://www.starlette.dev/requests/) из Starlette.
Это также означает, что если вы получаете данные напрямую из объекта `Request` (например, читаете тело запроса), то они не будут валидироваться, конвертироваться или документироваться (с OpenAPI, для автоматического пользовательского интерфейса API) средствами FastAPI.
## Документация по `Request` { #request-documentation }
-Подробнее об <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">объекте `Request` на официальном сайте документации Starlette</a>.
+Подробнее об [объекте `Request` на официальном сайте документации Starlette](https://www.starlette.dev/requests/).
/// note | Технические детали
# Веб-сокеты { #websockets }
-Вы можете использовать <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">веб-сокеты</a> в **FastAPI**.
+Вы можете использовать [веб-сокеты](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) в **FastAPI**.
## Установка `websockets` { #install-websockets }
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его и установили `websockets` (библиотека Python, упрощающая работу с протоколом "WebSocket"):
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его и установили `websockets` (библиотека Python, упрощающая работу с протоколом "WebSocket"):
<div class="termy">
## Проверка в действии { #try-it }
-Ð\95Ñ\81ли ваÑ\88 Ñ\84айл назÑ\8bваеÑ\82Ñ\81Ñ\8f `main.py`, Ñ\82о запÑ\83Ñ\81Ñ\82иÑ\82е пÑ\80иложение командой:
+Ð\9fомеÑ\81Ñ\82иÑ\82е ваÑ\88 код в Ñ\84айл `main.py`, заÑ\82ем запÑ\83Ñ\81Ñ\82иÑ\82е пÑ\80иложение:
<div class="termy">
```console
-$ fastapi dev main.py
+$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
-Откройте браузер по адресу <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
+Откройте браузер по адресу [http://127.0.0.1:8000](http://127.0.0.1:8000).
Вы увидите следующую простенькую страницу:
В веб-сокете вызывать `HTTPException` не имеет смысла. Вместо этого нужно использовать `WebSocketException`.
-Ð\97акÑ\80Ñ\8bваÑ\8eÑ\89ий Ñ\81Ñ\82аÑ\82Ñ\83Ñ\81 код можно иÑ\81полÑ\8cзоваÑ\82Ñ\8c из <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">valid codes defined in the specification</a>.
+Ð\92Ñ\8b можеÑ\82е иÑ\81полÑ\8cзоваÑ\82Ñ\8c код закÑ\80Ñ\8bÑ\82иÑ\8f из [допÑ\83Ñ\81Ñ\82имÑ\8bÑ\85 кодов, опÑ\80еделÑ\91ннÑ\8bÑ\85 в Ñ\81пеÑ\86иÑ\84икаÑ\86ии](https://tools.ietf.org/html/rfc6455#section-7.4.1).
///
### Веб-сокеты с зависимостями: проверка в действии { #try-the-websockets-with-dependencies }
-Ð\95Ñ\81ли ваÑ\88 Ñ\84айл назÑ\8bваеÑ\82Ñ\81Ñ\8f `main.py`, Ñ\82о запÑ\83Ñ\81Ñ\82иÑ\82е пÑ\80иложение командой:
+Ð\97апÑ\83Ñ\81Ñ\82иÑ\82е пÑ\80иложение:
<div class="termy">
```console
-$ fastapi dev main.py
+$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
-Откройте браузер по адресу <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
+Откройте браузер по адресу [http://127.0.0.1:8000](http://127.0.0.1:8000).
Там вы можете задать:
## Обработка отключений и работа с несколькими клиентами { #handling-disconnections-and-multiple-clients }
-Если веб-сокет соединение закрыто, то `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере:
+Если веб-сокет соединение закрыто, то `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере.
{* ../../docs_src/websockets_/tutorial003_py310.py hl[79:81] *}
Но имейте в виду, что это будет работать только в одном процессе и только пока он активен, так как всё обрабатывается в простом списке в оперативной памяти.
-Если нужно что-то легко интегрируемое с FastAPI, но более надежное и с поддержкой Redis, PostgreSQL или другого, то можно воспользоваться <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a>.
+Если нужно что-то легко интегрируемое с FastAPI, но более надежное и с поддержкой Redis, PostgreSQL или другого, то можно воспользоваться [encode/broadcaster](https://github.com/encode/broadcaster).
///
Для более глубокого изучения темы воспользуйтесь документацией Starlette:
-* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">The `WebSocket` class</a>.
-* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">Class-based WebSocket handling</a>.
+* [Класс `WebSocket`](https://www.starlette.dev/websockets/).
+* [Обработка WebSocket на основе классов](https://www.starlette.dev/endpoints/#websocketendpoint).
# Подключение WSGI — Flask, Django и другие { #including-wsgi-flask-django-others }
-Вы можете монтировать WSGI‑приложения, как вы видели в [Подприложения — Mounts](sub-applications.md){.internal-link target=_blank}, [За прокси‑сервером](behind-a-proxy.md){.internal-link target=_blank}.
+Вы можете монтировать WSGI‑приложения, как вы видели в [Подприложения — Mounts](sub-applications.md), [За прокси‑сервером](behind-a-proxy.md).
Для этого вы можете использовать `WSGIMiddleware` и обернуть им ваше WSGI‑приложение, например Flask, Django и т.д.
А всё остальное будет обрабатываться **FastAPI**.
-Если вы запустите это и перейдёте по <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a>, вы увидите HTTP‑ответ от Flask:
+Если вы запустите это и перейдёте по [http://localhost:8000/v1/](http://localhost:8000/v1/), вы увидите HTTP‑ответ от Flask:
```txt
Hello, World from Flask!
```
-А если вы перейдёте по <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a>, вы увидите HTTP‑ответ от FastAPI:
+А если вы перейдёте по [http://localhost:8000/v2](http://localhost:8000/v2), вы увидите HTTP‑ответ от FastAPI:
```JSON
{
## Предшествующие инструменты { #previous-tools }
-### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> { #django }
+### [Django](https://www.djangoproject.com/) { #django }
Это самый популярный Python-фреймворк, ему широко доверяют. Он используется для построения систем вроде Instagram.
Он был создан для генерации HTML на бэкенде, а не для создания API, используемых современным фронтендом (например, React, Vue.js и Angular) или другими системами (например, устройствами <abbr title="Internet of Things – Интернет вещей">IoT</abbr>), которые с ним общаются.
-### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
+### [Django REST Framework](https://www.django-rest-framework.org/) { #django-rest-framework }
Django REST Framework был создан как гибкий набор инструментов для построения веб-API поверх Django, чтобы улучшить его возможности в части API.
///
-### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> { #flask }
+### [Flask](https://flask.palletsprojects.com) { #flask }
Flask — это «микрофреймворк», он не включает интеграции с базами данных и многие другие вещи, которые в Django идут «из коробки».
///
-### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> { #requests }
+### [Requests](https://requests.readthedocs.io) { #requests }
**FastAPI** на самом деле не альтернатива **Requests**. Их области применения очень различны.
///
-### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a> { #swagger-openapi }
+### [Swagger](https://swagger.io/) / [OpenAPI](https://github.com/OAI/OpenAPI-Specification/) { #swagger-openapi }
Главной возможностью, которую хотелось взять из Django REST Framework, была автоматическая документация API.
И интегрировать основанные на стандартах инструменты пользовательского интерфейса:
-* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>
-* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>
+* [Swagger UI](https://github.com/swagger-api/swagger-ui)
+* [ReDoc](https://github.com/Rebilly/ReDoc)
Эти два инструмента выбраны за популярность и стабильность, но даже при беглом поиске можно найти десятки альтернативных интерфейсов для OpenAPI (которые можно использовать с **FastAPI**).
Существует несколько REST-фреймворков для Flask, но, вложив время и усилия в исследование, я обнаружил, что многие из них прекращены или заброшены, с несколькими нерешёнными Issue (тикет\обращение), из-за которых они непригодны.
-### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
+### [Marshmallow](https://marshmallow.readthedocs.io/en/stable/) { #marshmallow }
Одна из основных возможностей, нужных системам API, — «<dfn title="также называемая маршаллингом, преобразованием">сериализация</dfn>» данных, то есть преобразование данных из кода (Python) во что-то, что можно отправить по сети. Например, преобразование объекта с данными из базы в JSON-объект. Преобразование объектов `datetime` в строки и т. п.
///
-### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
+### [Webargs](https://webargs.readthedocs.io/en/latest/) { #webargs }
Ещё одна важная возможность для API — <dfn title="чтение и преобразование в данные Python">парсинг</dfn> данных из входящих HTTP-запросов.
///
-### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a> { #apispec }
+### [APISpec](https://apispec.readthedocs.io/en/stable/) { #apispec }
Marshmallow и Webargs предоставляют валидацию, парсинг и сериализацию как плагины.
///
-### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a> { #flask-apispec }
+### [Flask-apispec](https://flask-apispec.readthedocs.io/en/latest/) { #flask-apispec }
Это плагин для Flask, который связывает Webargs, Marshmallow и APISpec.
Его использование привело к созданию нескольких full-stack генераторов на Flask. Это основные стеки, которые я (и несколько внешних команд) использовали до сих пор:
-* <a href="https://github.com/tiangolo/full-stack" class="external-link" target="_blank">https://github.com/tiangolo/full-stack</a>
-* <a href="https://github.com/tiangolo/full-stack-flask-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchbase</a>
-* <a href="https://github.com/tiangolo/full-stack-flask-couchdb" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchdb</a>
+* [https://github.com/tiangolo/full-stack](https://github.com/tiangolo/full-stack)
+* [https://github.com/tiangolo/full-stack-flask-couchbase](https://github.com/tiangolo/full-stack-flask-couchbase)
+* [https://github.com/tiangolo/full-stack-flask-couchdb](https://github.com/tiangolo/full-stack-flask-couchdb)
-И эти же full-stack генераторы стали основой для [Генераторов проектов **FastAPI**](project-generation.md){.internal-link target=_blank}.
+И эти же full-stack генераторы стали основой для [Генераторов проектов **FastAPI**](project-generation.md).
/// info | Информация
///
-### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (и <a href="https://angular.io/" class="external-link" target="_blank">Angular</a>) { #nestjs-and-angular }
+### [NestJS](https://nestjs.com/) (и [Angular](https://angular.io/)) { #nestjs-and-angular }
Это даже не Python. NestJS — это JavaScript/TypeScript-фреймворк на NodeJS, вдохновлённый Angular.
///
-### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a> { #sanic }
+### [Sanic](https://sanic.readthedocs.io/en/latest/) { #sanic }
Это был один из первых чрезвычайно быстрых Python-фреймворков на основе `asyncio`. Он был сделан очень похожим на Flask.
/// note | Технические детали
-Он использовал <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a> вместо стандартного цикла `asyncio` в Python. Это и сделало его таким быстрым.
+Он использовал [`uvloop`](https://github.com/MagicStack/uvloop) вместо стандартного цикла `asyncio` в Python. Это и сделало его таким быстрым.
Он явно вдохновил Uvicorn и Starlette, которые сейчас быстрее Sanic в открытых бенчмарках.
///
-### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> { #falcon }
+### [Falcon](https://falconframework.org/) { #falcon }
Falcon — ещё один высокопроизводительный Python-фреймворк, он минималистичен и служит основой для других фреймворков, таких как Hug.
///
-### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> { #molten }
+### [Molten](https://moltenframework.com/) { #molten }
Я обнаружил Molten на ранних этапах создания **FastAPI**. И у него были очень похожие идеи:
///
-### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a> { #hug }
+### [Hug](https://github.com/hugapi/hug) { #hug }
Hug был одним из первых фреймворков, реализовавших объявление типов параметров API с использованием аннотаций типов Python. Это была отличная идея, которая вдохновила и другие инструменты.
/// info | Информация
-Hug был создан Тимоти Кросли, тем же автором <a href="https://github.com/timothycrosley/isort" class="external-link" target="_blank">`isort`</a>, отличного инструмента для автоматической сортировки импортов в файлах Python.
+Hug был создан Тимоти Кросли, тем же автором [`isort`](https://github.com/timothycrosley/isort), отличного инструмента для автоматической сортировки импортов в файлах Python.
///
///
-### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0.5) { #apistar-0-5 }
+### [APIStar](https://github.com/encode/apistar) (<= 0.5) { #apistar-0-5 }
Прямо перед решением строить **FastAPI** я нашёл сервер **APIStar**. В нём было почти всё, что я искал, и отличный дизайн.
## Что используется в **FastAPI** { #used-by-fastapi }
-### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> { #pydantic }
+### [Pydantic](https://docs.pydantic.dev/) { #pydantic }
Pydantic — это библиотека для определения валидации данных, сериализации и документации (с использованием JSON Schema) на основе аннотаций типов Python.
///
-### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
+### [Starlette](https://www.starlette.dev/) { #starlette }
Starlette — это лёгкий <dfn title="Новый стандарт построения асинхронных веб-приложений на Python">ASGI</dfn> фреймворк/набор инструментов, идеально подходящий для создания высокопроизводительных asyncio‑сервисов.
///
-### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
+### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
Uvicorn — молниеносный ASGI-сервер, построенный на uvloop и httptools.
Также вы можете использовать опцию командной строки `--workers`, чтобы получить асинхронный многопроцессный сервер.
-Подробнее см. раздел [Развёртывание](deployment/index.md){.internal-link target=_blank}.
+Подробнее см. раздел [Развёртывание](deployment/index.md).
///
## Бенчмарки и скорость { #benchmarks-and-speed }
-Чтобы понять, сравнить и увидеть разницу между Uvicorn, Starlette и FastAPI, см. раздел о [Бенчмарках](benchmarks.md){.internal-link target=_blank}.
+Чтобы понять, сравнить и увидеть разницу между Uvicorn, Starlette и FastAPI, см. раздел о [Бенчмарках](benchmarks.md).
results = await some_library()
```
-Тогда обÑ\8aÑ\8fвлÑ\8fйÑ\82е *Ñ\84Ñ\83нкÑ\86ии-обÑ\80абоÑ\82Ñ\87ики пути* с `async def`, например:
+Тогда обÑ\8aÑ\8fвлÑ\8fйÑ\82е *Ñ\84Ñ\83нкÑ\86ии-обÑ\80абоÑ\82Ñ\87иков пути* с `async def`, например:
```Python hl_lines="2"
@app.get('/')
---
-Ð\95Ñ\81ли вÑ\8b иÑ\81полÑ\8cзÑ\83еÑ\82е Ñ\81Ñ\82оÑ\80оннÑ\8eÑ\8e библиоÑ\82екÑ\83, коÑ\82оÑ\80аÑ\8f взаимодейÑ\81Ñ\82вÑ\83еÑ\82 Ñ\81 Ñ\87ем-Ñ\82о (база даннÑ\8bÑ\85, API, Ñ\84айловаÑ\8f Ñ\81иÑ\81Ñ\82ема и Ñ\82.д.) и не поддеÑ\80живаеÑ\82 иÑ\81полÑ\8cзование `await` (Ñ\81ейÑ\87аÑ\81 Ñ\8dÑ\82о оÑ\82ноÑ\81иÑ\82Ñ\81Ñ\8f к болÑ\8cÑ\88инÑ\81Ñ\82вÑ\83 библиоÑ\82ек длÑ\8f Ð\91Ð\94), Ñ\82огда обÑ\8aÑ\8fвлÑ\8fйÑ\82е *Ñ\84Ñ\83нкÑ\86ии-обÑ\80абоÑ\82Ñ\87ики пути* как обычно, просто с `def`, например:
+Ð\95Ñ\81ли вÑ\8b иÑ\81полÑ\8cзÑ\83еÑ\82е Ñ\81Ñ\82оÑ\80оннÑ\8eÑ\8e библиоÑ\82екÑ\83, коÑ\82оÑ\80аÑ\8f взаимодейÑ\81Ñ\82вÑ\83еÑ\82 Ñ\81 Ñ\87ем-Ñ\82о (база даннÑ\8bÑ\85, API, Ñ\84айловаÑ\8f Ñ\81иÑ\81Ñ\82ема и Ñ\82.д.) и не поддеÑ\80живаеÑ\82 иÑ\81полÑ\8cзование `await` (Ñ\81ейÑ\87аÑ\81 Ñ\8dÑ\82о оÑ\82ноÑ\81иÑ\82Ñ\81Ñ\8f к болÑ\8cÑ\88инÑ\81Ñ\82вÑ\83 библиоÑ\82ек длÑ\8f Ð\91Ð\94), Ñ\82огда обÑ\8aÑ\8fвлÑ\8fйÑ\82е *Ñ\84Ñ\83нкÑ\86ии-обÑ\80абоÑ\82Ñ\87иков пути* как обычно, просто с `def`, например:
```Python hl_lines="2"
@app.get('/')
---
-**Ð\9fÑ\80имеÑ\87ание**: вÑ\8b можеÑ\82е Ñ\81меÑ\88иваÑ\82Ñ\8c `def` и `async def` в *Ñ\84Ñ\83нкÑ\86иÑ\8fÑ\85-обÑ\80абоÑ\82Ñ\87икаÑ\85 пути* столько, сколько нужно, и объявлять каждую так, как лучше для вашего случая. FastAPI сделает с ними всё как надо.
+**Ð\9fÑ\80имеÑ\87ание**: вÑ\8b можеÑ\82е Ñ\81меÑ\88иваÑ\82Ñ\8c `def` и `async def` в *Ñ\84Ñ\83нкÑ\86иÑ\8fÑ\85-обÑ\80абоÑ\82Ñ\87иков пути* столько, сколько нужно, и объявлять каждую так, как лучше для вашего случая. FastAPI сделает с ними всё как надо.
В любом из случаев выше FastAPI всё равно работает асинхронно и очень быстро.
/// info | Информация
-Прекрасные иллюстрации от <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
+Прекрасные иллюстрации от [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
///
/// info | Информация
-Прекрасные иллюстрации от <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
+Прекрасные иллюстрации от [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
///
Того же уровня производительности вы получаете с **FastAPI**.
-А так как можно одновременно использовать параллелизм и асинхронность, вы получаете производительность выше, чем у большинства протестированных фреймворков на NodeJS и на уровне Go, который — компилируемый язык, ближе к C <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(всё благодаря Starlette)</a>.
+А так как можно одновременно использовать параллелизм и асинхронность, вы получаете производительность выше, чем у большинства протестированных фреймворков на NodeJS и на уровне Go, который — компилируемый язык, ближе к C [(всё благодаря Starlette)](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1).
### Конкурентность лучше параллелизма? { #is-concurrency-better-than-parallelism }
Плюс к этому простой факт, что Python — основной язык для **Data Science**, Машинного обучения и особенно Глубокого обучения, делает FastAPI очень хорошим выбором для веб-API и приложений в области Data Science / Машинного обучения (среди многих других).
-Как добиться такого параллелизма в продакшн, см. раздел [Развёртывание](deployment/index.md){.internal-link target=_blank}.
+Как добиться такого параллелизма в продакшн, см. раздел [Развёртывание](deployment/index.md).
## `async` и `await` { #async-and-await }
### Пишите свой асинхронный код { #write-your-own-async-code }
-Starlette (и **FastAPI**) основаны на <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, что делает их совместимыми и со стандартной библиотекой Python <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a>, и с <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>.
+Starlette (и **FastAPI**) основаны на [AnyIO](https://anyio.readthedocs.io/en/stable/), что делает их совместимыми и со стандартной библиотекой Python [asyncio](https://docs.python.org/3/library/asyncio-task.html), и с [Trio](https://trio.readthedocs.io/en/stable/).
-В частности, вы можете напрямую использовать <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> для продвинутых сценариев конкурентности, где в вашем коде нужны более сложные паттерны.
+В частности, вы можете напрямую использовать [AnyIO](https://anyio.readthedocs.io/en/stable/) для продвинутых сценариев конкурентности, где в вашем коде нужны более сложные паттерны.
-И даже если вы не используете FastAPI, вы можете писать свои асинхронные приложения с <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, чтобы они были максимально совместимыми и получали его преимущества (например, *структурную конкурентность*).
+И даже если вы не используете FastAPI, вы можете писать свои асинхронные приложения с [AnyIO](https://anyio.readthedocs.io/en/stable/), чтобы они были максимально совместимыми и получали его преимущества (например, *структурную конкурентность*).
-Я создал ещё одну библиотеку поверх AnyIO, тонкий слой, чтобы немного улучшить аннотации типов и получить более качественное **автозавершение**, **ошибки прямо в редакторе** и т.д. Там также есть дружелюбное введение и руководство, чтобы помочь вам **понять** и писать **свой собственный асинхронный код**: <a href="https://asyncer.tiangolo.com/" class="external-link" target="_blank">Asyncer</a>. Она особенно полезна, если вам нужно **комбинировать асинхронный код с обычным** (блокирующим/синхронным) кодом.
+Я создал ещё одну библиотеку поверх AnyIO, тонкий слой, чтобы немного улучшить аннотации типов и получить более качественное **автозавершение**, **ошибки прямо в редакторе** и т.д. Там также есть дружелюбное введение и руководство, чтобы помочь вам **понять** и писать **свой собственный асинхронный код**: [Asyncer](https://asyncer.tiangolo.com/). Она особенно полезна, если вам нужно **комбинировать асинхронный код с обычным** (блокирующим/синхронным) кодом.
### Другие формы асинхронного кода { #other-forms-of-asynchronous-code }
До этого работа с асинхронным кодом была заметно сложнее и труднее для понимания.
-В предыдущих версиях Python можно было использовать потоки или <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a>. Но такой код гораздо сложнее понимать, отлаживать и держать в голове.
+В предыдущих версиях Python можно было использовать потоки или [Gevent](https://www.gevent.org/). Но такой код гораздо сложнее понимать, отлаживать и держать в голове.
В прежних версиях NodeJS/браузерного JavaScript вы бы использовали «callbacks» (обратные вызовы), что приводит к «callback hell» (ад обратных вызовов).
Если вы пришли из другого async-фреймворка, который работает иначе, и привыкли объявлять тривиальные *функции-обработчики пути*, выполняющие только вычисления, через простой `def` ради крошечной выгоды в производительности (около 100 наносекунд), обратите внимание: в **FastAPI** эффект будет противоположным. В таких случаях лучше использовать `async def`, если только ваши *функции-обработчики пути* не используют код, выполняющий блокирующий <abbr title="Input/Output - Ввод/вывод: чтение или запись на диск, сетевые соединения.">I/O</abbr>.
-Тем не менее, в обоих случаях велика вероятность, что **FastAPI** [всё равно будет быстрее](index.md#performance){.internal-link target=_blank} (или как минимум сопоставим) с вашим предыдущим фреймворком.
+Тем не менее, в обоих случаях велика вероятность, что **FastAPI** [всё равно будет быстрее](index.md#performance) (или как минимум сопоставим) с вашим предыдущим фреймворком.
### Зависимости { #dependencies }
-То же относится к [зависимостям](tutorial/dependencies/index.md){.internal-link target=_blank}. Если зависимость — это обычная функция `def`, а не `async def`, она запускается во внешнем пуле потоков.
+То же относится к [зависимостям](tutorial/dependencies/index.md). Если зависимость — это обычная функция `def`, а не `async def`, она запускается во внешнем пуле потоков.
### Подзависимости { #sub-dependencies }
-У вас может быть несколько зависимостей и [подзависимостей](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank}, которые требуют друг друга (в виде параметров определений функций): часть из них может быть объявлена с `async def`, а часть — обычным `def`. Всё будет работать, а те, что объявлены обычным `def`, будут вызываться во внешнем потоке (из пула), а не «ожидаться».
+У вас может быть несколько зависимостей и [подзависимостей](tutorial/dependencies/sub-dependencies.md), которые требуют друг друга (в виде параметров определений функций): часть из них может быть объявлена с `async def`, а часть — обычным `def`. Всё будет работать, а те, что объявлены обычным `def`, будут вызываться во внешнем потоке (из пула), а не «ожидаться».
### Другие служебные функции { #other-utility-functions }
# Бенчмарки (тесты производительности) { #benchmarks }
-Независимые бенчмарки TechEmpower показывают, что приложения **FastAPI** под управлением Uvicorn — <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">одни из самых быстрых Python‑фреймворков</a>, уступающие только Starlette и самому Uvicorn (используются внутри FastAPI).
+Независимые бенчмарки TechEmpower показывают, что приложения **FastAPI** под управлением Uvicorn — [одни из самых быстрых Python‑фреймворков](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), уступающие только Starlette и самому Uvicorn (используются внутри FastAPI).
Но при просмотре бенчмарков и сравнений следует иметь в виду следующее.
## FastAPI Cloud { #fastapi-cloud }
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, стоящими за **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** создан тем же автором и командой, стоящими за **FastAPI**.
Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API с минимальными усилиями.
## Облачные провайдеры — спонсоры { #cloud-providers-sponsors }
-Некоторые другие облачные провайдеры ✨ [**спонсируют FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ тоже. 🙇
+Некоторые другие облачные провайдеры ✨ [**спонсируют FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ тоже. 🙇
Возможно, вы захотите попробовать их сервисы и воспользоваться их руководствами:
-* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
-* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>
+* [Render](https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi)
+* [Railway](https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi)
## Безопасность — HTTPS { #security-https }
-В [предыдущей главе про HTTPS](https.md){.internal-link target=_blank} мы разобрались, как HTTPS обеспечивает шифрование для вашего API.
+В [предыдущей главе про HTTPS](https.md) мы разобрались, как HTTPS обеспечивает шифрование для вашего API.
Также мы увидели, что HTTPS обычно обеспечивает компонент, **внешний** по отношению к серверу вашего приложения — **прокси-сервер TSL-терминации**.
### Процессы‑воркеры и порты { #worker-processes-and-ports }
-Помните из раздела [Об HTTPS](https.md){.internal-link target=_blank}, что на сервере только один процесс может слушать конкретную комбинацию порта и IP‑адреса?
+Помните из раздела [Об HTTPS](https.md), что на сервере только один процесс может слушать конкретную комбинацию порта и IP‑адреса?
Это по‑прежнему так.
Не беспокойтесь, если некоторые пункты про **контейнеры**, Docker или Kubernetes пока кажутся неочевидными.
-Я расскажу больше про образы контейнеров, Docker, Kubernetes и т.п. в следующей главе: [FastAPI внутри контейнеров — Docker](docker.md){.internal-link target=_blank}.
+Я расскажу больше про образы контейнеров, Docker, Kubernetes и т.п. в следующей главе: [FastAPI внутри контейнеров — Docker](docker.md).
///
/// tip | Совет
-Я приведу более конкретные примеры с контейнерами в следующей главе: [FastAPI внутри контейнеров — Docker](docker.md){.internal-link target=_blank}.
+Я приведу более конкретные примеры с контейнерами в следующей главе: [FastAPI внутри контейнеров — Docker](docker.md).
///
# FastAPI в контейнерах — Docker { #fastapi-in-containers-docker }
-При развёртывании приложений FastAPI распространённый подход — собирать **образ контейнера на Linux**. Обычно это делают с помощью <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Затем такой образ контейнера можно развернуть несколькими способами.
+При развёртывании приложений FastAPI распространённый подход — собирать **образ контейнера на Linux**. Обычно это делают с помощью [**Docker**](https://www.docker.com/). Затем такой образ контейнера можно развернуть несколькими способами.
Использование Linux-контейнеров даёт ряд преимуществ: **безопасность**, **воспроизводимость**, **простоту** и другие.
Docker — один из основных инструментов для создания и управления **образами контейнеров** и **контейнерами**.
-Существует публичный <a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a> с готовыми **официальными образами** для многих инструментов, окружений, баз данных и приложений.
+Существует публичный [Docker Hub](https://hub.docker.com/) с готовыми **официальными образами** для многих инструментов, окружений, баз данных и приложений.
-Например, есть официальный <a href="https://hub.docker.com/_/python" class="external-link" target="_blank">образ Python</a>.
+Например, есть официальный [образ Python](https://hub.docker.com/_/python).
А также множество образов для разных вещей, например баз данных:
-* <a href="https://hub.docker.com/_/postgres" class="external-link" target="_blank">PostgreSQL</a>
-* <a href="https://hub.docker.com/_/mysql" class="external-link" target="_blank">MySQL</a>
-* <a href="https://hub.docker.com/_/mongo" class="external-link" target="_blank">MongoDB</a>
-* <a href="https://hub.docker.com/_/redis" class="external-link" target="_blank">Redis</a>, и т.д.
+* [PostgreSQL](https://hub.docker.com/_/postgres)
+* [MySQL](https://hub.docker.com/_/mysql)
+* [MongoDB](https://hub.docker.com/_/mongo)
+* [Redis](https://hub.docker.com/_/redis), и т.д.
Используя готовые образы, очень легко **комбинировать** разные инструменты и использовать их. Например, чтобы попробовать новую базу данных. В большинстве случаев можно воспользоваться **официальными образами** и просто настроить их через переменные окружения.
Чаще всего используется файл `requirements.txt` с именами пакетов и их версиями по одному на строку.
-Разумеется, вы будете придерживаться тех же идей, что описаны здесь: [О версиях FastAPI](versions.md){.internal-link target=_blank}, чтобы задать диапазоны версий.
+Разумеется, вы будете придерживаться тех же идей, что описаны здесь: [О версиях FastAPI](versions.md), чтобы задать диапазоны версий.
Например, ваш `requirements.txt` может выглядеть так:
#### Используйте `CMD` — exec-форма { #use-cmd-exec-form }
-Инструкцию Docker <a href="https://docs.docker.com/reference/dockerfile/#cmd" class="external-link" target="_blank">`CMD`</a> можно писать в двух формах:
+Инструкцию Docker [`CMD`](https://docs.docker.com/reference/dockerfile/#cmd) можно писать в двух формах:
✅ **Exec**-форма:
CMD fastapi run app/main.py --port 80
```
-Обязательно используйте **exec**-форму, чтобы FastAPI мог корректно завершаться и чтобы срабатывали [события lifespan](../advanced/events.md){.internal-link target=_blank}.
+Обязательно используйте **exec**-форму, чтобы FastAPI мог корректно завершаться и чтобы срабатывали [события lifespan](../advanced/events.md).
-Подробнее об этом читайте в <a href="https://docs.docker.com/reference/dockerfile/#shell-and-exec-form" class="external-link" target="_blank">документации Docker о shell- и exec-формах</a>.
+Подробнее об этом читайте в [документации Docker о shell- и exec-формах](https://docs.docker.com/reference/dockerfile/#shell-and-exec-form).
-Это особенно заметно при использовании `docker compose`. См. раздел FAQ Docker Compose с техническими подробностями: <a href="https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop" class="external-link" target="_blank">Почему мои сервисы пересоздаются или останавливаются 10 секунд?</a>.
+Это особенно заметно при использовании `docker compose`. См. раздел FAQ Docker Compose с техническими подробностями: [Почему мои сервисы пересоздаются или останавливаются 10 секунд?](https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop).
#### Структура директорий { #directory-structure }
## Проверка { #check-it }
-Проверьте работу по адресу вашего Docker-хоста, например: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> или <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (или аналогичный URL вашего Docker-хоста).
+Проверьте работу по адресу вашего Docker-хоста, например: [http://192.168.99.100/items/5?q=somequery](http://192.168.99.100/items/5?q=somequery) или [http://127.0.0.1/items/5?q=somequery](http://127.0.0.1/items/5?q=somequery) (или аналогичный URL вашего Docker-хоста).
Вы увидите что-то вроде:
## Интерактивная документация API { #interactive-api-docs }
-Теперь зайдите на <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> или <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (или аналогичный URL вашего Docker-хоста).
+Теперь зайдите на [http://192.168.99.100/docs](http://192.168.99.100/docs) или [http://127.0.0.1/docs](http://127.0.0.1/docs) (или аналогичный URL вашего Docker-хоста).
-Вы увидите автоматическую интерактивную документацию API (на базе <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
+Вы увидите автоматическую интерактивную документацию API (на базе [Swagger UI](https://github.com/swagger-api/swagger-ui)):

## Альтернативная документация API { #alternative-api-docs }
-Также можно открыть <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> или <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (или аналогичный URL вашего Docker-хоста).
+Также можно открыть [http://192.168.99.100/redoc](http://192.168.99.100/redoc) или [http://127.0.0.1/redoc](http://127.0.0.1/redoc) (или аналогичный URL вашего Docker-хоста).
-Вы увидите альтернативную автоматическую документацию (на базе <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
+Вы увидите альтернативную автоматическую документацию (на базе [ReDoc](https://github.com/Rebilly/ReDoc)):

## Концепции развертывания { #deployment-concepts }
-Ещё раз рассмотрим [концепции развертывания](concepts.md){.internal-link target=_blank} применительно к контейнерам.
+Ещё раз рассмотрим [концепции развертывания](concepts.md) применительно к контейнерам.
Контейнеры главным образом упрощают **сборку и развёртывание** приложения, но не навязывают конкретный подход к этим **концепциям развертывания**, и существует несколько стратегий.
Если мы рассматриваем только **образ контейнера** для приложения FastAPI (и далее запущенный **контейнер**), то HTTPS обычно обрабатывается **внешним** инструментом.
-Это может быть другой контейнер, например с <a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>, который берёт на себя **HTTPS** и **автоматическое** получение **сертификатов**.
+Это может быть другой контейнер, например с [Traefik](https://traefik.io/), который берёт на себя **HTTPS** и **автоматическое** получение **сертификатов**.
/// tip | Подсказка
/// info | Информация
-Если вы используете Kubernetes, это, вероятно, будет <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init Container</a>.
+Если вы используете Kubernetes, это, вероятно, будет [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).
///
### Базовый Docker-образ { #base-docker-image }
-Ранее существовал официальный Docker-образ FastAPI: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Сейчас он помечен как устаревший. ⛔️
+Ранее существовал официальный Docker-образ FastAPI: [tiangolo/uvicorn-gunicorn-fastapi](https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker). Сейчас он помечен как устаревший. ⛔️
Скорее всего, вам **не стоит** использовать этот базовый образ (или какой-либо аналогичный).
## Docker-образ с `uv` { #docker-image-with-uv }
-Если вы используете <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> для установки и управления проектом, следуйте их <a href="https://docs.astral.sh/uv/guides/integration/docker/" class="external-link" target="_blank">руководству по Docker для uv</a>.
+Если вы используете [uv](https://github.com/astral-sh/uv) для установки и управления проектом, следуйте их [руководству по Docker для uv](https://docs.astral.sh/uv/guides/integration/docker/).
## Резюме { #recap }
В большинстве случаев вы, вероятно, не захотите использовать какой-либо базовый образ, а вместо этого **соберёте образ контейнера с нуля** на основе официального Docker-образа Python.
-Заботясь о **порядке** инструкций в `Dockerfile`и используя **кэш Docker**, вы можете **минимизировать время сборки**, чтобы повысить продуктивность (и не скучать). 😎
+Заботясь о **порядке** инструкций в `Dockerfile` и используя **кэш Docker**, вы можете **минимизировать время сборки**, чтобы повысить продуктивность (и не скучать). 😎
# FastAPI Cloud { #fastapi-cloud }
-Вы можете развернуть своё приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> одной командой, присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
+Вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com) одной командой, присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
## Вход { #login }
## О FastAPI Cloud { #about-fastapi-cloud }
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, что и **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** создан тем же автором и командой, что и **FastAPI**.
Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API с минимальными усилиями.
///
-Чтобы **изучить основы HTTPS** с точки зрения пользователя, загляните на <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
+Чтобы **изучить основы HTTPS** с точки зрения пользователя, загляните на [https://howhttps.works/](https://howhttps.works/).
Теперь, со стороны **разработчика**, вот несколько вещей, которые стоит держать в голове, размышляя об HTTPS:
* **По умолчанию** это означает, что вы можете иметь **лишь один HTTPS-сертификат на один IP-адрес**.
* Неважно, насколько мощный у вас сервер или насколько маленькие приложения на нём работают.
* Однако у этого есть **решение**.
-* Есть **расширение** протокола **TLS** (того самого, что занимается шифрованием на уровне TCP, до HTTP) под названием **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication – Указание имени сервера">SNI</abbr></a>**.
+* Есть **расширение** протокола **TLS** (того самого, что занимается шифрованием на уровне TCP, до HTTP) под названием **[<abbr title="Server Name Indication - Указание имени сервера">SNI</abbr>](https://en.wikipedia.org/wiki/Server_Name_Indication)**.
* Это расширение SNI позволяет одному серверу (с **одним IP-адресом**) иметь **несколько HTTPS-сертификатов** и обслуживать **несколько HTTPS-доменов/приложений**.
* Чтобы это работало, **один** компонент (программа), запущенный на сервере и слушающий **публичный IP-адрес**, должен иметь **все HTTPS-сертификаты** на этом сервере.
* **После** установления защищённого соединения, протокол обмена данными — **всё ещё HTTP**.
* Содержимое **зашифровано**, несмотря на то, что оно отправляется по **протоколу HTTP**.
-Обычно на сервере (машине, хосте и т.п.) запускают **одну программу/HTTP‑сервер**, которая **управляет всей частью, связанной с HTTPS**: принимает **зашифрованные HTTPS-запросы**, отправляет **расшифрованные HTTP-запросы** в само HTTP‑приложение, работающее на том же сервере (в нашем случае это приложение **FastAPI**), получает **HTTP-ответ** от приложения, **шифрует его** с использованием подходящего **HTTPS‑сертификата** и отправляет клиенту по **HTTPS**. Такой сервер часто называют **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">прокси‑сервером TLS-терминации</a>**.
+Обычно на сервере (машине, хосте и т.п.) запускают **одну программу/HTTP‑сервер**, которая **управляет всей частью, связанной с HTTPS**: принимает **зашифрованные HTTPS-запросы**, отправляет **расшифрованные HTTP-запросы** в само HTTP‑приложение, работающее на том же сервере (в нашем случае это приложение **FastAPI**), получает **HTTP-ответ** от приложения, **шифрует его** с использованием подходящего **HTTPS‑сертификата** и отправляет клиенту по **HTTPS**. Такой сервер часто называют **[прокси‑сервером TLS-терминации](https://en.wikipedia.org/wiki/TLS_termination_proxy)**.
Некоторые варианты, которые вы можете использовать как прокси‑сервер TLS-терминации:
Процесс получения таких сертификатов был неудобным, требовал бумажной волокиты, а сами сертификаты были довольно дорогими.
-Затем появился **<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>**.
+Затем появился **[Let's Encrypt](https://letsencrypt.org/)**.
Это проект Linux Foundation. Он предоставляет **HTTPS‑сертификаты бесплатно**, в автоматическом режиме. Эти сертификаты используют стандартные криптографические механизмы и имеют короткий срок действия (около 3 месяцев), поэтому **безопасность фактически выше** благодаря уменьшенному сроку жизни.
Заголовки прокси:
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
-* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
+* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
+* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
+* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
///
/// tip | Совет
-Подробнее об этом вы можете узнать в документации: [За прокси — Включить пересылаемые заголовки прокси](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
+Подробнее об этом вы можете узнать в документации: [За прокси — Включить пересылаемые заголовки прокси](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers)
///
Вы можете **развернуть сервер** самостоятельно, используя различные инструменты. Например, можно использовать **облачный сервис**, который выполнит часть работы за вас. Также возможны и другие варианты.
-Например, мы, команда, стоящая за FastAPI, создали <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>, чтобы сделать развёртывание приложений FastAPI в облаке как можно более простым и прямолинейным, с тем же удобством для разработчика, что и при работе с FastAPI.
+Например, мы, команда, стоящая за FastAPI, создали [**FastAPI Cloud**](https://fastapicloud.com), чтобы сделать развёртывание приложений FastAPI в облаке как можно более простым и прямолинейным, с тем же удобством для разработчика, что и при работе с FastAPI.
Я покажу вам некоторые из основных концепций, которые вы, вероятно, должны иметь в виду при развертывании приложения **FastAPI** (хотя большинство из них применимо к любому другому типу веб-приложений).
Есть несколько альтернатив, например:
-* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>: высокопроизводительный ASGI‑сервер.
-* <a href="https://hypercorn.readthedocs.io/" class="external-link" target="_blank">Hypercorn</a>: ASGI‑сервер, среди прочего совместимый с HTTP/2 и Trio.
-* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>: ASGI‑сервер, созданный для Django Channels.
-* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>: HTTP‑сервер на Rust для Python‑приложений.
-* <a href="https://unit.nginx.org/howto/fastapi/" class="external-link" target="_blank">NGINX Unit</a>: NGINX Unit — лёгкая и многофункциональная среда выполнения веб‑приложений.
+* [Uvicorn](https://www.uvicorn.dev/): высокопроизводительный ASGI‑сервер.
+* [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 }
Но вы также можете установить ASGI‑сервер вручную.
-Создайте [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активируйте его и затем установите серверное приложение.
+Создайте [виртуальное окружение](../virtual-environments.md), активируйте его и затем установите серверное приложение.
Например, чтобы установить Uvicorn:
При деплое приложения вам, скорее всего, захочется использовать **репликацию процессов**, чтобы задействовать **несколько ядер** и иметь возможность обрабатывать больше запросов.
-Как вы видели в предыдущей главе о [Концепциях деплоя](concepts.md){.internal-link target=_blank}, существует несколько стратегий.
+Как вы видели в предыдущей главе о [Концепциях деплоя](concepts.md), существует несколько стратегий.
Здесь я покажу, как использовать **Uvicorn** с **воркер-процессами** через команду `fastapi` или напрямую через команду `uvicorn`.
/// info | Информация
-Если вы используете контейнеры, например Docker или Kubernetes, я расскажу об этом подробнее в следующей главе: [FastAPI в контейнерах — Docker](docker.md){.internal-link target=_blank}.
+Если вы используете контейнеры, например Docker или Kubernetes, я расскажу об этом подробнее в следующей главе: [FastAPI в контейнерах — Docker](docker.md).
В частности, при запуске в **Kubernetes** вам, скорее всего, **не** понадобится использовать воркеры — вместо этого запускайте **один процесс Uvicorn на контейнер**, но об этом подробнее далее в той главе.
## Контейнеры и Docker { #containers-and-docker }
-В следующей главе о [FastAPI в контейнерах — Docker](docker.md){.internal-link target=_blank} я объясню стратегии, которые можно использовать для решения остальных **концепций деплоя**.
+В следующей главе о [FastAPI в контейнерах — Docker](docker.md) я объясню стратегии, которые можно использовать для решения остальных **концепций деплоя**.
Я покажу, как **собрать свой образ с нуля**, чтобы запускать один процесс Uvicorn. Это простой подход и, вероятно, именно то, что вам нужно при использовании распределённой системы управления контейнерами, такой как **Kubernetes**.
Часто добавляются новые функции, регулярно исправляются баги, код продолжает постоянно совершенствоваться.
-По указанным причинам текущие версии до сих пор `0.x.x`. Это говорит о том, что каждая версия может содержать обратно несовместимые изменения, следуя <a href="https://semver.org/" class="external-link" target="_blank">Семантическому версионированию</a>.
+По указанным причинам текущие версии до сих пор `0.x.x`. Это говорит о том, что каждая версия может содержать обратно несовместимые изменения, следуя [Семантическому версионированию](https://semver.org/).
Уже сейчас вы можете создавать приложения в продакшн, используя **FastAPI** (и скорее всего так и делаете), главное убедиться в том, что вы используете версию, которая корректно работает с вашим кодом.
## Доступные версии { #available-versions }
-Вы можете посмотреть доступные версии (например, проверить последнюю на данный момент) в [Примечаниях к выпуску](../release-notes.md){.internal-link target=_blank}.
+Вы можете посмотреть доступные версии (например, проверить последнюю на данный момент) в [Примечаниях к выпуску](../release-notes.md).
## О версиях { #about-versions }
Вам следует добавить тесты для вашего приложения.
-С помощью **FastAPI** это очень просто (благодаря Starlette), см. документацию: [Тестирование](../tutorial/testing.md){.internal-link target=_blank}
+С помощью **FastAPI** это очень просто (благодаря Starlette), см. документацию: [Тестирование](../tutorial/testing.md)
После создания тестов вы можете обновить свою версию **FastAPI** до более новой. После этого следует убедиться, что ваш код работает корректно, запустив тесты.
--- /dev/null
+# Поддержка редактора кода { #editor-support }
+
+Официальное [расширение FastAPI](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) улучшает ваш процесс разработки на FastAPI за счет обнаружения и навигации по *операциям пути* (обработчикам пути), а также развертывания в FastAPI Cloud и потоковой передачи логов в реальном времени.
+
+Подробности о расширении смотрите в README в [репозитории GitHub](https://github.com/fastapi/fastapi-vscode).
+
+## Установка и настройка { #setup-and-installation }
+
+**Расширение FastAPI** доступно как для [VS Code](https://code.visualstudio.com/), так и для [Cursor](https://www.cursor.com/). Его можно установить напрямую из панели расширений в каждом редакторе кода, выполнив поиск по «FastAPI» и выбрав расширение от **FastAPI Labs**. Расширение также работает в браузерных редакторах кода, таких как [vscode.dev](https://vscode.dev) и [github.dev](https://github.dev).
+
+### Обнаружение приложения { #application-discovery }
+
+По умолчанию расширение автоматически обнаруживает приложения FastAPI в вашем рабочем пространстве, сканируя файлы, где создается экземпляр `FastAPI()`. Если авто-обнаружение не подходит для структуры вашего проекта, вы можете указать точку входа через `[tool.fastapi]` в `pyproject.toml` или настройку VS Code `fastapi.entryPoint`, используя модульную нотацию (например, `myapp.main:app`).
+
+## Возможности { #features }
+
+- **Обозреватель операций пути** — древовидное представление на боковой панели всех <dfn title="маршруты, конечные точки">*операций пути*</dfn> вашего приложения. Нажмите, чтобы перейти к любому маршруту или определению роутера.
+- **Поиск маршрутов** — поиск по пути, методу или имени с помощью <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd> (на macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>E</kbd>).
+- **Навигация CodeLens** — кликабельные ссылки над вызовами тестового клиента (например, `client.get('/items')`), которые переходят к соответствующей *операции пути* для быстрой навигации между тестами и реализацией.
+- **Развернуть в FastAPI Cloud** — развертывание вашего приложения в один клик в [FastAPI Cloud](https://fastapicloud.com/).
+- **Поток логов приложения** — потоковая передача логов в реальном времени из вашего приложения, развернутого в FastAPI Cloud, с фильтрацией по уровню и текстовым поиском.
+
+Если вы хотите поверхностно ознакомиться с возможностями расширения, откройте палитру команд (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> или на macOS: <kbd>Cmd</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>), выберите «Welcome: Open walkthrough...», а затем «Get started with FastAPI».
/// tip | Совет
-Второй аргумент <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> - это возвращаемое по умолчанию значение.
+Второй аргумент [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) - это возвращаемое по умолчанию значение.
Если значение не указано, то по умолчанию оно равно `None`. В данном случае мы указываем `«World»` в качестве значения по умолчанию.
/// tip | Совет
-Подробнее об этом можно прочитать на сайте <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>.
+Подробнее об этом можно прочитать на сайте [The Twelve-Factor App: Config](https://12factor.net/config).
///
Это означает, что **любое значение**, считанное в Python из переменной окружения, **будет `str`**, и любое преобразование к другому типу или любая валидация должны быть выполнены в коде.
-Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md){.internal-link target=_blank}.
+Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md).
## Переменная окружения `PATH` { #path-environment-variable }
////
-Эта информация будет полезна при изучении [Виртуальных окружений](virtual-environments.md){.internal-link target=_blank}.
+Эта информация будет полезна при изучении [Виртуальных окружений](virtual-environments.md).
## Вывод { #conclusion }
Благодаря этому вы должны иметь базовое представление о том, что такое **переменные окружения** и как использовать их в Python.
-Подробнее о них вы также можете прочитать в <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">статье о переменных окружения на википедии</a>.
+Подробнее о них вы также можете прочитать в [статье о переменных окружения на википедии](https://en.wikipedia.org/wiki/Environment_variable).
Во многих случаях не всегда очевидно, как переменные окружения могут быть полезны и применимы. Но они постоянно появляются в различных сценариях разработки, поэтому знать о них полезно.
# FastAPI CLI { #fastapi-cli }
-**FastAPI CLI** это программа командной строки, которую вы можете использовать для запуска вашего FastAPI приложения, для управления FastAPI-проектом, а также для многих других вещей.
+**FastAPI <abbr title="command line interface - интерфейс командной строки">CLI</abbr>** - это программа командной строки, которую вы можете использовать, чтобы предоставлять доступ к вашему приложению FastAPI, управлять проектом FastAPI и т.д.
-`fastapi-cli` устанавливается вместе со стандартным пакетом FastAPI (при запуске команды `pip install "fastapi[standard]"`). Данный пакет предоставляет доступ к программе `fastapi` через терминал.
+При установке FastAPI (например, с помощью `pip install "fastapi[standard]"`) вместе с ним устанавливается программа командной строки, которую можно запускать в терминале.
-ЧÑ\82обÑ\8b запÑ\83Ñ\81Ñ\82иÑ\82Ñ\8c пÑ\80иложение FastAPI в Ñ\80ежиме Ñ\80азÑ\80абоÑ\82ки, вÑ\8b можеÑ\82е иÑ\81полÑ\8cзоваÑ\82Ñ\8c команду `fastapi dev`:
+ЧÑ\82обÑ\8b запÑ\83Ñ\81Ñ\82иÑ\82Ñ\8c ваÑ\88е пÑ\80иложение FastAPI в Ñ\80ежиме Ñ\80азÑ\80абоÑ\82ки, иÑ\81полÑ\8cзÑ\83йÑ\82е команду `fastapi dev`:
<div class="termy">
```console
-$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+$ <font color="#4E9A06">fastapi</font> dev
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
</div>
-Приложение командной строки `fastapi` это и есть **FastAPI CLI**.
+/// tip | Подсказка
+
+В продакшн вы будете использовать `fastapi run` вместо `fastapi dev`. 🚀
+
+///
+
+Внутри **FastAPI CLI** используется [Uvicorn](https://www.uvicorn.dev), высокопроизводительный, готовый к работе в продакшн ASGI-сервер. 😎
+
+Инструмент командной строки `fastapi` попытается автоматически обнаружить приложение FastAPI для запуска, предполагая, что это объект с именем `app` в файле `main.py` (или в некоторых других вариантах).
+
+Но вы можете явно указать, какое приложение использовать.
+
+## Настройте `entrypoint` приложения в `pyproject.toml` { #configure-the-app-entrypoint-in-pyproject-toml }
+
+Вы можете настроить, где находится ваше приложение, в файле `pyproject.toml`, например так:
+
+```toml
+[tool.fastapi]
+entrypoint = "main:app"
+```
+
+Этот `entrypoint` сообщит команде `fastapi`, что приложение нужно импортировать так:
+
+```python
+from main import app
+```
-FastAPI CLI берет путь к вашей Python-программе (напр. `main.py`) и автоматически находит объект `FastAPI` (обычно это `app`), затем определяет правильный процесс импорта и запускает сервер приложения.
+Если ваш код организован так:
+
+```
+.
+├── backend
+│ ├── main.py
+│ ├── __init__.py
+```
+
+Тогда следует указать `entrypoint` так:
+
+```toml
+[tool.fastapi]
+entrypoint = "backend.main:app"
+```
+
+что будет эквивалентно:
+
+```python
+from backend.main import app
+```
+
+### `fastapi dev` с указанием пути { #fastapi-dev-with-path }
+
+Вы также можете передать путь к файлу команде `fastapi dev`, и она постарается определить объект приложения FastAPI:
+
+```console
+$ fastapi dev main.py
+```
-Ð\94лÑ\8f Ñ\80абоÑ\82Ñ\8b в Ñ\80ежиме пÑ\80одакÑ\88н вмеÑ\81Ñ\82о `fastapi dev` нÑ\83жно иÑ\81полÑ\8cзоваÑ\82Ñ\8c `fastapi run`. ð\9f\9a\80
+Ð\9dо Ñ\82огда вам пÑ\80идеÑ\82Ñ\81Ñ\8f каждÑ\8bй Ñ\80аз не забÑ\8bваÑ\82Ñ\8c пеÑ\80едаваÑ\82Ñ\8c пÑ\80авилÑ\8cнÑ\8bй пÑ\83Ñ\82Ñ\8c пÑ\80и вÑ\8bзове командÑ\8b `fastapi`.
-Ð\92нÑ\83Ñ\82Ñ\80и **FastAPI CLI** иÑ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>, вÑ\8bÑ\81окопÑ\80оизводиÑ\82елÑ\8cнÑ\8bй, гоÑ\82овÑ\8bй к Ñ\80абоÑ\82е в пÑ\80одакÑ\88н ASGI-Ñ\81еÑ\80веÑ\80. ð\9f\98\8e
+Ð\9aÑ\80оме Ñ\82ого, дÑ\80Ñ\83гие инÑ\81Ñ\82Ñ\80Ñ\83менÑ\82Ñ\8b могÑ\83Ñ\82 не найÑ\82и его, напÑ\80имеÑ\80 [РаÑ\81Ñ\88иÑ\80ение VS Code](editor-support.md) или [FastAPI Cloud](https://fastapicloud.com), поÑ\8dÑ\82омÑ\83 Ñ\80екомендÑ\83еÑ\82Ñ\81Ñ\8f иÑ\81полÑ\8cзоваÑ\82Ñ\8c `entrypoint` в `pyproject.toml`.
## `fastapi dev` { #fastapi-dev }
/// tip | Подсказка
-Вы можете больше узнать об этом в [документации по развертыванию](deployment/index.md){.internal-link target=_blank}.
+Вы можете больше узнать об этом в [документации по развертыванию](deployment/index.md).
///
### Основано на открытых стандартах { #based-on-open-standards }
-* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> для создания API, включая объявления <dfn title="также известны как HTTP-методы, например: POST, GET, PUT, DELETE">операций</dfn> <dfn title="также известен как: эндпоинты, маршруты">пути</dfn>, параметров, тел запросов, безопасности и т.д.
-* Автоматическая документация моделей данных с помощью <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (так как сама спецификация OpenAPI основана на JSON Schema).
+* [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) для создания API, включая объявления <dfn title="также известны как HTTP-методы, например: POST, GET, PUT, DELETE">операций</dfn> <dfn title="также известен как: эндпоинты, маршруты">пути</dfn>, параметров, тел запросов, безопасности и т.д.
+* Автоматическая документация моделей данных с помощью [**JSON Schema**](https://json-schema.org/) (так как сама спецификация OpenAPI основана на JSON Schema).
* Разработан вокруг этих стандартов, после тщательного их изучения. Это не дополнительная надстройка поверх.
* Это также позволяет использовать автоматическую **генерацию клиентского кода** на многих языках.
Интерактивная документация для API и исследовательские веб-интерфейсы. Поскольку фреймворк основан на OpenAPI, существует несколько вариантов документирования, 2 из них включены по умолчанию.
-* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, с интерактивным исследованием, вызовом и тестированием вашего API прямо из браузера.
+* [**Swagger UI**](https://github.com/swagger-api/swagger-ui), с интерактивным исследованием, вызовом и тестированием вашего API прямо из браузера.

-* Альтернативная документация API в <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
+* Альтернативная документация API в [**ReDoc**](https://github.com/Rebilly/ReDoc).

Все основано на стандартных **аннотациях типов Python** (благодаря Pydantic). Не нужно изучать новый синтаксис. Только стандартный современный Python.
-Если вам нужно освежить знания о типах в Python (даже если вы не используете FastAPI), выделите 2 минуты и просмотрите краткое руководство: [Типы Python](python-types.md){.internal-link target=_blank}.
+Если вам нужно освежить знания о типах в Python (даже если вы не используете FastAPI), выделите 2 минуты и просмотрите краткое руководство: [Типы Python](python-types.md).
Вы пишете стандартный Python с типами:
Весь фреймворк был продуман так, чтобы быть простым и интуитивно понятным в использовании, все решения были проверены на множестве редакторов еще до начала разработки, чтобы обеспечить наилучшие условия при написании кода.
-В опросах Python‑разработчиков видно, <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">что одной из самых часто используемых функций является «автозавершение»</a>.
+В опросах Python‑разработчиков видно, [что одной из самых часто используемых функций является «автозавершение»](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features).
Вся структура **FastAPI** основана на удовлетворении этой возможности. Автозавершение работает везде.
Вот как ваш редактор может вам помочь:
-* в <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
+* в [Visual Studio Code](https://code.visualstudio.com/):

-* в <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
+* в [PyCharm](https://www.jetbrains.com/pycharm/):

Все схемы безопасности, определённые в OpenAPI, включая:
* HTTP Basic.
-* **OAuth2** (также с **токенами JWT**). Ознакомьтесь с руководством [OAuth2 с JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
+* **OAuth2** (также с **токенами JWT**). Ознакомьтесь с руководством [OAuth2 с JWT](tutorial/security/oauth2-jwt.md).
* Ключи API в:
* HTTP-заголовках.
* Параметрах запросов.
## Возможности Starlette { #starlette-features }
-**FastAPI** основан на <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a> и полностью совместим с ним. Так что любой дополнительный код Starlette, который у вас есть, также будет работать.
+**FastAPI** основан на [**Starlette**](https://www.starlette.dev/) и полностью совместим с ним. Так что любой дополнительный код Starlette, который у вас есть, также будет работать.
На самом деле, `FastAPI` — это подкласс `Starlette`. Таким образом, если вы уже знаете или используете Starlette, большая часть функционала будет работать так же.
С **FastAPI** вы получаете все возможности **Starlette** (так как FastAPI — это всего лишь Starlette на стероидах):
-* Серьёзно впечатляющая производительность. Это <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">один из самых быстрых фреймворков на Python, наравне с **NodeJS** и **Go**</a>.
+* Серьёзно впечатляющая производительность. Это [один из самых быстрых фреймворков на Python, наравне с **NodeJS** и **Go**](https://github.com/encode/starlette#performance).
* Поддержка **WebSocket**.
* Фоновые задачи в том же процессе.
* События запуска и выключения.
## Возможности Pydantic { #pydantic-features }
-**FastAPI** полностью совместим с (и основан на) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Поэтому любой дополнительный код Pydantic, который у вас есть, также будет работать.
+**FastAPI** полностью совместим с (и основан на) [**Pydantic**](https://docs.pydantic.dev/). Поэтому любой дополнительный код Pydantic, который у вас есть, также будет работать.
Включая внешние библиотеки, также основанные на Pydantic, такие как <abbr title="Object-Relational Mapper - объектно-реляционный маппер">ORM</abbr>’ы, <abbr title="Object-Document Mapper - объектно-документный маппер">ODM</abbr>’ы для баз данных.
## Подписаться на новостную рассылку { #subscribe-to-the-newsletter }
-Вы можете подписаться на редкую [новостную рассылку **FastAPI и его друзья**](newsletter.md){.internal-link target=_blank} и быть в курсе о:
+Вы можете подписаться на редкую [новостную рассылку **FastAPI и его друзья**](newsletter.md) и быть в курсе о:
* Новостях о FastAPI и его друзьях 🚀
* Руководствах 📝
## Подписаться на FastAPI в X (Twitter) { #follow-fastapi-on-x-twitter }
-<a href="https://x.com/fastapi" class="external-link" target="_blank">Подписаться на @fastapi в **X (Twitter)**</a> для получения наисвежайших новостей о **FastAPI**. 🐦
+[Подписаться на @fastapi в **X (Twitter)**](https://x.com/fastapi) для получения наисвежайших новостей о **FastAPI**. 🐦
## Добавить **FastAPI** звезду на GitHub { #star-fastapi-in-github }
-Вы можете добавить FastAPI "звезду" на GitHub (кликнув на кнопку звезды в правом верхнем углу): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. ⭐️
+Вы можете добавить FastAPI "звезду" на GitHub (кликнув на кнопку звезды в правом верхнем углу): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). ⭐️
Чем больше звёзд, тем легче другим пользователям найти проект и увидеть, что он уже оказался полезным для многих.
## Отслеживать свежие выпуски в репозитории на GitHub { #watch-the-github-repository-for-releases }
-Вы можете "отслеживать" FastAPI на GitHub (кликнув по кнопке "watch" наверху справа): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
+Вы можете "отслеживать" FastAPI на GitHub (кликнув по кнопке "watch" наверху справа): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). 👀
Там же Вы можете выбрать "Releases only".
## Связаться с автором { #connect-with-the-author }
-Можно связаться со <a href="https://tiangolo.com" class="external-link" target="_blank">мной (Sebastián Ramírez / `tiangolo`)</a>, автором.
+Можно связаться со [мной (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com), автором.
Вы можете:
-* <a href="https://github.com/tiangolo" class="external-link" target="_blank">Подписаться на меня на **GitHub**</a>.
+* [Подписаться на меня на **GitHub**](https://github.com/tiangolo).
* Посмотреть другие мои проекты с открытым кодом, которые могут быть полезны Вам.
* Подписаться, чтобы видеть, когда я создаю новый проект с открытым кодом.
-* <a href="https://x.com/tiangolo" class="external-link" target="_blank">Подписаться на меня в **X (Twitter)**</a> или в <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>.
+* [Подписаться на меня в **X (Twitter)**](https://x.com/tiangolo) или в [Mastodon](https://fosstodon.org/@tiangolo).
* Поделиться со мной, как Вы используете FastAPI (я обожаю это читать).
* Узнавать, когда я делаю объявления или выпускаю новые инструменты.
- * Вы также можете <a href="https://x.com/fastapi" class="external-link" target="_blank">подписаться на @fastapi в X (Twitter)</a> (это отдельный аккаунт).
-* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Подписаться на меня в **LinkedIn**</a>.
+ * Вы также можете [подписаться на @fastapi в X (Twitter)](https://x.com/fastapi) (это отдельный аккаунт).
+* [Подписаться на меня в **LinkedIn**](https://www.linkedin.com/in/tiangolo/).
* Узнавать, когда я делаю объявления или выпускаю новые инструменты (хотя чаще я использую X (Twitter) 🤷♂).
-* Читать, что я пишу (или подписаться на меня) на <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> или <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
+* Читать, что я пишу (или подписаться на меня) на [**Dev.to**](https://dev.to/tiangolo) или [**Medium**](https://medium.com/@tiangolo).
* Читать другие идеи, статьи и о созданных мной инструментах.
* Подписаться, чтобы читать, когда я публикую что-то новое.
## Оставить сообщение в X (Twitter) о **FastAPI** { #tweet-about-fastapi }
-<a href="https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">Оставьте сообщение в X (Twitter) о **FastAPI**</a> и позвольте мне и другим узнать, почему он Вам нравится. 🎉
+[Оставьте сообщение в X (Twitter) о **FastAPI**](https://x.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi) и позвольте мне и другим узнать, почему он Вам нравится. 🎉
Я люблю узнавать о том, как **FastAPI** используется, что Вам понравилось в нём, в каких проектах/компаниях Вы его используете и т.д.
## Оставить голос за FastAPI { #vote-for-fastapi }
-* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Голосуйте за **FastAPI** в Slant</a>.
-* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">Голосуйте за **FastAPI** в AlternativeTo</a>.
-* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">Расскажите, что Вы используете **FastAPI** на StackShare</a>.
+* [Голосуйте за **FastAPI** в Slant](https://www.slant.co/options/34241/~fastapi-review).
+* [Голосуйте за **FastAPI** в AlternativeTo](https://alternativeto.net/software/fastapi/about/).
+* [Расскажите, что Вы используете **FastAPI** на StackShare](https://stackshare.io/pypi-fastapi).
## Помочь другим с вопросами на GitHub { #help-others-with-questions-in-github }
Вы можете попробовать помочь другим с их вопросами в:
-* <a href="https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
-* <a href="https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
+* [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered)
+* [GitHub Issues](https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+)
Во многих случаях Вы уже можете знать ответы на эти вопросы. 🤓
-Если Вы много помогаете людям с их вопросами, Вы станете официальным [Экспертом FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}. 🎉
+Если Вы много помогаете людям с их вопросами, Вы станете официальным [Экспертом FastAPI](fastapi-people.md#fastapi-experts). 🎉
Только помните, самое важное — постарайтесь быть добрыми. Люди приходят со своими разочарованиями и часто задают вопросы не лучшим образом, но постарайтесь, насколько можете, быть доброжелательными. 🤗
Во многих случаях предоставляют только фрагмент кода, но этого недостаточно, чтобы **воспроизвести проблему**.
-* Попросите предоставить <a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">минимальный воспроизводимый пример</a>, который Вы сможете **скопировать-вставить** и запустить локально, чтобы увидеть ту же ошибку или поведение, или лучше понять их кейс.
+* Попросите предоставить [минимальный воспроизводимый пример](https://stackoverflow.com/help/minimal-reproducible-example), который Вы сможете **скопировать-вставить** и запустить локально, чтобы увидеть ту же ошибку или поведение, или лучше понять их кейс.
* Если чувствуете себя особенно великодушными, можете попытаться **создать такой пример** сами, основываясь только на описании проблемы. Просто помните, что это может занять много времени, и, возможно, сначала лучше попросить уточнить проблему.
## Отслеживать репозиторий на GitHub { #watch-the-github-repository }
-Вы можете "отслеживать" FastAPI на GitHub (кликнув по кнопке "watch" наверху справа): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
+Вы можете "отслеживать" FastAPI на GitHub (кликнув по кнопке "watch" наверху справа): [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi). 👀
Если Вы выберете "Watching" вместо "Releases only", то будете получать уведомления, когда кто-либо создаёт новый вопрос или Issue. Вы также можете указать, что хотите получать уведомления только о новых Issues, или обсуждениях, или пулл-реквестах и т.д.
## Задать вопросы { #ask-questions }
-Вы можете <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">создать новый вопрос</a> в репозитории GitHub, например:
+Вы можете [создать новый вопрос](https://github.com/fastapi/fastapi/discussions/new?category=questions) в репозитории GitHub, например:
* Задать **вопрос** или спросить о **проблеме**.
* Предложить новую **возможность**.
## Создать пулл-реквест { #create-a-pull-request }
-Вы можете [сделать вклад](contributing.md){.internal-link target=_blank} в исходный код пулл-реквестами, например:
+Вы можете [сделать вклад](contributing.md) в исходный код пулл-реквестами, например:
* Исправить опечатку, найденную в документации.
-* Поделиться статьёй, видео или подкастом о FastAPI, которые Вы создали или нашли, <a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">изменив этот файл</a>.
+* Поделиться статьёй, видео или подкастом о FastAPI, которые Вы создали или нашли, [изменив этот файл](https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml).
* Убедитесь, что добавили свою ссылку в начало соответствующего раздела.
-* Помочь с [переводом документации](contributing.md#translations){.internal-link target=_blank} на Ваш язык.
+* Помочь с [переводом документации](contributing.md#translations) на Ваш язык.
* Вы также можете проверять переводы, сделанные другими.
* Предложить новые разделы документации.
* Исправить существующую проблему/баг.
Основные задачи, которые Вы можете выполнить прямо сейчас:
-* [Помочь другим с вопросами на GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (смотрите секцию выше).
-* [Проверять пулл-реквесты](#review-pull-requests){.internal-link target=_blank} (смотрите секцию выше).
+* [Помочь другим с вопросами на GitHub](#help-others-with-questions-in-github) (смотрите секцию выше).
+* [Проверять пулл-реквесты](#review-pull-requests) (смотрите секцию выше).
Именно эти две задачи **забирают больше всего времени**. Это основная работа по поддержке FastAPI.
## Подключиться к чату { #join-the-chat }
-Подключайтесь к 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">серверу чата в Discord</a> 👥 и общайтесь с другими участниками сообщества FastAPI.
+Подключайтесь к 👥 [серверу чата в Discord](https://discord.gg/VQjSZaeJmf) 👥 и общайтесь с другими участниками сообщества FastAPI.
/// tip | Подсказка
-По вопросам — задавайте их в <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a>, так гораздо выше шанс, что Вы получите помощь от [Экспертов FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}.
+По вопросам — задавайте их в [GitHub Discussions](https://github.com/fastapi/fastapi/discussions/new?category=questions), так гораздо выше шанс, что Вы получите помощь от [Экспертов FastAPI](fastapi-people.md#fastapi-experts).
Используйте чат только для прочих общих бесед.
На GitHub шаблон поможет Вам правильно сформулировать вопрос, чтобы Вам было легче получить хороший ответ или даже решить проблему самостоятельно ещё до того, как спросите. И на GitHub я могу следить за тем, чтобы всегда отвечать на всё, даже если это занимает время. А с чатами я не могу сделать этого лично. 😅
-Кроме того, переписка в чатах хуже ищется, чем на GitHub, поэтому вопросы и ответы могут теряться среди остальных сообщений. И только те, что на GitHub, учитываются для получения лычки [Эксперт FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}, так что вероятнее всего Вы получите больше внимания именно на GitHub.
+Кроме того, переписка в чатах хуже ищется, чем на GitHub, поэтому вопросы и ответы могут теряться среди остальных сообщений. И только те, что на GitHub, учитываются для получения лычки [Эксперт FastAPI](fastapi-people.md#fastapi-experts), так что вероятнее всего Вы получите больше внимания именно на GitHub.
С другой стороны, в чатах тысячи пользователей, так что почти всегда есть шанс найти там кого-то для разговора. 😄
## Спонсировать автора { #sponsor-the-author }
-Если Ваш **продукт/компания** зависят от **FastAPI** или связаны с ним и Вы хотите донести до пользователей информацию о себе, Вы можете спонсировать автора (меня) через <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>. В зависимости от уровня поддержки Вы можете получить дополнительные бонусы, например, бейдж в документации. 🎁
+Если Ваш **продукт/компания** зависят от **FastAPI** или связаны с ним и Вы хотите донести до пользователей информацию о себе, Вы можете спонсировать автора (меня) через [GitHub Sponsors](https://github.com/sponsors/tiangolo). В зависимости от уровня поддержки Вы можете получить дополнительные бонусы, например, бейдж в документации. 🎁
---
# История, проектирование и будущее { #history-design-and-future }
-Однажды, <a href="https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920" class="external-link" target="_blank">один из пользователей **FastAPI** задал вопрос</a>:
+Однажды, [один из пользователей **FastAPI** задал вопрос](https://github.com/fastapi/fastapi/issues/3#issuecomment-454956920):
> Какова история этого проекта? Создаётся впечатление, что он явился из ниоткуда и завоевал мир за несколько недель [...]
Во многом история **FastAPI** - история его предшественников.
-Как написано в разделе [Альтернативы](alternatives.md){.internal-link target=_blank}:
+Как написано в разделе [Альтернативы](alternatives.md):
<blockquote markdown="1">
Я проверил несколько идей на самых популярных редакторах кода: PyCharm, VS Code, редакторы на базе Jedi.
-Согласно последнему <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">опросу Python-разработчиков</a>, который охватывает около 80% пользователей.
+Согласно последнему [опросу Python-разработчиков](https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools), который охватывает около 80% пользователей.
Это означает, что **FastAPI** был специально проверен на редакторах, используемых 80% Python-разработчиками. И поскольку большинство других редакторов, как правило, работают аналогичным образом, все его преимущества должны работать практически для всех редакторов.
## Зависимости { #requirements }
-Протестировав несколько вариантов, я решил, что в качестве основы буду использовать <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">**Pydantic**</a> и его преимущества.
+Протестировав несколько вариантов, я решил, что в качестве основы буду использовать [**Pydantic**](https://docs.pydantic.dev/) и его преимущества.
По моим предложениям был изменён код этого фреймворка, чтобы сделать его полностью совместимым с JSON Schema, поддержать различные способы определения ограничений и улучшить поддержку в редакторах кода (проверки типов, автозавершение) на основе тестов в нескольких редакторах.
-Во время разработки я также внес вклад в <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>, другую ключевую зависимость.
+Во время разработки я также внес вклад в [**Starlette**](https://www.starlette.dev/), другую ключевую зависимость.
## Разработка { #development }
У **FastAPI** великое будущее.
-И [ваш вклад в это](help-fastapi.md){.internal-link target=_blank} - очень ценен.
+И [ваша помощь](help-fastapi.md) очень ценится.
До версии FastAPI `0.122.0`, когда встроенные утилиты безопасности возвращали ошибку клиенту после неудачной аутентификации, они использовали HTTP статус-код `403 Forbidden`.
-Начиная с версии FastAPI `0.122.0`, используется более подходящий HTTP статус-код `401 Unauthorized`, и в ответе возвращается имеющий смысл HTTP-заголовок `WWW-Authenticate` в соответствии со спецификациями HTTP, <a href="https://datatracker.ietf.org/doc/html/rfc7235#section-3.1" class="external-link" target="_blank">RFC 7235</a>, <a href="https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized" class="external-link" target="_blank">RFC 9110</a>.
+Начиная с версии FastAPI `0.122.0`, используется более подходящий HTTP статус-код `401 Unauthorized`, и в ответе возвращается имеющий смысл HTTP-заголовок `WWW-Authenticate` в соответствии со спецификациями HTTP, [RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235#section-3.1), [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized).
Но если по какой-то причине ваши клиенты зависят от старого поведения, вы можете вернуть его, переопределив метод `make_not_authenticated_error` в ваших Security-классах.
Если в вашем коде есть уязвимость, она всё равно останется.
-Сокрытие документации лишь усложняет понимание того, как взаимодействовать с вашим API, и может усложнить его отладку в продакшн. Это можно считать просто разновидностью <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">безопасности через сокрытие</a>.
+Сокрытие документации лишь усложняет понимание того, как взаимодействовать с вашим API, и может усложнить его отладку в продакшн. Это можно считать просто разновидностью [безопасности через сокрытие](https://en.wikipedia.org/wiki/Security_through_obscurity).
Если вы хотите обезопасить свой API, есть несколько более эффективных вещей, которые можно сделать, например:
# Настройка Swagger UI { #configure-swagger-ui }
-Вы можете настроить дополнительные <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/" class="external-link" target="_blank">параметры Swagger UI</a>.
+Вы можете настроить дополнительные [параметры Swagger UI](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/).
Чтобы настроить их, передайте аргумент `swagger_ui_parameters` при создании объекта приложения `FastAPI()` или в функцию `get_swagger_ui_html()`.
## Другие параметры Swagger UI { #other-swagger-ui-parameters }
-Чтобы увидеть все остальные возможные настройки, прочитайте официальную <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/" class="external-link" target="_blank">документацию по параметрам Swagger UI</a>.
+Чтобы увидеть все остальные возможные настройки, прочитайте официальную [документацию по параметрам Swagger UI](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/).
## Настройки только для JavaScript { #javascript-only-settings }
### Тестирование { #test-it }
-Теперь вы должны иметь возможность открыть свою документацию по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> и перезагрузить страницу — «ассеты» (статические файлы) будут загружаться с нового CDN.
+Теперь вы должны иметь возможность открыть свою документацию по адресу [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) и перезагрузить страницу — «ассеты» (статические файлы) будут загружаться с нового CDN.
## Самостоятельный хостинг JavaScript и CSS для документации { #self-hosting-javascript-and-css-for-docs }
**Swagger UI** использует файлы:
-* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
-* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
+* [`swagger-ui-bundle.js`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js)
+* [`swagger-ui.css`](https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css)
А **ReDoc** использует файл:
-* <a href="https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a>
+* [`redoc.standalone.js`](https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js)
После этого структура файлов может выглядеть так:
### Протестируйте статические файлы { #test-the-static-files }
-Запустите своё приложение и откройте <a href="http://127.0.0.1:8000/static/redoc.standalone.js" class="external-link" target="_blank">http://127.0.0.1:8000/static/redoc.standalone.js</a>.
+Запустите своё приложение и откройте [http://127.0.0.1:8000/static/redoc.standalone.js](http://127.0.0.1:8000/static/redoc.standalone.js).
Вы должны увидеть очень длинный JavaScript-файл для **ReDoc**.
### Тестирование UI со статическими файлами { #test-static-files-ui }
-Теперь вы можете отключить Wi‑Fi, открыть свою документацию по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> и перезагрузить страницу.
+Теперь вы можете отключить Wi‑Fi, открыть свою документацию по адресу [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) и перезагрузить страницу.
Даже без Интернета вы сможете видеть документацию к своему API и взаимодействовать с ним.
Некоторые сценарии:
-* Преобразование тел запросов, не в формате JSON, в JSON (например, <a href="https://msgpack.org/index.html" class="external-link" target="_blank">`msgpack`</a>).
+* Преобразование тел запросов, не в формате JSON, в JSON (например, [`msgpack`](https://msgpack.org/index.html)).
* Распаковка тел запросов, сжатых с помощью gzip.
* Автоматическое логирование всех тел запросов.
/// tip | Совет
-Это учебный пример, демонстрирующий принцип работы. Если вам нужна поддержка Gzip, вы можете использовать готовый [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank}.
+Это учебный пример, демонстрирующий принцип работы. Если вам нужна поддержка Gzip, вы можете использовать готовый [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware).
///
Именно этих двух компонентов — `scope` и `receive` — достаточно, чтобы создать новый экземпляр `Request`.
-Чтобы узнать больше о `Request`, см. <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">документацию Starlette о запросах</a>.
+Чтобы узнать больше о `Request`, см. [документацию Starlette о запросах](https://www.starlette.dev/requests/).
///
/// tip | Совет
-Для решения этой задачи, вероятно, намного проще использовать `body` в пользовательском обработчике `RequestValidationError` ([Обработка ошибок](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
+Для решения этой задачи, вероятно, намного проще использовать `body` в пользовательском обработчике `RequestValidationError` ([Обработка ошибок](../tutorial/handling-errors.md#use-the-requestvalidationerror-body)).
Но этот пример всё равно актуален и показывает, как взаимодействовать с внутренними компонентами.
Используя информацию выше, вы можете той же вспомогательной функцией сгенерировать схему OpenAPI и переопределить любые нужные части.
-Например, добавим <a href="https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo" class="external-link" target="_blank">расширение OpenAPI ReDoc для включения собственного логотипа</a>.
+Например, добавим [расширение OpenAPI ReDoc для включения собственного логотипа](https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo).
### Обычный **FastAPI** { #normal-fastapi }
### Проверьте { #check-it }
-Перейдите на <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> — вы увидите, что используется ваш кастомный логотип (в этом примере — логотип **FastAPI**):
+Перейдите на [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) — вы увидите, что используется ваш кастомный логотип (в этом примере — логотип **FastAPI**):
<img src="/img/tutorial/extending-openapi/image01.png">
## Фильтрация данных — Безопасность { #filter-data-security }
-Чтобы убедиться, что вы не возвращаете больше данных, чем следует, прочитайте документацию: [Руководство — Модель ответа — Возвращаемый тип](../tutorial/response-model.md){.internal-link target=_blank}.
+Чтобы убедиться, что вы не возвращаете больше данных, чем следует, прочитайте документацию: [Руководство — Модель ответа — Возвращаемый тип](../tutorial/response-model.md).
+
+## Оптимизация производительности ответа — Модель ответа — Возвращаемый тип { #optimize-response-performance-response-model-return-type }
+
+Чтобы оптимизировать производительность при возврате JSON-данных, используйте возвращаемый тип или модель ответа; таким образом Pydantic выполнит сериализацию в JSON на стороне Rust, без прохождения через Python. Подробнее читайте в документации: [Руководство — Модель ответа — Возвращаемый тип](../tutorial/response-model.md).
## Теги в документации — OpenAPI { #documentation-tags-openapi }
-Чтобы добавить теги к вашим *операциям пути* и группировать их в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Теги](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank}.
+Чтобы добавить теги к вашим *операциям пути* и группировать их в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Теги](../tutorial/path-operation-configuration.md#tags).
## Краткое описание и описание в документации — OpenAPI { #documentation-summary-and-description-openapi }
-Чтобы добавить краткое описание и описание к вашим *операциям пути* и отобразить их в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Краткое описание и описание](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank}.
+Чтобы добавить краткое описание и описание к вашим *операциям пути* и отобразить их в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Краткое описание и описание](../tutorial/path-operation-configuration.md#summary-and-description).
## Описание ответа в документации — OpenAPI { #documentation-response-description-openapi }
-Чтобы задать описание ответа, отображаемое в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Описание ответа](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank}.
+Чтобы задать описание ответа, отображаемое в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Описание ответа](../tutorial/path-operation-configuration.md#response-description).
## Документация — пометить операцию пути устаревшей — OpenAPI { #documentation-deprecate-a-path-operation-openapi }
-Чтобы пометить *операцию пути* как устаревшую и показать это в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Пометить операцию пути устаревшей](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank}.
+Чтобы пометить *операцию пути* как устаревшую и показать это в интерфейсе документации, прочитайте документацию: [Руководство — Конфигурации операций пути — Пометить операцию пути устаревшей](../tutorial/path-operation-configuration.md#deprecate-a-path-operation).
## Преобразование любых данных к формату, совместимому с JSON { #convert-any-data-to-json-compatible }
-Чтобы преобразовать любые данные к формату, совместимому с JSON, прочитайте документацию: [Руководство — JSON-совместимый кодировщик](../tutorial/encoder.md){.internal-link target=_blank}.
+Чтобы преобразовать любые данные к формату, совместимому с JSON, прочитайте документацию: [Руководство — JSON-совместимый кодировщик](../tutorial/encoder.md).
## Метаданные OpenAPI — Документация { #openapi-metadata-docs }
-Чтобы добавить метаданные в вашу схему OpenAPI, включая лицензию, версию, контакты и т.д., прочитайте документацию: [Руководство — Метаданные и URL документации](../tutorial/metadata.md){.internal-link target=_blank}.
+Чтобы добавить метаданные в вашу схему OpenAPI, включая лицензию, версию, контакты и т.д., прочитайте документацию: [Руководство — Метаданные и URL документации](../tutorial/metadata.md).
## Пользовательский URL OpenAPI { #openapi-custom-url }
-Чтобы настроить URL OpenAPI (или удалить его), прочитайте документацию: [Руководство — Метаданные и URL документации](../tutorial/metadata.md#openapi-url){.internal-link target=_blank}.
+Чтобы настроить URL OpenAPI (или удалить его), прочитайте документацию: [Руководство — Метаданные и URL документации](../tutorial/metadata.md#openapi-url).
## URL документации OpenAPI { #openapi-docs-urls }
-Чтобы изменить URL, используемые для автоматически сгенерированных пользовательских интерфейсов документации, прочитайте документацию: [Руководство — Метаданные и URL документации](../tutorial/metadata.md#docs-urls){.internal-link target=_blank}.
+Чтобы изменить URL, используемые для автоматически сгенерированных пользовательских интерфейсов документации, прочитайте документацию: [Руководство — Метаданные и URL документации](../tutorial/metadata.md#docs-urls).
Ниже приведены некоторые библиотеки **GraphQL** с поддержкой **ASGI**. Их можно использовать с **FastAPI**:
-* <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a> 🍓
- * С <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">документацией для FastAPI</a>
-* <a href="https://ariadnegraphql.org/" class="external-link" target="_blank">Ariadne</a>
- * С <a href="https://ariadnegraphql.org/docs/fastapi-integration" class="external-link" target="_blank">документацией для FastAPI</a>
-* <a href="https://tartiflette.io/" class="external-link" target="_blank">Tartiflette</a>
- * С <a href="https://tartiflette.github.io/tartiflette-asgi/" class="external-link" target="_blank">Tartiflette ASGI</a> для интеграции с ASGI
-* <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>
- * С <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>
+* [Strawberry](https://strawberry.rocks/) 🍓
+ * С [документацией для FastAPI](https://strawberry.rocks/docs/integrations/fastapi)
+* [Ariadne](https://ariadnegraphql.org/)
+ * С [документацией для FastAPI](https://ariadnegraphql.org/docs/fastapi-integration)
+* [Tartiflette](https://tartiflette.io/)
+ * С [Tartiflette ASGI](https://tartiflette.github.io/tartiflette-asgi/) для интеграции с ASGI
+* [Graphene](https://graphene-python.org/)
+ * С [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3)
## GraphQL со Strawberry { #graphql-with-strawberry }
-Если вам нужно или хочется работать с **GraphQL**, <a href="https://strawberry.rocks/" class="external-link" target="_blank">**Strawberry**</a> — **рекомендуемая** библиотека, так как её дизайн ближе всего к дизайну **FastAPI**, всё основано на **аннотациях типов**.
+Если вам нужно или хочется работать с **GraphQL**, [**Strawberry**](https://strawberry.rocks/) — **рекомендуемая** библиотека, так как её дизайн ближе всего к дизайну **FastAPI**, всё основано на **аннотациях типов**.
В зависимости от вашего сценария использования вы можете предпочесть другую библиотеку, но если бы вы спросили меня, я, скорее всего, предложил бы попробовать **Strawberry**.
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
-Подробнее о Strawberry можно узнать в <a href="https://strawberry.rocks/" class="external-link" target="_blank">документации Strawberry</a>.
+Подробнее о Strawberry можно узнать в [документации Strawberry](https://strawberry.rocks/).
-А также в документации по <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">интеграции Strawberry с FastAPI</a>.
+А также в документации по [интеграции Strawberry с FastAPI](https://strawberry.rocks/docs/integrations/fastapi).
## Устаревший `GraphQLApp` из Starlette { #older-graphqlapp-from-starlette }
-В предыдущих версиях Starlette был класс `GraphQLApp` для интеграции с <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>.
+В предыдущих версиях Starlette был класс `GraphQLApp` для интеграции с [Graphene](https://graphene-python.org/).
-Он был объявлен устаревшим в Starlette, но если у вас есть код, который его использовал, вы можете легко **мигрировать** на <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>, который решает ту же задачу и имеет **почти идентичный интерфейс**.
+Он был объявлен устаревшим в Starlette, но если у вас есть код, который его использовал, вы можете легко **мигрировать** на [starlette-graphene3](https://github.com/ciscorn/starlette-graphene3), который решает ту же задачу и имеет **почти идентичный интерфейс**.
/// tip | Совет
-Если вам нужен GraphQL, я всё же рекомендую посмотреть <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a>, так как он основан на аннотациях типов, а не на пользовательских классах и типах.
+Если вам нужен GraphQL, я всё же рекомендую посмотреть [Strawberry](https://strawberry.rocks/), так как он основан на аннотациях типов, а не на пользовательских классах и типах.
///
## Подробнее { #learn-more }
-Подробнее о **GraphQL** вы можете узнать в <a href="https://graphql.org/" class="external-link" target="_blank">официальной документации GraphQL</a>.
+Подробнее о **GraphQL** вы можете узнать в [официальной документации GraphQL](https://graphql.org/).
Также можно почитать больше о каждой из указанных выше библиотек по приведённым ссылкам.
/// tip | Совет
-Если вы хотите **изучить FastAPI** структурированно (рекомендуется), вместо этого читайте [Учебник — Руководство пользователя](../tutorial/index.md){.internal-link target=_blank} по главам.
+Если вы хотите **изучить FastAPI** структурированно (рекомендуется), вместо этого читайте [Учебник - Руководство пользователя](../tutorial/index.md) по главам.
///
## Официальное руководство { #official-guide }
-У Pydantic есть официальное <a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">руководство по миграции</a> с v1 на v2.
+У Pydantic есть официальное [руководство по миграции](https://docs.pydantic.dev/latest/migration/) с v1 на v2.
Там также описано, что изменилось, как валидации стали более корректными и строгими, возможные нюансы и т.д.
## Тесты { #tests }
-Убедитесь, что у вас есть [тесты](../tutorial/testing.md){.internal-link target=_blank} для вашего приложения и что вы запускаете их в системе непрерывной интеграции (CI).
+Убедитесь, что у вас есть [тесты](../tutorial/testing.md) для вашего приложения и что вы запускаете их в системе непрерывной интеграции (CI).
Так вы сможете выполнить обновление и убедиться, что всё работает как ожидается.
Во многих случаях, когда вы используете обычные Pydantic‑модели без пользовательских настроек, вы сможете автоматизировать большую часть процесса миграции с Pydantic v1 на Pydantic v2.
-Вы можете использовать <a href="https://github.com/pydantic/bump-pydantic" class="external-link" target="_blank">`bump-pydantic`</a> от той же команды Pydantic.
+Вы можете использовать [`bump-pydantic`](https://github.com/pydantic/bump-pydantic) от той же команды Pydantic.
Этот инструмент поможет автоматически изменить большую часть кода, который нужно изменить.
# Тестирование базы данных { #testing-a-database }
-Вы можете изучить базы данных, SQL и SQLModel в <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">документации SQLModel</a>. 🤓
+Вы можете изучить базы данных, SQL и SQLModel в [документации SQLModel](https://sqlmodel.tiangolo.com/). 🤓
-Есть мини-<a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">руководство по использованию SQLModel с FastAPI</a>. ✨
+Есть мини-[руководство по использованию SQLModel с FastAPI](https://sqlmodel.tiangolo.com/tutorial/fastapi/). ✨
-В этом руководстве есть раздел о <a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/" class="external-link" target="_blank">тестировании SQL-баз данных</a>. 😎
+В этом руководстве есть раздел о [тестировании SQL-баз данных](https://sqlmodel.tiangolo.com/tutorial/fastapi/tests/). 😎
<em>Фреймворк FastAPI: высокая производительность, прост в изучении, позволяет быстро писать код, готов к продакшн</em>
</p>
<p align="center">
-<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
+<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Тест">
</a>
-<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
+<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Покрытие">
</a>
-<a href="https://pypi.org/project/fastapi" target="_blank">
+<a href="https://pypi.org/project/fastapi">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Версия пакета">
</a>
-<a href="https://pypi.org/project/fastapi" target="_blank">
+<a href="https://pypi.org/project/fastapi">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Поддерживаемые версии Python">
</a>
</p>
---
-**Документация**: <a href="https://fastapi.tiangolo.com/ru" target="_blank">https://fastapi.tiangolo.com</a>
+**Документация**: [https://fastapi.tiangolo.com](https://fastapi.tiangolo.com/ru)
-**Исходный код**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
+**Исходный код**: [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi)
---
* **Простота**: Разработан так, чтобы его было легко использовать и осваивать. Меньше времени на чтение документации.
* **Краткость**: Минимизируйте дублирование кода. Несколько возможностей из каждого объявления параметров. Меньше ошибок.
* **Надежность**: Получите код, готовый к продакшн. С автоматической интерактивной документацией.
-* **На основе стандартов**: Основан на открытых стандартах API и полностью совместим с ними: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (ранее известный как Swagger) и <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
+* **На основе стандартов**: Основан на открытых стандартах API и полностью совместим с ними: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (ранее известный как Swagger) и [JSON Schema](https://json-schema.org/).
<small>* оценка на основе тестов внутренней команды разработчиков, создающих продакшн-приложения.</small>
### Ключевой-спонсор { #keystone-sponsor }
{% for sponsor in sponsors.keystone -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
### Золотые и серебряные спонсоры { #gold-and-silver-sponsors }
{% for sponsor in sponsors.gold -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
<!-- /sponsors -->
-<a href="https://fastapi.tiangolo.com/ru/fastapi-people/#sponsors" class="external-link" target="_blank">Другие спонсоры</a>
+[Другие спонсоры](https://fastapi.tiangolo.com/ru/fastapi-people/#sponsors)
## Мнения { #opinions }
"_[...] В последнее время я много где использую **FastAPI**. [...] На самом деле я планирую использовать его для всех **ML-сервисов моей команды в Microsoft**. Некоторые из них интегрируются в основной продукт **Windows**, а некоторые — в продукты **Office**._"
-<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26"><small>(ref)</small></a></div>
---
"_Мы начали использовать библиотеку **FastAPI**, чтобы поднять **REST**-сервер, к которому можно обращаться за **предсказаниями**. [для Ludwig]_"
-<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/"><small>(ref)</small></a></div>
---
"_**Netflix** рада объявить об открытом релизе нашего фреймворка оркестрации **антикризисного управления**: **Dispatch**! [создан с помощью **FastAPI**]_"
-<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072"><small>(ref)</small></a></div>
---
"_Я в полном восторге от **FastAPI**. Это так весело!_"
-<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>Ведущий подкаста <a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a></strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>Ведущий подкаста [Python Bytes](https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855)</strong> <a href="https://x.com/brianokken/status/1112220079972728832"><small>(ref)</small></a></div>
---
"_Честно говоря, то, что вы создали, выглядит очень солидно и отполировано. Во многих смыслах это то, чем я хотел видеть **Hug** — очень вдохновляет видеть, как кто-то это создал._"
-<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>Создатель <a href="https://github.com/hugapi/hug" target="_blank">Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong>Создатель [Hug](https://github.com/hugapi/hug)</strong> <a href="https://news.ycombinator.com/item?id=19455465"><small>(ref)</small></a></div>
---
"_Мы переключились на **FastAPI** для наших **API** [...] Думаю, вам тоже понравится [...]_"
-<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>Основатели <a href="https://explosion.ai" target="_blank">Explosion AI</a> — создатели <a href="https://spacy.io" target="_blank">spaCy</a></strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>Основатели [Explosion AI](https://explosion.ai) — создатели [spaCy](https://spacy.io)</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680"><small>(ref)</small></a></div>
---
"_Если кто-то собирается делать продакшн-API на Python, я настоятельно рекомендую **FastAPI**. Он **прекрасно спроектирован**, **прост в использовании** и **отлично масштабируется**, стал **ключевым компонентом** нашей стратегии API-first и приводит в действие множество автоматизаций и сервисов, таких как наш Virtual TAC Engineer._"
-<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
+<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/"><small>(ref)</small></a></div>
---
## Мини-документальный фильм о FastAPI { #fastapi-mini-documentary }
-В конце 2025 года вышел <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">мини-документальный фильм о FastAPI</a>, вы можете посмотреть его онлайн:
+В конце 2025 года вышел [мини-документальный фильм о FastAPI](https://www.youtube.com/watch?v=mpR8ngthqiE), вы можете посмотреть его онлайн:
-<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
+<a href="https://www.youtube.com/watch?v=mpR8ngthqiE"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
## **Typer**, FastAPI для CLI { #typer-the-fastapi-of-clis }
-<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
+<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
-Если вы создаёте приложение <abbr title="Command Line Interface - Интерфейс командной строки">CLI</abbr> для использования в терминале вместо веб-API, посмотрите <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
+Если вы создаёте приложение <abbr title="Command Line Interface - Интерфейс командной строки">CLI</abbr> для использования в терминале вместо веб-API, посмотрите [**Typer**](https://typer.tiangolo.com/).
**Typer** — младший брат FastAPI. И он задуман как **FastAPI для CLI**. ⌨️ 🚀
FastAPI стоит на плечах гигантов:
-* <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> для части, связанной с вебом.
-* <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> для части, связанной с данными.
+* [Starlette](https://www.starlette.dev/) для части, связанной с вебом.
+* [Pydantic](https://docs.pydantic.dev/) для части, связанной с данными.
## Установка { #installation }
-Создайте и активируйте <a href="https://fastapi.tiangolo.com/ru/virtual-environments/" class="external-link" target="_blank">виртуальное окружение</a>, затем установите FastAPI:
+Создайте и активируйте [виртуальное окружение](https://fastapi.tiangolo.com/ru/virtual-environments/), затем установите FastAPI:
<div class="termy">
**Примечание**:
-Если не уверены, посмотрите раздел _«Нет времени?»_ о <a href="https://fastapi.tiangolo.com/ru/async/#in-a-hurry" target="_blank">`async` и `await` в документации</a>.
+Если не уверены, посмотрите раздел _«Нет времени?»_ о [`async` и `await` в документации](https://fastapi.tiangolo.com/ru/async/#in-a-hurry).
</details>
<div class="termy">
```console
-$ fastapi dev main.py
+$ fastapi dev
╭────────── FastAPI CLI - Development mode ───────────╮
│ │
</div>
<details markdown="1">
-<summary>О команде <code>fastapi dev main.py</code>...</summary>
+<summary>О команде <code>fastapi dev</code>...</summary>
-Команда `fastapi dev` читает ваш файл `main.py`, находит в нём приложение **FastAPI** и запускает сервер с помощью <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
+Команда `fastapi dev` читает ваш файл `main.py`, находит в нём приложение **FastAPI** и запускает сервер с помощью [Uvicorn](https://www.uvicorn.dev).
По умолчанию `fastapi dev` запускается с включённой авто-перезагрузкой для локальной разработки.
-Подробнее в <a href="https://fastapi.tiangolo.com/ru/fastapi-cli/" target="_blank">документации по FastAPI CLI</a>.
+Подробнее в [документации по FastAPI CLI](https://fastapi.tiangolo.com/ru/fastapi-cli/).
</details>
### Проверка { #check-it }
-Откройте браузер на <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
+Откройте браузер на [http://127.0.0.1:8000/items/5?q=somequery](http://127.0.0.1:8000/items/5?q=somequery).
Вы увидите JSON-ответ:
### Интерактивная документация API { #interactive-api-docs }
-Перейдите на <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Перейдите на [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
-Вы увидите автоматическую интерактивную документацию API (предоставлена <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
+Вы увидите автоматическую интерактивную документацию API (предоставлена [Swagger UI](https://github.com/swagger-api/swagger-ui)):

### Альтернативная документация API { #alternative-api-docs }
-Теперь откройте <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+Теперь откройте [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
-Вы увидите альтернативную автоматическую документацию (предоставлена <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
+Вы увидите альтернативную автоматическую документацию (предоставлена [ReDoc](https://github.com/Rebilly/ReDoc)):

### Обновление интерактивной документации API { #interactive-api-docs-upgrade }
-Перейдите на <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Перейдите на [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
* Интерактивная документация API будет автоматически обновлена, включая новое тело запроса:
### Обновление альтернативной документации API { #alternative-api-docs-upgrade }
-Теперь откройте <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+Теперь откройте [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
* Альтернативная документация также отразит новый параметр запроса и тело запроса:
* Очень мощную и простую в использовании систему **<dfn title="также известна как: компоненты, ресурсы, провайдеры, сервисы, инъекции">внедрения зависимостей</dfn>**.
* Безопасность и аутентификацию, включая поддержку **OAuth2** с **JWT токенами** и **HTTP Basic** аутентификацию.
* Более продвинутые (но столь же простые) приёмы объявления **глубоко вложенных JSON-моделей** (спасибо Pydantic).
-* Интеграцию **GraphQL** с <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> и другими библиотеками.
+* Интеграцию **GraphQL** с [Strawberry](https://strawberry.rocks) и другими библиотеками.
* Множество дополнительных функций (благодаря Starlette), таких как:
* **WebSockets**
* чрезвычайно простые тесты на основе HTTPX и `pytest`
### Разверните приложение (опционально) { #deploy-your-app-optional }
-При желании вы можете развернуть своё приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
+При желании вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com), присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
Если у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉), вы можете развернуть ваше приложение одной командой.
-Перед развертыванием убедитесь, что вы вошли в систему:
-
-<div class="termy">
-
-```console
-$ fastapi login
-
-You are logged in to FastAPI Cloud 🚀
-```
-
-</div>
-
-Затем разверните приложение:
-
<div class="termy">
```console
#### О FastAPI Cloud { #about-fastapi-cloud }
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, что и **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** создан тем же автором и командой, что и **FastAPI**.
Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API при минимальных усилиях.
## Производительность { #performance }
-Независимые бенчмарки TechEmpower показывают приложения **FastAPI**, работающие под управлением Uvicorn, как <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">один из самых быстрых доступных фреймворков Python</a>, уступающий только самим Starlette и Uvicorn (используются внутри FastAPI). (*)
+Независимые бенчмарки TechEmpower показывают приложения **FastAPI**, работающие под управлением Uvicorn, как [один из самых быстрых доступных фреймворков Python](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), уступающий только самим Starlette и Uvicorn (используются внутри FastAPI). (*)
-Чтобы узнать больше, см. раздел <a href="https://fastapi.tiangolo.com/ru/benchmarks/" class="internal-link" target="_blank">Бенчмарки</a>.
+Чтобы узнать больше, см. раздел [Бенчмарки](https://fastapi.tiangolo.com/ru/benchmarks/).
## Зависимости { #dependencies }
Используется Pydantic:
-* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> — для проверки адресов электронной почты.
+* [`email-validator`](https://github.com/JoshData/python-email-validator) — для проверки адресов электронной почты.
Используется Starlette:
-* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> — обязателен, если вы хотите использовать `TestClient`.
-* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> — обязателен, если вы хотите использовать конфигурацию шаблонов по умолчанию.
-* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - обязателен, если вы хотите поддерживать <dfn title="преобразование строки, полученной из HTTP-запроса, в данные Python">«парсинг»</dfn> форм через `request.form()`.
+* [`httpx`](https://www.python-httpx.org) — обязателен, если вы хотите использовать `TestClient`.
+* [`jinja2`](https://jinja.palletsprojects.com) — обязателен, если вы хотите использовать конфигурацию шаблонов по умолчанию.
+* [`python-multipart`](https://github.com/Kludex/python-multipart) - обязателен, если вы хотите поддерживать <dfn title="преобразование строки, полученной из HTTP-запроса, в данные Python">«парсинг»</dfn> форм через `request.form()`.
Используется FastAPI:
-* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> — сервер, который загружает и «отдаёт» ваше приложение. Включает `uvicorn[standard]`, содержащий некоторые зависимости (например, `uvloop`), нужные для высокой производительности.
+* [`uvicorn`](https://www.uvicorn.dev) — сервер, который загружает и «отдаёт» ваше приложение. Включает `uvicorn[standard]`, содержащий некоторые зависимости (например, `uvloop`), нужные для высокой производительности.
* `fastapi-cli[standard]` — чтобы предоставить команду `fastapi`.
- * Включает `fastapi-cloud-cli`, который позволяет развернуть ваше приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
+ * Включает `fastapi-cloud-cli`, который позволяет развернуть ваше приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com).
### Без зависимостей `standard` { #without-standard-dependencies }
Дополнительные опциональные зависимости Pydantic:
-* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> — для управления настройками.
-* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> — дополнительные типы для использования с Pydantic.
+* [`pydantic-settings`](https://docs.pydantic.dev/latest/usage/pydantic_settings/) — для управления настройками.
+* [`pydantic-extra-types`](https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/) — дополнительные типы для использования с Pydantic.
Дополнительные опциональные зависимости FastAPI:
-* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> — обязателен, если вы хотите использовать `ORJSONResponse`.
-* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> — обязателен, если вы хотите использовать `UJSONResponse`.
+* [`orjson`](https://github.com/ijl/orjson) — обязателен, если вы хотите использовать `ORJSONResponse`.
+* [`ujson`](https://github.com/esnme/ultrajson) — обязателен, если вы хотите использовать `UJSONResponse`.
## Лицензия { #license }
Вы можете использовать этот шаблон для старта: в нём уже сделана значительная часть начальной настройки, безопасность, база данных и несколько эндпоинтов API.
-Репозиторий GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-template" class="external-link" target="_blank">Full Stack FastAPI Template</a>
+Репозиторий GitHub: [Full Stack FastAPI Template](https://github.com/tiangolo/full-stack-fastapi-template)
## Шаблон Full Stack FastAPI — Технологический стек и возможности { #full-stack-fastapi-template-technology-stack-and-features }
## Pydantic-модели { #pydantic-models }
-<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> — это библиотека Python для валидации данных.
+[Pydantic](https://docs.pydantic.dev/) — это библиотека Python для валидации данных.
Вы объявляете «форму» данных как классы с атрибутами.
/// info | Информация
-Чтобы узнать больше о <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic, ознакомьтесь с его документацией</a>.
+Чтобы узнать больше о [Pydantic, ознакомьтесь с его документацией](https://docs.pydantic.dev/).
///
**FastAPI** целиком основан на Pydantic.
-Вы увидите намного больше всего этого на практике в [Учебник - Руководство пользователя](tutorial/index.md){.internal-link target=_blank}.
+Вы увидите намного больше всего этого на практике в [Учебник - Руководство пользователя](tutorial/index.md).
## Подсказки типов с аннотациями метаданных { #type-hints-with-metadata-annotations }
* **Документирования** API с использованием OpenAPI:
* что затем используется пользовательскими интерфейсами автоматической интерактивной документации.
-Всё это может звучать абстрактно. Не волнуйтесь. Вы увидите всё это в действии в [Учебник - Руководство пользователя](tutorial/index.md){.internal-link target=_blank}.
+Всё это может звучать абстрактно. Не волнуйтесь. Вы увидите всё это в действии в [Учебник - Руководство пользователя](tutorial/index.md).
Важно то, что, используя стандартные типы Python в одном месте (вместо добавления дополнительных классов, декораторов и т.д.), **FastAPI** сделает за вас большую часть работы.
/// info | Информация
-Если вы уже прошли всё руководство и вернулись, чтобы узнать больше о типах, хорошим ресурсом будет <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">«шпаргалка» от `mypy`</a>.
+Если вы уже прошли всё руководство и вернулись, чтобы узнать больше о типах, хорошим ресурсом будет [«шпаргалка» от `mypy`](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html).
///
## Технические детали { #technical-details }
-Класс `BackgroundTasks` приходит напрямую из <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>.
+Класс `BackgroundTasks` приходит напрямую из [`starlette.background`](https://www.starlette.dev/background/).
Он импортируется/включается прямо в FastAPI, чтобы вы могли импортировать его из `fastapi` и избежать случайного импорта альтернативного `BackgroundTask` (без `s` на конце) из `starlette.background`.
По‑прежнему можно использовать один `BackgroundTask` в FastAPI, но тогда вам нужно создать объект в своём коде и вернуть Starlette `Response`, включающий его.
-Подробнее см. в <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">официальной документации Starlette по фоновым задачам</a>.
+Подробнее см. в [официальной документации Starlette по фоновым задачам](https://www.starlette.dev/background/).
## Предостережение { #caveat }
-Если вам нужно выполнять тяжелые вычисления в фоне, и при этом они не обязательно должны запускаться тем же процессом (например, вам не нужно делиться памятью, переменными и т.п.), вам могут подойти более мощные инструменты, такие как <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>.
+Если вам нужно выполнять тяжелые вычисления в фоне, и при этом они не обязательно должны запускаться тем же процессом (например, вам не нужно делиться памятью, переменными и т.п.), вам могут подойти более мощные инструменты, такие как [Celery](https://docs.celeryq.dev).
Они обычно требуют более сложной конфигурации, менеджера очереди сообщений/заданий (например, RabbitMQ или Redis), но позволяют запускать фоновые задачи в нескольких процессах и, что особенно важно, на нескольких серверах.
Для простоты мы воспользовались выдуманным заголовком.
-В реальных случаях для получения наилучших результатов используйте интегрированные [утилиты безопасности](security/index.md){.internal-link target=_blank}.
+В реальных случаях для получения наилучших результатов используйте интегрированные [утилиты безопасности](security/index.md).
///
/// tip | Подсказка
-Обратите внимание, что так же, как и в случае с [зависимостями в декораторах *операций пути*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, никакое значение не будет передано в вашу *функцию-обработчик пути*.
+Обратите внимание, что так же, как и в случае с [зависимостями в декораторах *операций пути*](dependencies/dependencies-in-path-operation-decorators.md), никакое значение не будет передано в вашу *функцию-обработчик пути*.
///
* Все они будут включать предопределённые `responses`.
* Все эти *операции пути* будут иметь список `dependencies`, вычисляемых/выполняемых перед ними.
* Если вы также объявите зависимости в конкретной *операции пути*, **они тоже будут выполнены**.
- * Сначала выполняются зависимости маршрутизатора, затем [`dependencies` в декораторе](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, и затем обычные параметрические зависимости.
- * Вы также можете добавить [`Security`-зависимости с `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
+ * Сначала выполняются зависимости маршрутизатора, затем [`dependencies` в декораторе](dependencies/dependencies-in-path-operation-decorators.md), и затем обычные параметрические зависимости.
+ * Вы также можете добавить [`Security`-зависимости с `scopes`](../advanced/security/oauth2-scopes.md).
/// tip | Подсказка
Вы импортируете и создаёте класс `FastAPI` как обычно.
-И мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого `APIRouter`:
+И мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md), которые будут объединены с зависимостями для каждого `APIRouter`:
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
from app.routers import items, users
```
-Чтобы узнать больше о Python-пакетах и модулях, прочитайте <a href="https://docs.python.org/3/tutorial/modules.html" class="external-link" target="_blank">официальную документацию Python о модулях</a>.
+Чтобы узнать больше о Python-пакетах и модулях, прочитайте [официальную документацию Python о модулях](https://docs.python.org/3/tutorial/modules.html).
///
///
+## Настройка `entrypoint` в `pyproject.toml` { #configure-the-entrypoint-in-pyproject-toml }
+
+Так как ваш объект FastAPI `app` находится в `app/main.py`, вы можете настроить `entrypoint` в файле `pyproject.toml` следующим образом:
+
+```toml
+[tool.fastapi]
+entrypoint = "app.main:app"
+```
+
+это эквивалентно импорту:
+
+```python
+from app.main import app
+```
+
+Таким образом, команда `fastapi` будет знать, где найти ваше приложение.
+
+/// Note | Примечание
+
+Вы также можете передать путь в команду, например:
+
+```console
+$ fastapi dev app/main.py
+```
+
+Но вам придётся каждый раз помнить и указывать корректный путь при вызове команды `fastapi`.
+
+Кроме того, другие инструменты могут не суметь его найти, например [расширение VS Code](../editor-support.md) или [FastAPI Cloud](https://fastapicloud.com), поэтому рекомендуется использовать `entrypoint` в `pyproject.toml`.
+
+///
+
## Проверка автоматической документации API { #check-the-automatic-api-docs }
Теперь запустите приложение:
<div class="termy">
```console
-$ fastapi dev app/main.py
+$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
-Откройте документацию по адресу <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Откройте документацию по адресу [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Вы увидите автоматическую документацию API, включая пути из всех подмодулей, с использованием корректных путей (и префиксов) и корректных тегов:
Помимо обычных простых типов, таких как `str`, `int`, `float` и т.д., вы можете использовать более сложные простые типы, которые наследуются от `str`.
-Чтобы увидеть все варианты, которые у вас есть, ознакомьтесь с <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">обзором типов Pydantic</a>. Вы увидите некоторые примеры в следующей главе.
+Чтобы увидеть все варианты, которые у вас есть, ознакомьтесь с [обзором типов Pydantic](https://docs.pydantic.dev/latest/concepts/types/). Вы увидите некоторые примеры в следующей главе.
Например, так как в модели `Image` у нас есть поле `url`, то мы можем объявить его как тип `HttpUrl` из Pydantic вместо типа `str`:
-# Body - Обновления { #body-updates }
+# Тело запроса - Обновления { #body-updates }
## Обновление с заменой при помощи `PUT` { #update-replacing-with-put }
-Чтобы обновить элемент, вы можете использовать операцию <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT" class="external-link" target="_blank">HTTP `PUT`</a>.
+Чтобы обновить элемент, вы можете использовать операцию [HTTP `PUT`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT).
Вы можете использовать `jsonable_encoder`, чтобы преобразовать входные данные в данные, которые можно сохранить как JSON (например, в NoSQL-базе данных). Например, преобразование `datetime` в `str`.
## Частичное обновление с помощью `PATCH` { #partial-updates-with-patch }
-Также можно использовать операцию <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH" class="external-link" target="_blank">HTTP `PATCH`</a> для *частичного* обновления данных.
+Также можно использовать операцию [HTTP `PATCH`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH) для частичного обновления данных.
Это означает, что можно передавать только те данные, которые необходимо обновить, оставляя остальные нетронутыми.
-/// note | ТеÑ\85ниÑ\87еÑ\81кие деÑ\82али
+/// note | Ð\9fÑ\80имеÑ\87ание
`PATCH` менее распространен и известен, чем `PUT`.
///
-/// note | ТеÑ\85ниÑ\87еÑ\81кие деÑ\82али
+/// note | Ð\9fÑ\80имеÑ\87ание
Обратите внимание, что входная модель по-прежнему валидируется.
Таким образом, если вы хотите получать частичные обновления, в которых могут быть опущены все атрибуты, вам необходимо иметь модель, в которой все атрибуты помечены как необязательные (со значениями по умолчанию или `None`).
-Чтобы отличить модели со всеми необязательными значениями для **обновления** от моделей с обязательными значениями для **создания**, можно воспользоваться идеями, описанными в [Дополнительные модели](extra-models.md){.internal-link target=_blank}.
+Чтобы отличить модели со всеми необязательными значениями для обновления и модели с обязательными значениями для создания, можно воспользоваться идеями, описанными в [Дополнительные модели](extra-models.md).
///
Ваш API почти всегда должен отправлять тело **ответа**. Но клиентам не обязательно всегда отправлять **тело запроса**: иногда они запрашивают только путь, возможно с некоторыми параметрами запроса, но без тела.
-Чтобы объявить тело **запроса**, используйте модели <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, со всей их мощью и преимуществами.
+Чтобы объявить тело **запроса**, используйте модели [Pydantic](https://docs.pydantic.dev/), со всей их мощью и преимуществами.
/// info | Информация
* Если данные некорректны, вернёт понятную и наглядную ошибку, указывающую, где именно и что было некорректно.
* Передаст полученные данные в параметр `item`.
* Поскольку внутри функции вы объявили его с типом `Item`, у вас будет поддержка со стороны редактора кода (автозавершение и т.п.) для всех атрибутов и их типов.
-* Сгенерирует определения <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта.
+* Сгенерирует определения [JSON Schema](https://json-schema.org) для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта.
* Эти схемы будут частью сгенерированной схемы OpenAPI и будут использоваться автоматической документацией <abbr title="User Interfaces - Пользовательские интерфейсы">UIs</abbr>.
## Автоматическая документация { #automatic-docs }
В сам Pydantic даже были внесены некоторые изменения для поддержки этого.
-Предыдущие скриншоты сделаны в <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>.
+Предыдущие скриншоты сделаны в [Visual Studio Code](https://code.visualstudio.com).
-Но вы получите такую же поддержку редактора кода в <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> и большинстве других редакторов Python:
+Но вы получите такую же поддержку редактора кода в [PyCharm](https://www.jetbrains.com/pycharm/) и большинстве других редакторов Python:
<img src="/img/tutorial/body/image05.png">
/// tip | Совет
-Если вы используете <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> в качестве редактора кода, вы можете использовать плагин <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
+Если вы используете [PyCharm](https://www.jetbrains.com/pycharm/) в качестве редактора кода, вы можете использовать плагин [Pydantic PyCharm Plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin/).
Он улучшает поддержку моделей Pydantic в редакторе кода, включая:
## Без Pydantic { #without-pydantic }
-Если вы не хотите использовать модели Pydantic, вы также можете использовать параметры **Body**. См. раздел документации [Тело запроса - Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
+Если вы не хотите использовать модели Pydantic, вы также можете использовать параметры **Body**. См. раздел документации [Тело запроса - Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body).
# CORS (Cross-Origin Resource Sharing) { #cors-cross-origin-resource-sharing }
-<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Понятие CORS или "Cross-Origin Resource Sharing"</a> относится к ситуациям, при которых запущенный в браузере фронтенд содержит JavaScript-код, который взаимодействует с бэкендом, находящимся на другом "источнике" ("origin").
+[CORS или "Cross-Origin Resource Sharing"](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) относится к ситуациям, при которых запущенный в браузере фронтенд содержит JavaScript-код, который взаимодействует с бэкендом, находящимся на другом "источнике" ("origin").
## Источник { #origin }
* `allow_origins` - Список источников, на которые разрешено выполнять кросс-доменные запросы. Например, `['https://example.org', 'https://www.example.org']`. Можно использовать `['*']`, чтобы разрешить любые источники.
* `allow_origin_regex` - Регулярное выражение для определения источников, на которые разрешено выполнять кросс-доменные запросы. Например, `'https://.*\.example\.org'`.
* `allow_methods` - Список HTTP-методов, которые разрешены для кросс-доменных запросов. По умолчанию `['GET']`. Можно использовать `['*']`, чтобы разрешить все стандартные методы.
-* `allow_headers` - Список HTTP-заголовков запроса, которые должны поддерживаться при кросс-доменных запросах. По умолчанию `[]`. Можно использовать `['*']`, чтобы разрешить все заголовки. Заголовки `Accept`, `Accept-Language`, `Content-Language` и `Content-Type` всегда разрешены для <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests" class="external-link" rel="noopener" target="_blank">простых CORS-запросов</a>.
+* `allow_headers` - Список HTTP-заголовков запроса, которые должны поддерживаться при кросс-доменных запросах. По умолчанию `[]`. Можно использовать `['*']`, чтобы разрешить все заголовки. Заголовки `Accept`, `Accept-Language`, `Content-Language` и `Content-Type` всегда разрешены для [простых CORS-запросов](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests).
* `allow_credentials` - Указывает, что куки разрешены в кросс-доменных запросах. По умолчанию `False`.
- Ни один из параметров `allow_origins`, `allow_methods` и `allow_headers` не может быть установлен в `['*']`, если `allow_credentials` имеет значение `True`. Все они должны быть <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards" class="external-link" rel="noopener" target="_blank">указаны явно</a>.
+ Ни один из параметров `allow_origins`, `allow_methods` и `allow_headers` не может быть установлен в `['*']`, если `allow_credentials` имеет значение `True`. Все они должны быть [указаны явно](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#credentialed_requests_and_wildcards).
* `expose_headers` - Указывает любые заголовки ответа, которые должны быть доступны браузеру. По умолчанию `[]`.
* `max_age` - Устанавливает максимальное время в секундах, в течение которого браузер кэширует CORS-ответы. По умолчанию `600`.
## Больше информации { #more-info }
-Для получения более подробной информации о <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">документации CORS от Mozilla</a>.
+Для получения более подробной информации о <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> обратитесь к [документации CORS от Mozilla](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).
/// note | Технические детали
/// info | Информация
-Для получения дополнительной информации, ознакомьтесь с <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">официальной документацией Python</a>.
+Для получения дополнительной информации, ознакомьтесь с [официальной документацией Python](https://docs.python.org/3/library/__main__.html).
///
В этом примере мы используем выдуманные пользовательские HTTP-заголовки `X-Key` и `X-Token`.
-Но в реальных проектах, при внедрении системы безопасности, вы получите больше пользы используя интегрированные [средства защиты (следующая глава)](../security/index.md){.internal-link target=_blank}.
+Но в реальных проектах, при внедрении системы безопасности, вы получите больше пользы используя интегрированные [средства защиты (следующая глава)](../security/index.md).
///
-## Ð\98Ñ\81клÑ\8eÑ\87ениÑ\8f в Ð\97ависимостях и возвращаемые значения { #dependencies-errors-and-return-values }
+## Ð\9eÑ\88ибки в зависимостях и возвращаемые значения { #dependencies-errors-and-return-values }
Вы можете использовать те же *функции* зависимостей, что и обычно.
## Зависимости для группы *операций путей* { #dependencies-for-a-group-of-path-operations }
-Позже, читая о том как структурировать большие приложения ([Большие приложения — несколько файлов](../../tutorial/bigger-applications.md){.internal-link target=_blank}), возможно, многофайловые, вы узнаете как объявить единый параметр `dependencies` для всей группы *операций путей*.
+Позже, читая о том как структурировать большие приложения ([Большие приложения — несколько файлов](../../tutorial/bigger-applications.md)), возможно, многофайловые, вы узнаете как объявить единый параметр `dependencies` для всей группы *операций путей*.
## Глобальные Зависимости { #global-dependencies }
Любая функция, с которой можно корректно использовать:
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> или
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
+* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) или
+* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
будет корректной для использования в качестве зависимости **FastAPI**.
/// note | Технические детали
-Это работает благодаря <a href="https://docs.python.org/3/library/contextlib.html" class="external-link" target="_blank">менеджерам контекста</a> в Python.
+Это работает благодаря [менеджерам контекста](https://docs.python.org/3/library/contextlib.html) в Python.
**FastAPI** использует их внутренне для достижения этого.
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
-Если вы хотите перехватывать исключения и формировать на их основе пользовательский ответ, создайте [Пользовательский обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
+Если вы хотите перехватывать исключения и формировать на их основе пользовательский ответ, создайте [Пользовательский обработчик исключений](../handling-errors.md#install-custom-exception-handlers).
## Зависимости с `yield` и `except` { #dependencies-with-yield-and-except }
Зависимости с `yield` со временем эволюционировали, чтобы покрыть разные сценарии и исправить некоторые проблемы.
-Если вы хотите посмотреть, что менялось в разных версиях FastAPI, вы можете прочитать об этом подробнее в продвинутом руководстве: [Продвинутые зависимости — зависимости с `yield`, `HTTPException`, `except` и фоновыми задачами](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
+Если вы хотите посмотреть, что менялось в разных версиях FastAPI, вы можете прочитать об этом подробнее в продвинутом руководстве: [Продвинутые зависимости — зависимости с `yield`, `HTTPException`, `except` и фоновыми задачами](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks).
## Контекстные менеджеры { #context-managers }
### Что такое «контекстные менеджеры» { #what-are-context-managers }
«Контекстные менеджеры» — это любые объекты Python, которые можно использовать в операторе `with`.
-Например, <a href="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files" class="external-link" target="_blank">можно использовать `with` для чтения файла</a>:
+Например, [можно использовать `with` для чтения файла](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files):
```Python
with open("./somefile.txt") as f:
///
-В Python можно создавать менеджеры контекста, <a href="https://docs.python.org/3/reference/datamodel.html#context-managers" class="external-link" target="_blank">создав класс с двумя методами: `__enter__()` и `__exit__()`</a>.
+В Python можно создавать менеджеры контекста, [создав класс с двумя методами: `__enter__()` и `__exit__()`](https://docs.python.org/3/reference/datamodel.html#context-managers).
Их также можно использовать внутри зависимостей **FastAPI** с `yield`, применяя операторы
`with` или `async with` внутри функции зависимости:
Другой способ создания менеджера контекста — с помощью:
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> или
-* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
+* [`@contextlib.contextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager) или
+* [`@contextlib.asynccontextmanager`](https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager)
оформив ими функцию с одним `yield`.
Для некоторых типов приложений может потребоваться добавить зависимости ко всему приложению.
-Подобно тому, как вы можете [добавлять `dependencies` (зависимости) в *декораторах операций пути*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, вы можете добавлять зависимости сразу ко всему `FastAPI` приложению.
+Подобно тому, как вы можете [добавлять `dependencies` (зависимости) в *декораторах операций пути*](dependencies-in-path-operation-decorators.md), вы можете добавлять зависимости сразу ко всему `FastAPI` приложению.
В этом случае они будут применяться ко всем *операциям пути* в приложении:
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
-Все способы [добавления `dependencies` (зависимостей) в *декораторах операций пути*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} по-прежнему применимы, но в данном случае зависимости применяются ко всем *операциям пути* приложения.
+Все способы [добавления `dependencies` (зависимостей) в *декораторах операций пути*](dependencies-in-path-operation-decorators.md) по-прежнему применимы, но в данном случае зависимости применяются ко всем *операциям пути* приложения.
## Зависимости для групп *операций пути* { #dependencies-for-groups-of-path-operations }
-Ð\9fозднее, Ñ\87иÑ\82аÑ\8f о Ñ\82ом, как Ñ\81Ñ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80иÑ\80оваÑ\82Ñ\8c более кÑ\80Ñ\83пнÑ\8bе пÑ\80иложениÑ\8f ([пÑ\80иложениÑ\8f, Ñ\81одеÑ\80жаÑ\89ие много Ñ\84айлов](../../tutorial/bigger-applications.md){.internal-link target=_blank}), возможно, состоящие из нескольких файлов, вы узнаете, как объявить один параметр `dependencies` для целой группы *операций пути*.
+Ð\9fозднее, Ñ\87иÑ\82аÑ\8f о Ñ\82ом, как Ñ\81Ñ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80иÑ\80оваÑ\82Ñ\8c более кÑ\80Ñ\83пнÑ\8bе пÑ\80иложениÑ\8f ([Ð\91олее кÑ\80Ñ\83пнÑ\8bе пÑ\80иложениÑ\8f - неÑ\81колÑ\8cко Ñ\84айлов](../../tutorial/bigger-applications.md)), возможно, состоящие из нескольких файлов, вы узнаете, как объявить один параметр `dependencies` для целой группы *операций пути*.
* Обеспечить общую логику (один и тот же алгоритм снова и снова).
* Разделять соединения с базой данных.
-* Обеспечить безопасность, аутентификацию, требования к ролям и т. п.
+* Обеспечить безопасность, аутентификацию, требования к ролям и т.п.
* И многое другое...
Всё это при минимизации повторения кода.
Если у вас более старая версия, вы получите ошибки при попытке использовать `Annotated`.
-Убедитесь, что вы [обновили версию FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} как минимум до 0.95.1, прежде чем использовать `Annotated`.
+Убедитесь, что вы [обновили версию FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions) как минимум до 0.95.1, прежде чем использовать `Annotated`.
///
### Объявите зависимость в «зависимом» { #declare-the-dependency-in-the-dependant }
-Точно так же, как вы используете `Body`, `Query` и т. д. с параметрами вашей *функции обработки пути*, используйте `Depends` с новым параметром:
+Точно так же, как вы используете `Body`, `Query` и т.д. с параметрами вашей *функции обработки пути*, используйте `Depends` с новым параметром:
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
-Хотя вы используете `Depends` в параметрах вашей функции так же, как `Body`, `Query` и т. д., `Depends` работает немного иначе.
+Хотя вы используете `Depends` в параметрах вашей функции так же, как `Body`, `Query` и т.д., `Depends` работает немного иначе.
В `Depends` вы передаёте только один параметр.
Вы можете использовать `async def` или обычное `def`.
-И вы можете объявлять зависимости с `async def` внутри обычных *функций обработки пути* `def`, или зависимости `def` внутри *функций обработки пути* `async def` и т. д.
+И вы можете объявлять зависимости с `async def` внутри обычных *функций обработки пути* `def`, или зависимости `def` внутри *функций обработки пути* `async def` и т.д.
Это не важно. **FastAPI** знает, что делать.
/// note | Примечание
-Если вы не уверены, посмотрите раздел [Async: *"In a hurry?"*](../../async.md#in-a-hurry){.internal-link target=_blank} о `async` и `await` в документации.
+Если вы не уверены, посмотрите раздел [Async: «Нет времени?»](../../async.md#in-a-hurry) о `async` и `await` в документации.
///
Например, она не принимает объекты `datetime`, так как они не совместимы с JSON.
-В таком случае объект `datetime` следует преобразовать в строку, соответствующую <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">формату ISO</a>.
+В таком случае объект `datetime` следует преобразовать в `str`, содержащую данные в [формате ISO](https://en.wikipedia.org/wiki/ISO_8601).
Точно так же эта база данных не может принять Pydantic-модель (объект с атрибутами), а только `dict`.
В данном примере она преобразует Pydantic-модель в `dict`, а `datetime` - в `str`.
-Результатом её вызова является объект, который может быть закодирован с помощью функции из стандартной библиотеки Python – <a href="https://docs.python.org/3/library/json.html#json.dumps" class="external-link" target="_blank">`json.dumps()`</a>.
+Результатом её вызова является объект, который может быть закодирован с помощью функции из стандартной библиотеки Python – [`json.dumps()`](https://docs.python.org/3/library/json.html#json.dumps).
Функция не возвращает большой `str`, содержащий данные в формате JSON (в виде строки). Она возвращает стандартную структуру данных Python (например, `dict`) со значениями и подзначениями, которые совместимы с JSON.
* `datetime.timedelta`:
* Встроенный в Python `datetime.timedelta`.
* В запросах и ответах будет представлен в виде общего количества секунд типа `float`.
- * Pydantic также позволяет представить его как "Кодировку разницы во времени ISO 8601", <a href="https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers" class="external-link" target="_blank">см. документацию для получения дополнительной информации</a>.
+ * Pydantic также позволяет представить его как "Кодировку разницы во времени ISO 8601", [см. документацию для получения дополнительной информации](https://docs.pydantic.dev/latest/concepts/serialization/#custom-serializers).
* `frozenset`:
* В запросах и ответах обрабатывается так же, как и `set`:
* В запросах будет прочитан список, исключены дубликаты и преобразован в `set`.
* `Decimal`:
* Встроенный в Python `Decimal`.
* В запросах и ответах обрабатывается так же, как и `float`.
-* Вы можете проверить все допустимые типы данных Pydantic здесь: <a href="https://docs.pydantic.dev/latest/usage/types/types/" class="external-link" target="_blank">Типы данных Pydantic</a>.
+* Вы можете проверить все допустимые типы данных Pydantic здесь: [Типы данных Pydantic](https://docs.pydantic.dev/latest/usage/types/types/).
## Пример { #example }
Никогда не храните пароли пользователей в чистом виде. Всегда храните "безопасный хэш", который вы затем сможете проверить.
-Если вам это не знакомо, вы можете узнать про "хэш пароля" в [главах о безопасности](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
+Если вам это не знакомо, вы можете узнать про "хэш пароля" в [главах о безопасности](security/simple-oauth2.md#password-hashing).
///
Он будет определён в OpenAPI как `anyOf`.
-Для этого используйте стандартную аннотацию типов в Python <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>:
+Для этого используйте стандартную аннотацию типов в Python [`typing.Union`](https://docs.python.org/3/library/typing.html#typing.Union):
/// note | Примечание
-При объявлении <a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a> сначала указывайте наиболее специфичный тип, затем менее специфичный. В примере ниже более специфичный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
+При объявлении [`Union`](https://docs.pydantic.dev/latest/concepts/types/#unions) сначала указывайте наиболее специфичный тип, затем менее специфичный. В примере ниже более специфичный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
///
<div class="termy">
```console
-$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+$ <font color="#4E9A06">fastapi</font> dev
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
### Проверьте { #check-it }
-Откройте браузер по адресу: <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
+Откройте браузер по адресу: [http://127.0.0.1:8000](http://127.0.0.1:8000).
Вы увидите JSON-ответ вида:
### Интерактивная документация API { #interactive-api-docs }
-Теперь перейдите по адресу: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Теперь перейдите по адресу: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
-Вы увидите автоматически сгенерированную интерактивную документацию по API (предоставлено <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
+Вы увидите автоматически сгенерированную интерактивную документацию по API (предоставлено [Swagger UI](https://github.com/swagger-api/swagger-ui)):

### Альтернативная документация API { #alternative-api-docs }
-И теперь перейдите по адресу <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+И теперь перейдите по адресу [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
-Вы увидите альтернативную автоматически сгенерированную документацию (предоставлено <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
+Вы увидите альтернативную автоматически сгенерированную документацию (предоставлено [ReDoc](https://github.com/Rebilly/ReDoc)):

#### «Схема» API { #api-schema }
-В данном случае <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> — это спецификация, которая определяет, как описывать схему вашего API.
+В данном случае [OpenAPI](https://github.com/OAI/OpenAPI-Specification) — это спецификация, которая определяет, как описывать схему вашего API.
-Это определение схемы включает пути вашего API, возможные параметры, которые они принимают, и т. п.
+Это определение схемы включает пути вашего API, возможные параметры, которые они принимают, и т.п.
#### «Схема» данных { #data-schema }
Термин «схема» также может относиться к форме некоторых данных, например, к содержимому JSON.
-В таком случае это будут атрибуты JSON, их типы данных и т. п.
+В таком случае это будут атрибуты JSON, их типы данных и т.п.
#### OpenAPI и JSON Schema { #openapi-and-json-schema }
Если вам интересно, как выглядит исходная схема OpenAPI, FastAPI автоматически генерирует JSON (схему) с описанием всего вашего API.
-Вы можете посмотреть её напрямую по адресу: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
+Вы можете посмотреть её напрямую по адресу: [http://127.0.0.1:8000/openapi.json](http://127.0.0.1:8000/openapi.json).
Вы увидите JSON, начинающийся примерно так:
Вы также можете использовать её для автоматической генерации кода для клиентов, которые взаимодействуют с вашим API. Например, для фронтенд-, мобильных или IoT-приложений.
+### Настройте app `entrypoint` в `pyproject.toml` { #configure-the-app-entrypoint-in-pyproject-toml }
+
+Вы можете указать расположение вашего приложения в файле `pyproject.toml`, например:
+
+```toml
+[tool.fastapi]
+entrypoint = "main:app"
+```
+
+Этот `entrypoint` подскажет команде `fastapi`, что приложение нужно импортировать так:
+
+```python
+from main import app
+```
+
+Если структура вашего кода выглядит так:
+
+```
+.
+├── backend
+│ ├── main.py
+│ ├── __init__.py
+```
+
+Тогда следует указать такой `entrypoint`:
+
+```toml
+[tool.fastapi]
+entrypoint = "backend.main:app"
+```
+
+что будет эквивалентно:
+
+```python
+from backend.main import app
+```
+
+### `fastapi dev` с путём { #fastapi-dev-with-path }
+
+Вы также можете передать путь к файлу в команду `fastapi dev`, и она попытается определить объект приложения FastAPI для использования:
+
+```console
+$ fastapi dev main.py
+```
+
+Но в этом случае вам придётся каждый раз помнить о передаче корректного пути при вызове команды `fastapi`.
+
+Кроме того, другие инструменты могут его не найти, например [Расширение VS Code](../editor-support.md) или [FastAPI Cloud](https://fastapicloud.com), поэтому рекомендуется использовать `entrypoint` в `pyproject.toml`.
+
### Разверните приложение (необязательно) { #deploy-your-app-optional }
-При желании вы можете развернуть своё приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, перейдите и присоединитесь к списку ожидания, если ещё не сделали этого. 🚀
+При желании вы можете развернуть своё приложение FastAPI в [FastAPI Cloud](https://fastapicloud.com), перейдите и присоединитесь к списку ожидания, если ещё не сделали этого. 🚀
Если у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉), вы можете развернуть приложение одной командой.
`FastAPI` — это класс, который напрямую наследуется от `Starlette`.
-Вы можете использовать весь функционал <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> и в `FastAPI`.
+Вы можете использовать весь функционал [Starlette](https://www.starlette.dev/) и в `FastAPI`.
///
/// note | Примечание
-Если вы не знаете, в чём разница, посмотрите [Асинхронность: *"Нет времени?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+Если вы не знаете, в чём разница, посмотрите [Асинхронность: *"Нет времени?"*](../async.md#in-a-hurry).
///
Также можно вернуть модели Pydantic (подробнее об этом позже).
-Многие другие объекты и модели будут автоматически преобразованы в JSON (включая ORM и т. п.). Попробуйте использовать те, что вам привычнее, с высокой вероятностью они уже поддерживаются.
+Многие другие объекты и модели будут автоматически преобразованы в JSON (включая ORM и т.п.). Попробуйте использовать те, что вам привычнее, с высокой вероятностью они уже поддерживаются.
### Шаг 6: разверните приложение { #step-6-deploy-it }
-Разверните приложение в **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** одной командой: `fastapi deploy`. 🎉
+Разверните приложение в **[FastAPI Cloud](https://fastapicloud.com)** одной командой: `fastapi deploy`. 🎉
#### О FastAPI Cloud { #about-fastapi-cloud }
-**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, что и **FastAPI**.
+**[FastAPI Cloud](https://fastapicloud.com)** создан тем же автором и командой, что и **FastAPI**.
Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API с минимальными усилиями.
## Установка пользовательских обработчиков исключений { #install-custom-exception-handlers }
-Вы можете добавить пользовательские обработчики исключений с помощью <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">тех же утилит обработки исключений из Starlette</a>.
+Вы можете добавить пользовательские обработчики исключений с помощью [тех же утилит обработки исключений из Starlette](https://www.starlette.dev/exceptions/).
Допустим, у вас есть пользовательское исключение `UnicornException`, которое вы (или используемая вами библиотека) можете `вызвать`.
Все блоки кода можно копировать и использовать напрямую (это действительно протестированные файлы Python).
-Чтобы запустить любой из примеров, скопируйте код в файл `main.py` и запустите `fastapi dev` с:
+Чтобы запустить любой из примеров, скопируйте код в файл `main.py` и запустите `fastapi dev`:
<div class="termy">
```console
-$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+$ <font color="#4E9A06">fastapi</font> dev
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
Первый шаг — установить FastAPI.
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, и затем **установите FastAPI**:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, и затем **установите FastAPI**:
<div class="termy">
/// note | Примечание
-При установке с помощью `pip install "fastapi[standard]"` добавляются некоторые стандартные необязательные зависимости по умолчанию, включая `fastapi-cloud-cli`, который позволяет развернуть приложение на <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
+При установке с помощью `pip install "fastapi[standard]"` добавляются некоторые стандартные необязательные зависимости по умолчанию, включая `fastapi-cloud-cli`, который позволяет развернуть приложение на [FastAPI Cloud](https://fastapicloud.com).
Если вы не хотите иметь эти необязательные зависимости, установите просто `pip install fastapi`.
///
+/// tip | Совет
+
+У FastAPI есть [официальное расширение для VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (и Cursor), которое предоставляет множество функций, включая обзор операций пути, поиск операций пути, навигацию CodeLens в тестах (переход к определению из тестов), а также развертывание в FastAPI Cloud и просмотр логов - всё прямо из вашего редактора кода.
+
+///
+
## Продвинутое руководство пользователя { #advanced-user-guide }
Существует также **Продвинутое руководство пользователя**, которое вы сможете прочитать после **Учебник - Руководство пользователя**.
| `version` | `string` | Версия API. Версия вашего собственного приложения, а не OpenAPI. К примеру `2.5.0`. |
| `terms_of_service` | `str` | Ссылка к условиям пользования API. Если указано, то это должен быть URL-адрес. |
| `contact` | `dict` | Контактная информация для открытого API. Может содержать несколько полей. <details><summary>поля <code>contact</code></summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Описание</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Идентификационное имя контактного лица/организации.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL указывающий на контактную информацию. ДОЛЖЕН быть в формате URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Email адрес контактного лица/организации. ДОЛЖЕН быть в формате email адреса.</td></tr></tbody></table></details> |
-| `license_info` | `dict` | Информация о лицензии открытого API. Может содержать несколько полей. <details><summary>поля <code>license_info</code></summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Описание</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ОБЯЗАТЕЛЬНО</strong> (если установлен параметр <code>license_info</code>). Название лицензии, используемой для API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Выражение лицензии <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> для API. Поле <code>identifier</code> взаимоисключающее с полем <code>url</code>. <small>Доступно начиная с OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL, указывающий на лицензию, используемую для API. ДОЛЖЕН быть в формате URL.</td></tr></tbody></table></details> |
+| `license_info` | `dict` | Информация о лицензии открытого API. Может содержать несколько полей. <details><summary>поля <code>license_info</code></summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Описание</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ОБЯЗАТЕЛЬНО</strong> (если установлен параметр <code>license_info</code>). Название лицензии, используемой для API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Выражение лицензии [SPDX](https://spdx.org/licenses/) для API. Поле <code>identifier</code> взаимоисключающее с полем <code>url</code>. <small>Доступно начиная с OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL, указывающий на лицензию, используемую для API. ДОЛЖЕН быть в формате URL.</td></tr></tbody></table></details> |
Вы можете задать их следующим образом:
/// info | Дополнительная информация
-Узнайте больше о тегах в [Конфигурации операции пути](path-operation-configuration.md#tags){.internal-link target=_blank}.
+Узнайте больше о тегах в [Конфигурации операции пути](path-operation-configuration.md#tags).
///
Если у вас есть зависимости с `yield`, то код выхода (код после `yield`) будет выполняться *после* middleware.
-Если были какие‑либо фоновые задачи (рассматриваются в разделе [Фоновые задачи](background-tasks.md){.internal-link target=_blank}, вы увидите это позже), они будут запущены *после* всех middleware.
+Если были какие‑либо фоновые задачи (рассматриваются в разделе [Фоновые задачи](background-tasks.md), вы увидите это позже), они будут запущены *после* всех middleware.
///
/// tip | Совет
-Имейте в виду, что можно добавлять проприетарные HTTP-заголовки <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">с префиксом `X-`</a>.
+Имейте в виду, что можно добавлять проприетарные HTTP-заголовки [с префиксом `X-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).
-Но если вы хотите, чтобы клиент в браузере мог видеть ваши пользовательские заголовки, необходимо добавить их в настройки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}), используя параметр `expose_headers`, описанный в <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">документации по CORS Starlette</a>.
+Но если вы хотите, чтобы клиент в браузере мог видеть ваши пользовательские заголовки, необходимо добавить их в настройки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md)), используя параметр `expose_headers`, описанный в [документации по CORS Starlette](https://www.starlette.dev/middleware/#corsmiddleware).
///
/// tip | Совет
-Мы используем <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> вместо `time.time()` для обеспечения большей точности в таких случаях. 🤓
+Мы используем [`time.perf_counter()`](https://docs.python.org/3/library/time.html#time.perf_counter) вместо `time.time()` для обеспечения большей точности в таких случаях. 🤓
///
## Другие middleware { #other-middlewares }
-О других middleware вы можете узнать больше в разделе [Advanced User Guide: Advanced Middleware](../advanced/middleware.md){.internal-link target=_blank}.
+О других middleware вы можете узнать больше в разделе [Расширенное руководство пользователя: Продвинутое middleware](../advanced/middleware.md).
В следующем разделе вы можете прочитать, как настроить <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> с помощью middleware.
Вы можете передать только `int`-значение кода, например `404`.
-Но если вы не помните, для чего нужен каждый числовой код, вы можете использовать сокращенные константы в параметре `status`:
+Но если вы не помните, для чего нужен каждый числовой код, вы можете использовать сокращенные константы в `status`:
{* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *}
Так как описания обычно длинные и содержат много строк, вы можете объявить описание *операции пути* в <dfn title="многострочная строка, первое выражение внутри функции (не присвоенное какой-либо переменной), используемая для документации">строке документации</dfn> функции, и **FastAPI** прочитает её оттуда.
-Вы можете использовать <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> в строке документации, и он будет интерпретирован и отображён корректно (с учетом отступа в строке документации).
+Вы можете использовать [Markdown](https://en.wikipedia.org/wiki/Markdown) в строке документации, и он будет интерпретирован и отображён корректно (с учетом отступа в строке документации).
{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
Если вы используете более старую версию, вы столкнётесь с ошибками при попытке использовать `Annotated`.
-Убедитесь, что вы [обновили версию FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} как минимум до 0.95.1 перед тем, как использовать `Annotated`.
+Убедитесь, что вы [обновили версию FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions) как минимум до 0.95.1 перед тем, как использовать `Annotated`.
///
Валидация также применима к значениям типа `float`.
-В этом случае становится важной возможность добавить ограничение <abbr title="greater than – больше чем"><code>gt</code></abbr>, вместо <abbr title="greater than or equal – больше или равно"><code>ge</code></abbr>, поскольку в таком случае вы можете, например, создать ограничение, чтобы значение было больше `0`, даже если оно меньше `1`.
+В этом случае становится важной возможность добавить ограничение <abbr title="greater than - больше чем"><code>gt</code></abbr>, вместо <abbr title="greater than or equal - больше или равно"><code>ge</code></abbr>, поскольку в таком случае вы можете, например, создать ограничение, чтобы значение было больше `0`, даже если оно меньше `1`.
Таким образом, `0.5` будет корректным значением. А `0.0` или `0` — нет.
-То же самое справедливо и для <abbr title="less than – меньше чем"><code>lt</code></abbr>.
+То же самое справедливо и для <abbr title="less than - меньше чем"><code>lt</code></abbr>.
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
## Резюме { #recap }
-С помощью `Query`, `Path` (и других классов, которые мы пока не затронули) вы можете добавлять метаданные и строковую валидацию тем же способом, как и в главе [Query-параметры и валидация строк](query-params-str-validations.md){.internal-link target=_blank}.
+С помощью `Query`, `Path` (и других классов, которые мы пока не затронули) вы можете добавлять метаданные и строковую валидацию тем же способом, как и в главе [Query-параметры и валидация строк](query-params-str-validations.md).
А также вы можете добавить валидацию числовых данных:
Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
-Если запустите этот пример и перейдёте по адресу: <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, то увидите ответ:
+Если запустите этот пример и перейдёте по адресу: [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo), то увидите ответ:
```JSON
{"item_id":"foo"}
## <dfn title="также известно как: сериализация, парсинг, маршаллинг">Преобразование</dfn> данных { #data-conversion }
-Если запустите этот пример и перейдёте по адресу: <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, то увидите ответ:
+Если запустите этот пример и перейдёте по адресу: [http://127.0.0.1:8000/items/3](http://127.0.0.1:8000/items/3), то увидите ответ:
```JSON
{"item_id":3}
## Валидация данных { #data-validation }
-Если откроете браузер по адресу <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, то увидите интересную HTTP-ошибку:
+Если откроете браузер по адресу [http://127.0.0.1:8000/items/foo](http://127.0.0.1:8000/items/foo), то увидите интересную HTTP-ошибку:
```JSON
{
из-за того, что параметр пути `item_id` имеет значение `"foo"`, которое не является типом `int`.
-Та же ошибка возникнет, если вместо `int` передать `float`, например: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
+Та же ошибка возникнет, если вместо `int` передать `float`, например: [http://127.0.0.1:8000/items/4.2](http://127.0.0.1:8000/items/4.2)
/// check | Заметка
## Документация { #documentation }
-И теперь, когда откроете браузер по адресу: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, то увидите вот такую автоматически сгенерированную документацию API:
+И теперь, когда откроете браузер по адресу: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs), то увидите вот такую автоматически сгенерированную документацию API:
<img src="/img/tutorial/path-params/image01.png">
## Преимущества стандартизации, альтернативная документация { #standards-based-benefits-alternative-documentation }
-Поскольку сгенерированная схема соответствует стандарту <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a>, её можно использовать со множеством совместимых инструментов.
+Поскольку сгенерированная схема соответствует стандарту [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md), её можно использовать со множеством совместимых инструментов.
-Именно поэтому, **FastAPI** сам предоставляет альтернативную документацию API (используя ReDoc), которую можно получить по адресу: <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
+Именно поэтому, **FastAPI** сам предоставляет альтернативную документацию API (используя ReDoc), которую можно получить по адресу: [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc).
<img src="/img/tutorial/path-params/image02.png">
## Pydantic { #pydantic }
-Вся проверка данных выполняется под капотом с помощью <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>. Поэтому вы можете быть уверены в качестве обработки данных.
+Вся проверка данных выполняется под капотом с помощью [Pydantic](https://docs.pydantic.dev/), поэтому вы получаете все его преимущества. И вы можете быть уверены, что находитесь в надёжных руках.
Вы можете использовать в аннотациях как простые типы данных, вроде `str`, `float`, `bool`, так и более сложные типы.
## Предопределенные значения { #predefined-values }
-Что если нам нужно заранее определить допустимые *параметры пути*, которые *операция пути* может принимать? В таком случае можно использовать стандартное перечисление <abbr title="Enumeration">`Enum`</abbr> Python.
+Что если нам нужно заранее определить допустимые *параметры пути*, которые *операция пути* может принимать? В таком случае можно использовать стандартное перечисление <abbr title="Enumeration - Перечисление">`Enum`</abbr> Python.
### Создание класса `Enum` { #create-an-enum-class }
Если у вас более старая версия, при попытке использовать `Annotated` вы получите ошибки.
-Убедитесь, что вы [обновили версию FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} как минимум до 0.95.1 перед использованием `Annotated`.
+Убедитесь, что вы [обновили версию FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions) как минимум до 0.95.1 перед использованием `Annotated`.
///
## Использовать `Annotated` в типе для параметра `q` { #use-annotated-in-the-type-for-the-q-parameter }
-Помните, я уже говорил, что `Annotated` можно использовать для добавления метаданных к параметрам в разделе [Введение в типы Python](../python-types.md#type-hints-with-metadata-annotations){.internal-link target=_blank}?
+Помните, я уже говорил, что `Annotated` можно использовать для добавления метаданных к параметрам в разделе [Введение в типы Python](../python-types.md#type-hints-with-metadata-annotations)?
Пришло время использовать его с FastAPI. 🚀
Если вы не используете `Annotated`, а применяете **(устаревший) стиль со значением по умолчанию**, то при вызове этой функции без FastAPI в **других местах** вам нужно **помнить** о том, что надо передать аргументы, чтобы всё работало корректно, иначе значения будут не такими, как вы ожидаете (например, вместо `str` будет `QueryInfo` или что-то подобное). И ни редактор, ни Python не будут ругаться при самом вызове функции — ошибка проявится лишь при операциях внутри.
-Так как `Annotated` может содержать больше одной аннотации метаданных, теперь вы можете использовать ту же функцию и с другими инструментами, например с <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">Typer</a>. 🚀
+Так как `Annotated` может содержать больше одной аннотации метаданных, теперь вы можете использовать ту же функцию и с другими инструментами, например с [Typer](https://typer.tiangolo.com/). 🚀
## Больше валидаций { #add-more-validations }
В таких случаях можно использовать **кастомную функцию-валидатор**, которая применяется после обычной валидации (например, после проверки, что значение — это `str`).
-Этого можно добиться, используя <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">`AfterValidator` Pydantic</a> внутри `Annotated`.
+Этого можно добиться, используя [`AfterValidator` Pydantic](https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator) внутри `Annotated`.
/// tip | Совет
-В Pydantic также есть <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> и другие. 🤓
+В Pydantic также есть [`BeforeValidator`](https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator) и другие. 🤓
///
/// tip | Совет
-Если вам нужна валидация, требующая общения с каким‑либо **внешним компонентом** — базой данных или другим API — вместо этого используйте **Зависимости FastAPI** (FastAPI Dependencies), вы познакомитесь с ними позже.
+Если вам нужна валидация, требующая общения с каким‑либо **внешним компонентом** — базой данных или другим API — вместо этого используйте **Зависимости FastAPI**, вы познакомитесь с ними позже.
Эти кастомные валидаторы предназначены для проверок, которые можно выполнить, имея **только** те же **данные**, что пришли в запросе.
/// tip | Подсказка
-Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#predefined-values){.internal-link target=_blank}.
+Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#predefined-values).
///
/// info | Дополнительная информация
-Чтобы получать загруженные файлы, сначала установите <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Чтобы получать загруженные файлы, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установили пакет, например:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
```console
$ pip install python-multipart
* Файл, хранящийся в памяти до максимального предела размера, после преодоления которого он будет храниться на диске.
* Это означает, что он будет хорошо работать с большими файлами, такими как изображения, видео, большие бинарные файлы и т.д., не потребляя при этом всю память.
* Из загруженного файла можно получить метаданные.
-* Он реализует <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> `async` интерфейс.
-* Он предоставляет реальный объект Python <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> который вы можете передать непосредственно другим библиотекам, которые ожидают файл в качестве объекта.
+* Он реализует [file-like](https://docs.python.org/3/glossary.html#term-file-like-object) `async` интерфейс.
+* Он предоставляет реальный объект Python [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile), который вы можете передать непосредственно другим библиотекам, которые ожидают файл в качестве объекта.
### `UploadFile` { #uploadfile }
* `filename`: Строка `str` с исходным именем файла, который был загружен (например, `myimage.jpg`).
* `content_type`: Строка `str` с типом содержимого (MIME type / media type) (например, `image/jpeg`).
-* `file`: <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a> (a <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> объект). Это фактический файл Python, который можно передавать непосредственно другим функциям или библиотекам, ожидающим файл в качестве объекта.
+* `file`: [`SpooledTemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile) (a [file-like](https://docs.python.org/3/glossary.html#term-file-like-object) объект). Это фактический файл Python, который можно передавать непосредственно другим функциям или библиотекам, ожидающим файл в качестве объекта.
`UploadFile` имеет следующие методы `async`. Все они вызывают соответствующие файловые методы (используя внутренний `SpooledTemporaryFile`).
Данные из форм обычно кодируются с использованием "media type" `application/x-www-form-urlencoded` когда он не включает файлы.
-Но когда форма включает файлы, она кодируется как multipart/form-data. Если вы используете `File`, **FastAPI** будет знать, что ему нужно получить файлы из нужной части тела.
+Но когда форма включает файлы, она кодируется как `multipart/form-data`. Если вы используете `File`, **FastAPI** будет знать, что ему нужно получить файлы из нужной части тела.
-Если вы хотите узнать больше об этих кодировках и полях форм, перейдите по ссылке <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> web docs for <code>POST</code></a>.
+Если вы хотите узнать больше об этих кодировках и полях форм, перейдите по ссылке [<abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> web docs for `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
///
/// info | Дополнительная информация
-Чтобы использовать формы, сначала установите <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Чтобы использовать формы, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
-Убедитесь, что вы создали и активировали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, а затем установите пакет, например:
+Убедитесь, что вы создали и активировали [виртуальное окружение](../virtual-environments.md), а затем установите пакет, например:
```console
$ pip install python-multipart
/// info | Информация
-Чтобы получать загруженные файлы и/или данные форм, сначала установите <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Чтобы получать загруженные файлы и/или данные форм, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установили пакет, например:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
```console
$ pip install python-multipart
/// info | Дополнительная информация
-Чтобы использовать формы, сначала установите <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
+Чтобы использовать формы, сначала установите [`python-multipart`](https://github.com/Kludex/python-multipart).
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установили пакет, например:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
```console
$ pip install python-multipart
Но когда форма содержит файлы, она кодируется как `multipart/form-data`. О работе с файлами вы прочтёте в следующей главе.
-Если вы хотите узнать больше про эти кодировки и поля формы, обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> веб-документации для `POST`</a>.
+Если вы хотите узнать больше про эти кодировки и поля формы, обратитесь к [<abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> веб-документации для `POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST).
///
* Добавить **JSON Schema** для ответа в OpenAPI *операции пути*.
* Это будет использовано **автоматической документацией**.
* Это также будет использовано инструментами автоматической генерации клиентского кода.
+* **Сериализовать** возвращаемые данные в JSON с помощью Pydantic, который написан на **Rust**, поэтому это будет **намного быстрее**.
Но самое главное:
/// info | Информация
-Чтобы использовать `EmailStr`, сначала установите <a href="https://github.com/JoshData/python-email-validator" class="external-link" target="_blank">`email-validator`</a>.
+Чтобы использовать `EmailStr`, сначала установите [`email-validator`](https://github.com/JoshData/python-email-validator).
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установите пакет, например:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установите пакет, например:
```console
$ pip install email-validator
### Возврат Response напрямую { #return-a-response-directly }
-Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах документации для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}.
+Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах документации для продвинутых](../advanced/response-directly.md).
{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
Но когда вы возвращаете произвольный объект, не являющийся валидным типом Pydantic (например, объект базы данных), и аннотируете его таким образом в функции, FastAPI попытается создать модель ответа Pydantic из этой аннотации типа и потерпит неудачу.
-То же произойдёт, если у вас будет что-то вроде <dfn title="Объединение нескольких типов означает «любой из этих типов».">union</dfn> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
+То же произойдёт, если у вас будет что-то вроде <dfn title="Объединение нескольких типов означает «любой из этих типов».">объединение</dfn> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
* `response_model_exclude_defaults=True`
* `response_model_exclude_none=True`
-как описано в <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">документации Pydantic</a> для `exclude_defaults` и `exclude_none`.
+как описано в [документации Pydantic](https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict) для `exclude_defaults` и `exclude_none`.
///
/// info | Информация
-В качестве значения параметра `status_code` также может использоваться `IntEnum`, например, из библиотеки <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a> в Python.
+В качестве значения параметра `status_code` также может использоваться `IntEnum`, например, из библиотеки [`http.HTTPStatus`](https://docs.python.org/3/library/http.html#http.HTTPStatus) в Python.
///
/// tip | Подсказка
-Чтобы узнать больше о HTTP кодах статуса и о том, для чего каждый из них предназначен, ознакомьтесь с <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> документацией об HTTP статус-кодах</a>.
+Чтобы узнать больше о HTTP кодах статуса и о том, для чего каждый из них предназначен, ознакомьтесь с [<abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> документацией об HTTP статус-кодах](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).
///
## Изменение кода статуса по умолчанию { #changing-the-default }
-Позже, в [Руководстве для продвинутых пользователей](../advanced/response-change-status-code.md){.internal-link target=_blank}, вы узнаете, как возвращать HTTP статус-код, отличный от значения по умолчанию, которое вы объявляете здесь.
+Позже, в [Руководстве для продвинутых пользователей](../advanced/response-change-status-code.md), вы узнаете, как возвращать HTTP статус-код, отличный от значения по умолчанию, которое вы объявляете здесь.
Эта дополнительная информация будет добавлена как есть в выходную **JSON Schema** этой модели и будет использоваться в документации API.
-Вы можете использовать атрибут `model_config`, который принимает `dict`, как описано в <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Документации Pydantic: Конфигурация</a>.
+Вы можете использовать атрибут `model_config`, который принимает `dict`, как описано в [Документация Pydantic: Конфигурация](https://docs.pydantic.dev/latest/api/config/).
Вы можете задать `"json_schema_extra"` с `dict`, содержащим любые дополнительные данные, которые вы хотите видеть в сгенерированной JSON Schema, включая `examples`.
OpenAPI также добавила поля `example` и `examples` в другие части спецификации:
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object" class="external-link" target="_blank">`Parameter Object` (в спецификации)</a>, которое использовалось в FastAPI:
+* [`Parameter Object` (в спецификации)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object), которое использовалось в FastAPI:
* `Path()`
* `Query()`
* `Header()`
* `Cookie()`
-* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object" class="external-link" target="_blank">`Request Body Object`, в поле `content`, в `Media Type Object` (в спецификации)</a>, которое использовалось в FastAPI:
+* [`Request Body Object`, в поле `content`, в `Media Type Object` (в спецификации)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object), которое использовалось в FastAPI:
* `Body()`
* `File()`
* `Form()`
### Поле `examples` в JSON Schema { #json-schemas-examples-field }
-Позже в новой версии спецификации JSON Schema было добавлено поле <a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a>.
+Позже в новой версии спецификации JSON Schema было добавлено поле [`examples`](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5).
А затем новый OpenAPI 3.1.0 был основан на последней версии (JSON Schema 2020-12), которая включала это новое поле `examples`.
/// info | Дополнительная информация
-Пакет <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> автоматически устанавливается вместе с **FastAPI**, если вы запускаете команду `pip install "fastapi[standard]"`.
+Пакет [`python-multipart`](https://github.com/Kludex/python-multipart) автоматически устанавливается вместе с **FastAPI**, если вы запускаете команду `pip install "fastapi[standard]"`.
Однако, если вы используете команду `pip install fastapi`, пакет `python-multipart` по умолчанию не включается.
-Чтобы установить его вручную, убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md){.internal-link target=_blank}, активировали его и затем установили пакет:
+Чтобы установить его вручную, убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md), активировали его и затем установили пакет:
```console
$ pip install python-multipart
<div class="termy">
```console
-$ fastapi dev main.py
+$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
## Проверка { #check-it }
-Перейдите к интерактивной документации по адресу: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Перейдите к интерактивной документации по адресу: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Вы увидите примерно следующее:
Поскольку мы используем относительный URL, если ваш API расположен по адресу `https://example.com/`, то он будет ссылаться на `https://example.com/token`. А если ваш API расположен по адресу `https://example.com/api/v1/`, то он будет ссылаться на `https://example.com/api/v1/token`.
-Использование относительного URL важно для того, чтобы ваше приложение продолжало работать даже в таком продвинутом случае, как [За прокси-сервером](../../advanced/behind-a-proxy.md){.internal-link target=_blank}.
+Использование относительного URL важно для того, чтобы ваше приложение продолжало работать даже в таком продвинутом случае, как [За прокси-сервером](../../advanced/behind-a-proxy.md).
///
Через неделю срок действия токена истечет, пользователь не будет авторизован и ему придется заново входить в систему, чтобы получить новый токен. А если пользователь (или третье лицо) попытается модифицировать токен, чтобы изменить срок действия, вы сможете это обнаружить, поскольку подписи не будут совпадать.
-Если вы хотите поиграть с JWT-токенами и посмотреть, как они работают, посмотрите <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a>.
+Если вы хотите поиграть с JWT-токенами и посмотреть, как они работают, посмотрите [https://jwt.io](https://jwt.io/).
## Установка `PyJWT` { #install-pyjwt }
Нам необходимо установить `pyjwt` для генерации и проверки JWT-токенов на языке Python.
-Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md){.internal-link target=_blank}, активируйте его, а затем установите `pyjwt`:
+Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md), активируйте его, а затем установите `pyjwt`:
<div class="termy">
Если вы планируете использовать алгоритмы цифровой подписи, такие как RSA или ECDSA, вам следует установить зависимость библиотеки криптографии `pyjwt[crypto]`.
-Подробнее об этом можно прочитать в <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">документации по установке PyJWT</a>.
+Подробнее об этом можно прочитать в [документации по установке PyJWT](https://pyjwt.readthedocs.io/en/latest/installation.html).
///
Рекомендуемый алгоритм — "Argon2".
-Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md){.internal-link target=_blank}, активируйте его, и затем установите pwdlib вместе с Argon2:
+Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md), активируйте его, и затем установите pwdlib вместе с Argon2:
<div class="termy">
## Проверка в действии { #check-it }
-Запустите сервер и перейдите к документации: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Запустите сервер и перейдите к документации: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
Вы увидите пользовательский интерфейс вида:
```
/// info | Дополнительная информация
-Более полное объяснение `**user_dict` можно найти в [документации к **Дополнительным моделям**](../extra-models.md#about-user-in-dict){.internal-link target=_blank}.
+Более полное объяснение `**user_dict` можно найти в [документации к **Дополнительным моделям**](../extra-models.md#about-user-in-dict).
///
## Возврат токена { #return-the-token }
## Посмотрим, как это работает { #see-it-in-action }
-Откройте интерактивную документацию: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
+Откройте интерактивную документацию: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).
### Аутентификация { #authenticate }
--- /dev/null
+# События, отправляемые сервером (SSE) { #server-sent-events-sse }
+
+Вы можете передавать данные потоком клиенту, используя Server-Sent Events (SSE).
+
+Это похоже на [Стриминг JSON Lines](stream-json-lines.md), но использует формат `text/event-stream`, который нативно поддерживается браузерами через [`EventSource` API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).
+
+/// info | Информация
+
+Добавлено в FastAPI 0.135.0.
+
+///
+
+## Что такое Server-Sent Events? { #what-are-server-sent-events }
+
+SSE — это стандарт для потоковой передачи данных с сервера на клиента по HTTP.
+
+Каждое событие — это небольшой текстовый блок с «полями», такими как `data`, `event`, `id` и `retry`, разделёнными пустыми строками.
+
+Это выглядит так:
+
+```
+data: {"name": "Portal Gun", "price": 999.99}
+
+data: {"name": "Plumbus", "price": 32.99}
+
+```
+
+SSE часто используют для стриминга ответов ИИ в чатах, живых уведомлений, логов и наблюдаемости, а также в других случаях, когда сервер «проталкивает» обновления клиенту.
+
+/// tip | Совет
+
+Если вам нужно стримить бинарные данные, например видео или аудио, посмотрите расширенное руководство: [Stream Data](../advanced/stream-data.md).
+
+///
+
+## Стриминг SSE с FastAPI { #stream-sse-with-fastapi }
+
+Чтобы стримить SSE с FastAPI, используйте `yield` в своей функции-обработчике пути и укажите `response_class=EventSourceResponse`.
+
+Импортируйте `EventSourceResponse` из `fastapi.sse`:
+
+{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[4,22] *}
+
+Каждый возвращаемый через `yield` элемент кодируется как JSON и отправляется в поле `data:` события SSE.
+
+Если вы объявите тип возврата как `AsyncIterable[Item]`, FastAPI будет использовать его, чтобы выполнить **валидацию**, добавить **документацию** и **сериализовать** данные с помощью Pydantic.
+
+{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[1:25] hl[10:12,23] *}
+
+/// tip | Совет
+
+Так как Pydantic будет сериализовать это на стороне **Rust**, вы получите значительно более высокую **производительность**, чем если не объявите тип возврата.
+
+///
+
+### Несинхронные функции-обработчики пути { #non-async-path-operation-functions }
+
+Вы также можете использовать обычные функции `def` (без `async`) и применять `yield` тем же образом.
+
+FastAPI проследит, чтобы выполнение прошло корректно и не блокировало цикл событий.
+
+Так как в этом случае функция не async, правильным типом возврата будет `Iterable[Item]`:
+
+{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[28:31] hl[29] *}
+
+### Без объявленного типа возврата { #no-return-type }
+
+Вы также можете опустить тип возврата. FastAPI использует [`jsonable_encoder`](./encoder.md) для преобразования данных и их отправки.
+
+{* ../../docs_src/server_sent_events/tutorial001_py310.py ln[34:37] hl[35] *}
+
+## `ServerSentEvent` { #serversentevent }
+
+Если вам нужно задать поля SSE, такие как `event`, `id`, `retry` или `comment`, вы можете возвращать через `yield` объекты `ServerSentEvent` вместо обычных данных.
+
+Импортируйте `ServerSentEvent` из `fastapi.sse`:
+
+{* ../../docs_src/server_sent_events/tutorial002_py310.py hl[4,26] *}
+
+Поле `data` всегда кодируется как JSON. Вы можете передавать любое значение, сериализуемое в JSON, включая Pydantic-модели.
+
+## Необработанные данные { #raw-data }
+
+Если нужно отправлять данные без JSON-кодирования, используйте `raw_data` вместо `data`.
+
+Это полезно для отправки заранее отформатированного текста, строк логов или специальных значений <dfn title="Значение, используемое для обозначения особого условия или состояния">«сентинель»</dfn>, например `[DONE]`.
+
+{* ../../docs_src/server_sent_events/tutorial003_py310.py hl[17] *}
+
+/// note | Примечание
+
+`data` и `raw_data` взаимно исключают друг друга. В каждом `ServerSentEvent` можно задать только одно из них.
+
+///
+
+## Возобновление с `Last-Event-ID` { #resuming-with-last-event-id }
+
+Когда браузер переподключается после обрыва соединения, он отправляет последний полученный `id` в HTTP-заголовке `Last-Event-ID`.
+
+Вы можете прочитать его как параметр заголовка и использовать, чтобы возобновить поток с того места, где клиент остановился:
+
+{* ../../docs_src/server_sent_events/tutorial004_py310.py hl[25,27,31] *}
+
+## SSE с POST { #sse-with-post }
+
+SSE работает с любым HTTP-методом, не только с `GET`.
+
+Это полезно для таких протоколов, как [MCP](https://modelcontextprotocol.io), которые стримят SSE по `POST`:
+
+{* ../../docs_src/server_sent_events/tutorial005_py310.py hl[14] *}
+
+## Технические детали { #technical-details }
+
+FastAPI из коробки реализует некоторые лучшие практики для SSE.
+
+- Отправлять комментарий «ping» для поддержания соединения («keep alive») каждые 15 секунд, когда нет сообщений, чтобы предотвратить закрытие соединения некоторыми прокси, как рекомендовано в [HTML specification: Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html#authoring-notes).
+- Устанавливать заголовок `Cache-Control: no-cache`, чтобы предотвратить кэширование потока.
+- Устанавливать специальный заголовок `X-Accel-Buffering: no`, чтобы предотвратить буферизацию в некоторых прокси, например Nginx.
+
+Вам не нужно ничего настраивать, это работает из коробки. 🤓
**FastAPI** не требует использовать SQL (реляционную) базу данных. Но вы можете использовать любую базу данных, которую хотите.
-Здесь мы рассмотрим пример с использованием <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel</a>.
+Здесь мы рассмотрим пример с использованием [SQLModel](https://sqlmodel.tiangolo.com/).
-**SQLModel** построен поверх <a href="https://www.sqlalchemy.org/" class="external-link" target="_blank">SQLAlchemy</a> и Pydantic. Его создал тот же автор, что и **FastAPI**, чтобы он идеально подходил для приложений FastAPI, которым нужны **SQL базы данных**.
+**SQLModel** построен поверх [SQLAlchemy](https://www.sqlalchemy.org/) и Pydantic. Его создал тот же автор, что и **FastAPI**, чтобы он идеально подходил для приложений FastAPI, которым нужны **SQL базы данных**.
/// tip | Подсказка
/// tip | Подсказка
-Существует официальный генератор проектов на **FastAPI** и **PostgreSQL**, включающий frontend и другие инструменты: <a href="https://github.com/fastapi/full-stack-fastapi-template" class="external-link" target="_blank">https://github.com/fastapi/full-stack-fastapi-template</a>
+Существует официальный генератор проектов на **FastAPI** и **PostgreSQL**, включающий frontend и другие инструменты: [https://github.com/fastapi/full-stack-fastapi-template](https://github.com/fastapi/full-stack-fastapi-template)
///
-Это очень простое и короткое руководство. Если вы хотите узнать больше о базах данных в целом, об SQL или о более продвинутых возможностях, обратитесь к <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">документации SQLModel</a>.
+Это очень простое и короткое руководство. Если вы хотите узнать больше о базах данных в целом, об SQL или о более продвинутых возможностях, обратитесь к [документации SQLModel](https://sqlmodel.tiangolo.com/).
## Установка `SQLModel` { #install-sqlmodel }
-Сначала убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его и затем установили `sqlmodel`:
+Сначала убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его и затем установили `sqlmodel`:
<div class="termy">
{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *}
-Класс `Hero` очень похож на модель Pydantic (фактически, под капотом, *это и есть модель Pydantic*).
+Класс `Hero` очень похож на модель Pydantic (фактически, под капотом, это и есть модель Pydantic).
Есть несколько отличий:
* `Field(primary_key=True)` сообщает SQLModel, что `id` — это **первичный ключ** в SQL базе данных (подробнее о первичных ключах SQL можно узнать в документации SQLModel).
- **Примечание:** Мы используем `int | None` для поля первичного ключа, чтобы в Python-коде можно было *создать объект без `id`* (`id=None`), предполагая, что база данных *сгенерирует его при сохранении*. SQLModel понимает, что база данных предоставит `id`, и *определяет столбец как `INTEGER` (не `NULL`)* в схеме базы данных. См. <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">документацию SQLModel о первичных ключах</a> для подробностей.
+ **Примечание:** Мы используем `int | None` для поля первичного ключа, чтобы в Python-коде можно было *создать объект без `id`* (`id=None`), предполагая, что база данных *сгенерирует его при сохранении*. SQLModel понимает, что база данных предоставит `id`, и *определяет столбец как `INTEGER` (не `NULL`)* в схеме базы данных. См. [документацию SQLModel о первичных ключах](https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id) для подробностей.
* `Field(index=True)` сообщает SQLModel, что нужно создать **SQL индекс** для этого столбца, что позволит быстрее выполнять выборки при чтении данных, отфильтрованных по этому столбцу.
Параметр `check_same_thread=False` позволяет FastAPI использовать одну и ту же базу данных SQLite в разных потоках. Это необходимо, так как **один запрос** может использовать **больше одного потока** (например, в зависимостях).
-Не волнуйтесь, с такой структурой кода мы позже обеспечим использование **одной *сессии* SQLModel на запрос**, по сути именно этого и добивается `check_same_thread`.
+Не волнуйтесь, с такой структурой кода мы позже обеспечим использование **одной сессии SQLModel на запрос**, по сути именно этого и добивается `check_same_thread`.
### Создание таблиц { #create-the-tables }
/// tip | Подсказка
-В SQLModel появятся утилиты миграций - обёртки над Alembic, но пока вы можете использовать <a href="https://alembic.sqlalchemy.org/en/latest/" class="external-link" target="_blank">Alembic</a> напрямую.
+В SQLModel появятся утилиты миграций — обёртки над Alembic, но пока вы можете использовать [Alembic](https://alembic.sqlalchemy.org/en/latest/) напрямую.
///
<div class="termy">
```console
-$ fastapi dev main.py
+$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
<div class="termy">
```console
-$ fastapi dev main.py
+$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
## Резюме { #recap }
-Вы можете использовать <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">**SQLModel**</a> для взаимодействия с SQL базой данных и упростить код с помощью *моделей данных* и *моделей-таблиц*.
+Вы можете использовать [**SQLModel**](https://sqlmodel.tiangolo.com/) для взаимодействия с SQL базой данных и упростить код с помощью *моделей данных* и *моделей-таблиц*.
-Гораздо больше вы можете узнать в документации **SQLModel**, там есть более подробное мини-<a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">руководство по использованию SQLModel с **FastAPI**</a>. 🚀
+Гораздо больше вы можете узнать в документации **SQLModel**, там есть более подробное мини-[руководство по использованию SQLModel с **FastAPI**](https://sqlmodel.tiangolo.com/tutorial/fastapi/). 🚀
Это отличается от использования `APIRouter`, так как примонтированное приложение является полностью независимым.
OpenAPI и документация из вашего главного приложения не будут содержать ничего из примонтированного приложения, и т.д.
-Вы можете прочитать больше об этом в [Расширенном руководстве пользователя](../advanced/index.md){.internal-link target=_blank}.
+Вы можете прочитать больше об этом в [Расширенном руководстве пользователя](../advanced/index.md).
## Детали { #details }
## Больше информации { #more-info }
-Для получения дополнительной информации о деталях и настройках ознакомьтесь с <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Документацией Starlette о статических файлах</a>.
+Для получения дополнительной информации о деталях и настройках ознакомьтесь с [документацией Starlette о статических файлах](https://www.starlette.dev/staticfiles/).
--- /dev/null
+# Стриминг JSON Lines { #stream-json-lines }
+
+У вас может быть последовательность данных, которую вы хотите отправлять в «**потоке**». Это можно сделать с помощью **JSON Lines**.
+
+/// info | Информация
+
+Добавлено в FastAPI 0.134.0.
+
+///
+
+## Что такое поток? { #what-is-a-stream }
+
+«**Стриминг**» данных означает, что ваше приложение начнет отправлять элементы данных клиенту, не дожидаясь готовности всей последовательности.
+
+То есть оно отправит первый элемент, клиент его получит и начнет обрабатывать, а вы в это время можете все еще генерировать следующий элемент.
+
+```mermaid
+sequenceDiagram
+ participant App
+ participant Client
+
+ App->>App: Produce Item 1
+ App->>Client: Send Item 1
+ App->>App: Produce Item 2
+ Client->>Client: Process Item 1
+ App->>Client: Send Item 2
+ App->>App: Produce Item 3
+ Client->>Client: Process Item 2
+ App->>Client: Send Item 3
+ Client->>Client: Process Item 3
+ Note over App: Keeps producing...
+ Note over Client: Keeps consuming...
+```
+
+Это может быть даже бесконечный поток, когда вы продолжаете отправлять данные.
+
+## JSON Lines { #json-lines }
+
+В таких случаях часто отправляют «**JSON Lines**», это формат, в котором отправляется по одному JSON-объекту на строку.
+
+Ответ будет иметь тип содержимого `application/jsonl` (вместо `application/json`), а тело ответа будет примерно таким:
+
+```json
+{"name": "Plumbus", "description": "A multi-purpose household device."}
+{"name": "Portal Gun", "description": "A portal opening device."}
+{"name": "Meeseeks Box", "description": "A box that summons a Meeseeks."}
+```
+
+Это очень похоже на JSON-массив (эквивалент списка Python), но вместо того чтобы быть обернутым в `[]` и иметь `,` между элементами, здесь **один JSON-объект на строку**, они разделены символом новой строки.
+
+/// info | Информация
+
+Важный момент в том, что ваше приложение сможет по очереди производить каждую строку, пока клиент потребляет предыдущие строки.
+
+///
+
+/// note | Технические детали
+
+Так как каждый JSON-объект будет разделен новой строкой, в их содержимом не могут быть буквальные символы новой строки, но могут быть экранированные переводы строк (`\n`), что входит в стандарт JSON.
+
+Однако обычно об этом не нужно беспокоиться — всё делается автоматически, читайте дальше. 🤓
+
+///
+
+## Варианты использования { #use-cases }
+
+Вы можете использовать это для стриминга данных из сервиса **AI LLM**, из **логов** или **телеметрии**, или из других типов данных, которые можно структурировать в элементы **JSON**.
+
+/// tip | Совет
+
+Если вы хотите стримить бинарные данные, например видео или аудио, посмотрите расширенное руководство: [Потоковая передача данных](../advanced/stream-data.md).
+
+///
+
+## Стриминг JSON Lines с FastAPI { #stream-json-lines-with-fastapi }
+
+Чтобы стримить JSON Lines с FastAPI, вместо использования `return` в вашей *функции-обработчике пути* используйте `yield`, чтобы по очереди выдавать каждый элемент.
+
+{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[24] *}
+
+Если каждый JSON-элемент, который вы хотите отправить обратно, имеет тип `Item` (Pydantic-модель), и это асинхронная функция, вы можете объявить тип возвращаемого значения как `AsyncIterable[Item]`:
+
+{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[1:24] hl[9:11,22] *}
+
+Если вы объявите тип возвращаемого значения, FastAPI будет использовать его, чтобы **валидировать** данные, **документировать** их в OpenAPI, **фильтровать** и **сериализовать** с помощью Pydantic.
+
+/// tip | Совет
+
+Так как Pydantic будет сериализовывать это на стороне **Rust**, вы получите значительно более высокую **производительность**, чем если бы вы не указывали тип возвращаемого значения.
+
+///
+
+### Неасинхронные функции-обработчики пути { #non-async-path-operation-functions }
+
+Вы также можете использовать обычные функции `def` (без `async`) и использовать `yield` таким же образом.
+
+FastAPI обеспечит корректное выполнение так, чтобы это не блокировало цикл событий.
+
+Поскольку в этом случае функция не асинхронная, подходящим типом возвращаемого значения будет `Iterable[Item]`:
+
+{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[27:30] hl[28] *}
+
+### Без возвращаемого типа { #no-return-type }
+
+Вы также можете опустить тип возвращаемого значения. Тогда FastAPI использует [`jsonable_encoder`](./encoder.md), чтобы преобразовать данные к виду, который можно сериализовать в JSON, и затем отправит их как JSON Lines.
+
+{* ../../docs_src/stream_json_lines/tutorial001_py310.py ln[33:36] hl[34] *}
+
+## События, отправляемые сервером (SSE) { #server-sent-events-sse }
+
+FastAPI также имеет полноценную поддержку Server-Sent Events (SSE), которые довольно похожи, но с парой дополнительных деталей. Вы можете узнать о них в следующей главе: [События, отправляемые сервером (SSE)](server-sent-events.md). 🤓
# Тестирование { #testing }
-Благодаря <a href="https://www.starlette.dev/testclient/" class="external-link" target="_blank">Starlette</a>, тестировать приложения **FastAPI** легко и приятно.
+Благодаря [Starlette](https://www.starlette.dev/testclient/), тестировать приложения **FastAPI** легко и приятно.
-Тестирование основано на библиотеке <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>, которая в свою очередь основана на библиотеке Requests, так что все действия знакомы и интуитивно понятны.
+Тестирование основано на библиотеке [HTTPX](https://www.python-httpx.org), которая в свою очередь основана на библиотеке Requests, так что все действия знакомы и интуитивно понятны.
-Используя эти инструменты, Вы можете напрямую задействовать <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a> с **FastAPI**.
+Используя эти инструменты, Вы можете напрямую задействовать [pytest](https://docs.pytest.org/) с **FastAPI**.
## Использование класса `TestClient` { #using-testclient }
/// info | Информация
-Для использования класса `TestClient` сначала установите <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a>.
+Для использования класса `TestClient` сначала установите [`httpx`](https://www.python-httpx.org).
-Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установили пакет, например:
+Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
```console
$ pip install httpx
/// tip | Подсказка
-Если для тестирования Вам, помимо запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, для подключения к базе данных с помощью асинхронного драйвера), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md){.internal-link target=_blank} в расширенном руководстве.
+Если для тестирования Вам, помимо запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, для подключения к базе данных с помощью асинхронного драйвера), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md) в расширенном руководстве.
///
### Файл приложения **FastAPI** { #fastapi-app-file }
-Допустим, структура файлов Вашего приложения похожа на ту, что описана на странице [Более крупные приложения](bigger-applications.md){.internal-link target=_blank}:
+Допустим, структура файлов Вашего приложения похожа на ту, что описана на странице [Более крупные приложения](bigger-applications.md):
```
.
### Файл тестов { #testing-file }
-Также Ñ\83 Ð\92аÑ\81 можеÑ\82 бÑ\8bÑ\82Ñ\8c Ñ\84айл `test_main.py` Ñ\81одеÑ\80жаÑ\89ий Ñ\82еÑ\81Ñ\82Ñ\8b. Ð\9cожно Ñ\80азмеÑ\81Ñ\82иÑ\82Ñ\8c Ñ\82еÑ\81Ñ\82овÑ\8bй Ñ\84айл и Ñ\84айл пÑ\80иложениÑ\8f в одной диÑ\80екÑ\82оÑ\80ии (в диÑ\80екÑ\82оÑ\80иÑ\8fÑ\85 длÑ\8f Python-кода желаÑ\82елÑ\8cно Ñ\80азмеÑ\89аÑ\82Ñ\8c и Ñ\84айл `__init__.py`):
+Также Ñ\83 Ð\92аÑ\81 можеÑ\82 бÑ\8bÑ\82Ñ\8c Ñ\84айл `test_main.py` Ñ\81одеÑ\80жаÑ\89ий Ñ\82еÑ\81Ñ\82Ñ\8b. Ð\9eн можеÑ\82 наÑ\85одиÑ\82Ñ\8cÑ\81Ñ\8f в Ñ\82ом же Python-пакеÑ\82е (в Ñ\82ой же диÑ\80екÑ\82оÑ\80ии Ñ\81 Ñ\84айлом `__init__.py`):
``` hl_lines="5"
.
* Для передачи *HTTP-заголовков*, передайте объект `dict` через параметр `headers`.
* Для передачи *cookies* также передайте `dict`, но через параметр `cookies`.
-Для получения дополнительной информации о передаче данных на бэкенд с помощью `httpx` или `TestClient` ознакомьтесь с <a href="https://www.python-httpx.org" class="external-link" target="_blank">документацией HTTPX</a>.
+Для получения дополнительной информации о передаче данных на бэкенд с помощью `httpx` или `TestClient` ознакомьтесь с [документацией HTTPX](https://www.python-httpx.org).
/// info | Информация
Обратите внимание, что `TestClient` принимает данные, которые можно конвертировать в JSON, но не модели Pydantic.
-Если в Ваших тестах есть модели Pydantic и Вы хотите отправить их в тестируемое приложение, то можете использовать функцию `jsonable_encoder`, описанную на странице [Кодировщик совместимый с JSON](encoder.md){.internal-link target=_blank}.
+Если в Ваших тестах есть модели Pydantic и Вы хотите отправить их в тестируемое приложение, то можете использовать функцию `jsonable_encoder`, описанную на странице [Кодировщик совместимый с JSON](encoder.md).
///
Далее Вам нужно установить `pytest`.
-Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установили пакет, например:
+Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
<div class="termy">
На этой странице вы узнаете, как пользоваться **виртуальными окружениями** и как они работают.
-Если вы готовы начать использовать **инструмент, который управляет всем** за вас (включая установку Python), попробуйте <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+Если вы готовы начать использовать **инструмент, который управляет всем** за вас (включая установку Python), попробуйте [uv](https://github.com/astral-sh/uv).
///
//// tab | `uv`
-Если у вас установлен <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>, вы можете использовать его для создания виртуального окружения.
+Если у вас установлен [`uv`](https://github.com/astral-sh/uv), вы можете использовать его для создания виртуального окружения.
<div class="termy">
//// tab | Windows Bash
-Или если вы используете Bash для Windows (например, <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
+Или если вы используете Bash для Windows (например, [Git Bash](https://gitforwindows.org/)):
<div class="termy">
/// tip | Подсказка
-Если вы используете <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>, то для установки вы будете использовать его вместо `pip`, поэтому обновлять `pip` не нужно. 😎
+Если вы используете [`uv`](https://github.com/astral-sh/uv), то для установки вы будете использовать его вместо `pip`, поэтому обновлять `pip` не нужно. 😎
///
/// tip | Подсказка
-Если вы использовали <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> для создания виртуального окружения, он уже сделал это за вас — можно пропустить этот шаг. 😎
+Если вы использовали [`uv`](https://github.com/astral-sh/uv) для создания виртуального окружения, он уже сделал это за вас — можно пропустить этот шаг. 😎
///
//// tab | `uv`
-Если у вас установлен <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
+Если у вас установлен [`uv`](https://github.com/astral-sh/uv):
<div class="termy">
//// tab | `uv`
-Если у вас установлен <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
+Если у вас установлен [`uv`](https://github.com/astral-sh/uv):
<div class="termy">
Например:
-* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a>
-* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a>
+* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
+* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
/// tip | Подсказка
## Зачем нужны виртуальные окружения { #why-virtual-environments }
-Чтобы работать с FastAPI, вам нужно установить <a href="https://www.python.org/" class="external-link" target="_blank">Python</a>.
+Чтобы работать с FastAPI, вам нужно установить [Python](https://www.python.org/).
После этого вам нужно будет **установить** FastAPI и другие **пакеты**, которые вы хотите использовать.
</div>
-Будет загружен сжатый файл с кодом FastAPI, обычно с <a href="https://pypi.org/project/fastapi/" class="external-link" target="_blank">PyPI</a>.
+Будет загружен сжатый файл с кодом FastAPI, обычно с [PyPI](https://pypi.org/project/fastapi/).
Также будут **загружены** файлы для других пакетов, от которых зависит FastAPI.
//// tab | Windows Bash
-Или если вы используете Bash для Windows (например, <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
+Или если вы используете Bash для Windows (например, [Git Bash](https://gitforwindows.org/)):
<div class="termy">
////
-Эта команда создаст или изменит некоторые [переменные окружения](environment-variables.md){.internal-link target=_blank}, которые будут доступны для следующих команд.
+Эта команда создаст или изменит некоторые [переменные окружения](environment-variables.md), которые будут доступны для следующих команд.
Одна из таких переменных — `PATH`.
/// tip | Подсказка
-Вы можете узнать больше о переменной окружения `PATH` в разделе [Переменные окружения](environment-variables.md#path-environment-variable){.internal-link target=_blank}.
+Вы можете узнать больше о переменной окружения `PATH` в разделе [Переменные окружения](environment-variables.md#path-environment-variable).
///
Существует много **альтернатив** для управления виртуальными окружениями, зависимостями (requirements), проектами.
-Когда вы будете готовы и захотите использовать инструмент для **управления всем проектом** — зависимостями пакетов, виртуальными окружениями и т. п., я бы предложил попробовать <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+Когда вы будете готовы и захотите использовать инструмент для **управления всем проектом** — зависимостями пакетов, виртуальными окружениями и т.п., я бы предложил попробовать [uv](https://github.com/astral-sh/uv).
`uv` может многое: