]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Update translations for ru (update-and-add) (#15152)
authorSebastián Ramírez <tiangolo@gmail.com>
Thu, 19 Mar 2026 17:56:20 +0000 (18:56 +0100)
committerGitHub <noreply@github.com>
Thu, 19 Mar 2026 17:56:20 +0000 (18:56 +0100)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
104 files changed:
docs/ru/docs/_llm-test.md
docs/ru/docs/advanced/additional-responses.md
docs/ru/docs/advanced/additional-status-codes.md
docs/ru/docs/advanced/advanced-dependencies.md
docs/ru/docs/advanced/async-tests.md
docs/ru/docs/advanced/behind-a-proxy.md
docs/ru/docs/advanced/custom-response.md
docs/ru/docs/advanced/dataclasses.md
docs/ru/docs/advanced/events.md
docs/ru/docs/advanced/generate-clients.md
docs/ru/docs/advanced/index.md
docs/ru/docs/advanced/json-base64-bytes.md [new file with mode: 0644]
docs/ru/docs/advanced/middleware.md
docs/ru/docs/advanced/openapi-callbacks.md
docs/ru/docs/advanced/openapi-webhooks.md
docs/ru/docs/advanced/path-operation-advanced-configuration.md
docs/ru/docs/advanced/response-change-status-code.md
docs/ru/docs/advanced/response-cookies.md
docs/ru/docs/advanced/response-directly.md
docs/ru/docs/advanced/response-headers.md
docs/ru/docs/advanced/security/http-basic-auth.md
docs/ru/docs/advanced/security/index.md
docs/ru/docs/advanced/security/oauth2-scopes.md
docs/ru/docs/advanced/settings.md
docs/ru/docs/advanced/stream-data.md [new file with mode: 0644]
docs/ru/docs/advanced/strict-content-type.md [new file with mode: 0644]
docs/ru/docs/advanced/sub-applications.md
docs/ru/docs/advanced/templates.md
docs/ru/docs/advanced/testing-websockets.md
docs/ru/docs/advanced/using-request-directly.md
docs/ru/docs/advanced/websockets.md
docs/ru/docs/advanced/wsgi.md
docs/ru/docs/alternatives.md
docs/ru/docs/async.md
docs/ru/docs/benchmarks.md
docs/ru/docs/deployment/cloud.md
docs/ru/docs/deployment/concepts.md
docs/ru/docs/deployment/docker.md
docs/ru/docs/deployment/fastapicloud.md
docs/ru/docs/deployment/https.md
docs/ru/docs/deployment/index.md
docs/ru/docs/deployment/manually.md
docs/ru/docs/deployment/server-workers.md
docs/ru/docs/deployment/versions.md
docs/ru/docs/editor-support.md [new file with mode: 0644]
docs/ru/docs/environment-variables.md
docs/ru/docs/fastapi-cli.md
docs/ru/docs/features.md
docs/ru/docs/help-fastapi.md
docs/ru/docs/history-design-future.md
docs/ru/docs/how-to/authentication-error-status-code.md
docs/ru/docs/how-to/conditional-openapi.md
docs/ru/docs/how-to/configure-swagger-ui.md
docs/ru/docs/how-to/custom-docs-ui-assets.md
docs/ru/docs/how-to/custom-request-and-route.md
docs/ru/docs/how-to/extending-openapi.md
docs/ru/docs/how-to/general.md
docs/ru/docs/how-to/graphql.md
docs/ru/docs/how-to/index.md
docs/ru/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
docs/ru/docs/how-to/testing-database.md
docs/ru/docs/index.md
docs/ru/docs/project-generation.md
docs/ru/docs/python-types.md
docs/ru/docs/tutorial/background-tasks.md
docs/ru/docs/tutorial/bigger-applications.md
docs/ru/docs/tutorial/body-nested-models.md
docs/ru/docs/tutorial/body-updates.md
docs/ru/docs/tutorial/body.md
docs/ru/docs/tutorial/cors.md
docs/ru/docs/tutorial/debugging.md
docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
docs/ru/docs/tutorial/dependencies/global-dependencies.md
docs/ru/docs/tutorial/dependencies/index.md
docs/ru/docs/tutorial/encoder.md
docs/ru/docs/tutorial/extra-data-types.md
docs/ru/docs/tutorial/extra-models.md
docs/ru/docs/tutorial/first-steps.md
docs/ru/docs/tutorial/handling-errors.md
docs/ru/docs/tutorial/index.md
docs/ru/docs/tutorial/metadata.md
docs/ru/docs/tutorial/middleware.md
docs/ru/docs/tutorial/path-operation-configuration.md
docs/ru/docs/tutorial/path-params-numeric-validations.md
docs/ru/docs/tutorial/path-params.md
docs/ru/docs/tutorial/query-params-str-validations.md
docs/ru/docs/tutorial/query-params.md
docs/ru/docs/tutorial/request-files.md
docs/ru/docs/tutorial/request-form-models.md
docs/ru/docs/tutorial/request-forms-and-files.md
docs/ru/docs/tutorial/request-forms.md
docs/ru/docs/tutorial/response-model.md
docs/ru/docs/tutorial/response-status-code.md
docs/ru/docs/tutorial/schema-extra-example.md
docs/ru/docs/tutorial/security/first-steps.md
docs/ru/docs/tutorial/security/oauth2-jwt.md
docs/ru/docs/tutorial/security/simple-oauth2.md
docs/ru/docs/tutorial/server-sent-events.md [new file with mode: 0644]
docs/ru/docs/tutorial/sql-databases.md
docs/ru/docs/tutorial/static-files.md
docs/ru/docs/tutorial/stream-json-lines.md [new file with mode: 0644]
docs/ru/docs/tutorial/testing.md
docs/ru/docs/virtual-environments.md

index 247d3a964f37f6dbbbfc4f890d599e100d1052b8..dbb1a2b7fe9152ca450cc9bde25548670a0f9c56 100644 (file)
@@ -11,7 +11,7 @@
 * Проверьте, всё ли в порядке в переводе.
 * При необходимости улучшите ваш языковой специфичный промпт, общий промпт или английский документ.
 * Затем вручную исправьте оставшиеся проблемы в переводе, чтобы он был хорошим.
-* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт настолько хороши, насколько это возможно (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">LLM — недетерминированные алгоритмы</a>).
+* Переведите заново, имея хороший перевод на месте. Идеальным результатом будет ситуация, когда LLM больше не вносит изменений в перевод. Это означает, что общий промпт и ваш языковой специфичный промпт настолько хороши, насколько это возможно (иногда он будет делать несколько, казалось бы, случайных изменений, причина в том, что [LLM — недетерминированные алгоритмы](https://doublespeak.chat/#/handbook#deterministic-output)).
 
 Тесты:
 
@@ -169,15 +169,15 @@ works(foo="bar")  # Это работает 🎉
 Текст ссылок должен переводиться, адрес ссылки не должен изменяться:
 
 * [Ссылка на заголовок выше](#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/)
 
 ////
 
@@ -294,7 +294,7 @@ works(foo="bar")  # Это работает 🎉
 * чувствительный к регистру
 * нечувствительный к регистру
 
-* обслуживать приложение
+* отдавать приложение
 * отдавать страницу
 
 * приложение
index ca36ba20e336c238a0a74e92dee119d9f392271b..f7e8d9dec07b25cad62ec28974ca7ca20958d649 100644 (file)
@@ -243,5 +243,5 @@ new_dict = {**old_dict, "new key": "new value"}
 
 Чтобы увидеть, что именно можно включать в ответы, посмотрите эти разделы спецификации 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`.
index 7c73cf5d5d51d7ab82679794527a7fca6311f9f1..aec66a13ff191553e414e85d5c826a0cb3c3d1f4 100644 (file)
@@ -38,4 +38,4 @@
 
 Если вы возвращаете дополнительные статус-коды и ответы напрямую, они не будут включены в схему OpenAPI (документацию API), потому что у FastAPI нет способа заранее знать, что вы собираетесь вернуть.
 
-Но вы можете задокументировать это в своём коде, используя: [Дополнительные ответы](additional-responses.md){.internal-link target=_blank}.
+Но вы можете задокументировать это в своём коде, используя: [Дополнительные ответы](additional-responses.md).
index 686a0cf91e21f337875f89caed1f69daf86d04df..fe37a79c1f08b3545c6f2f969d6d7de364a71378 100644 (file)
@@ -48,7 +48,7 @@
 checker(q="somequery")
 ```
 
-…и передаст возвращённое значение как значение зависимости в параметр `fixed_content_included` нашей *функции-обработчика пути*:
+…и передаст возвращённое значение как значение зависимости в параметр `fixed_content_included` нашей *функции-обработчику пути*:
 
 {* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
 
@@ -132,7 +132,7 @@ checker(q="somequery")
 
 Так сессия освободит подключение к базе данных, и другие запросы смогут его использовать.
 
-Если у вас есть другой сценарий, где нужно раннее завершение зависимости с `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`, я рассмотрю добавление нового способа опционально включать раннее закрытие.
 
@@ -144,7 +144,7 @@ checker(q="somequery")
 
 ### Фоновые задачи и зависимости с `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` выполнялся после завершения фоновых задач.
 
index 52939c25596febd87678e434744837993428ae20..1c0b888cc9eab9dc9386f16786fbd5f63d9938ab 100644 (file)
 
 Чтобы работать с асинхронным 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):
 
 ```
 .
@@ -84,7 +84,7 @@ response = client.get('/')
 
 /// 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).
 
 ///
 
@@ -94,6 +94,6 @@ response = client.get('/')
 
 /// 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.
 
 ///
index ec75ed369889e94718d8064764cf503c28ff72b4..4f212868ad6734b2a97cff82471a5af153498807 100644 (file)
@@ -16,9 +16,9 @@
 
 Заголовки прокси:
 
-* <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)
 
 ///
 
@@ -60,7 +60,7 @@ https://mysuperapp.com/items/
 
 /// tip | Совет
 
-Если хотите узнать больше об HTTPS, смотрите руководство [О HTTPS](../deployment/https.md){.internal-link target=_blank}.
+Если хотите узнать больше об HTTPS, смотрите руководство [О HTTPS](../deployment/https.md).
 
 ///
 
@@ -228,7 +228,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Учтите, что сервер (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
 {
@@ -251,9 +251,9 @@ Uvicorn ожидает, что прокси обратится к нему по
 
 ## Локальное тестирование с 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` со следующим содержимым:
 
@@ -330,7 +330,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 ### Проверьте ответы { #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
 {
@@ -345,7 +345,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 ///
 
-А теперь откройте 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).
 
 Мы получим тот же ответ:
 
@@ -370,13 +370,13 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 «Официальный» способ доступа к приложению — через прокси с заданным префиксом пути. Поэтому, как и ожидается, если открыть интерфейс документации, отдаваемый напрямую 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">
 
@@ -433,7 +433,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 ///
 
-В интерфейсе документации по адресу <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">
 
@@ -461,6 +461,6 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 ## Монтирование вложенного приложения { #mounting-a-sub-application }
 
-Если вам нужно смонтировать вложенное приложение (как описано в [Вложенные приложения — монтирование](sub-applications.md){.internal-link target=_blank}), и при этом вы используете прокси с `root_path`, делайте это обычным образом — всё будет работать, как ожидается.
+Если вам нужно смонтировать вложенное приложение (как описано в [Вложенные приложения — монтирование](sub-applications.md)), и при этом вы используете прокси с `root_path`, делайте это обычным образом — всё будет работать, как ожидается.
 
 FastAPI умно использует `root_path` внутри, так что всё просто работает. ✨
index b9f91373da21fba5180e642bbef6345954b3cb06..fdfe2c5498828dc9c3b1d47bd47bfd189bbee5a6 100644 (file)
@@ -1,52 +1,36 @@
 # Кастомные ответы — 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 }
 
@@ -69,7 +53,7 @@
 
 ### Вернуть `Response` { #return-a-response }
 
-Как показано в разделе [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}, вы также можете переопределить ответ прямо в своей операции пути, просто вернув его.
+Как показано в разделе [Вернуть Response напрямую](response-directly.md), вы также можете переопределить ответ прямо в своей операции пути, просто вернув его.
 
 Тот же пример сверху, возвращающий `HTMLResponse`, может выглядеть так:
 
@@ -154,37 +138,11 @@ FastAPI (фактически Starlette) автоматически добави
 
 Это ответ по умолчанию, используемый в **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.
 
 ///
 
@@ -214,31 +172,25 @@ FastAPI (фактически Starlette) автоматически добави
 
 ### `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).
 
 ///
 
@@ -267,7 +219,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 Вы можете создать собственный класс ответа, унаследовавшись от `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`.
 
@@ -291,13 +243,21 @@ FastAPI (фактически Starlette) автоматически добави
 
 Разумеется, вы наверняка найдёте гораздо более полезные способы воспользоваться этим, чем просто форматирование 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] *}
 
@@ -309,4 +269,4 @@ FastAPI (фактически Starlette) автоматически добави
 
 ## Дополнительная документация { #additional-documentation }
 
-Вы также можете объявить тип содержимого и многие другие детали в OpenAPI с помощью `responses`: [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Вы также можете объявить тип содержимого и многие другие детали в OpenAPI с помощью `responses`: [Дополнительные ответы в OpenAPI](additional-responses.md).
index 87a5763c105f1412b871f90eb914d31082f4f71f..f9f8689b049485fec58ae7e046545213c1babfe9 100644 (file)
@@ -2,11 +2,11 @@
 
 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.
 
@@ -74,7 +74,7 @@ FastAPI построен поверх **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 (хотя могла бы), а список словарей с внутренними данными.
 
@@ -88,7 +88,7 @@ FastAPI построен поверх **Pydantic**, и я показывал в
 
 Вы также можете комбинировать `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 }
 
index bcb5b000a4106a991413f426f963e9934420b503..464bba93e97a763f3be26c07628bdcb9842d9e3a 100644 (file)
@@ -150,11 +150,11 @@ async with lifespan(app):
 
 Немного технических подробностей для любопытных умников. 🤓
 
-Под капотом, в 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, которое можно использовать в других частях вашего кода.
 
@@ -162,4 +162,4 @@ async with lifespan(app):
 
 ## Подприложения { #sub-applications }
 
-🚨 Имейте в виду, что эти события lifespan (startup и shutdown) будут выполнены только для основного приложения, а не для [Подприложения — Mounts](sub-applications.md){.internal-link target=_blank}.
+🚨 Имейте в виду, что эти события lifespan (startup и shutdown) будут выполнены только для основного приложения, а не для [Подприложения — Mounts](sub-applications.md).
index 4eb098a88fab4922293980446351b1d9e23445ff..75bd7c47c413af04805ed158bf99f07dec9929bc 100644 (file)
@@ -8,11 +8,11 @@
 
 ## Генераторы 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 | Совет
 
@@ -24,15 +24,15 @@ FastAPI автоматически генерирует спецификации
 
 В этом разделе представлены решения с **венчурной поддержкой** и **поддержкой компаний** от компаний, которые спонсируют 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 доступны и их можно найти онлайн. 🤓
 
@@ -66,11 +66,11 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
 
 Это сгенерирует 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">
 
index c0a52c6c14a83464aa6a52813f21ace1d8928eb3..6cb92dd0049582257acc8b5efe030a4beebd1bff 100644 (file)
@@ -2,7 +2,7 @@
 
 ## Дополнительные возможности { #additional-features }
 
-Основное [Учебник - Руководство пользователя](../tutorial/index.md){.internal-link target=_blank} должно быть достаточно, чтобы познакомить вас со всеми основными функциями **FastAPI**.
+Основное [Учебник - Руководство пользователя](../tutorial/index.md) должно быть достаточно, чтобы познакомить вас со всеми основными функциями **FastAPI**.
 
 В следующих разделах вы увидите другие варианты, конфигурации и дополнительные возможности.
 
@@ -16,6 +16,6 @@
 
 ## Сначала прочитайте Учебник - Руководство пользователя { #read-the-tutorial-first }
 
-Вы все еще можете использовать большинство функций **FastAPI** со знаниями из [Учебник - Руководство пользователя](../tutorial/index.md){.internal-link target=_blank}.
+Вы все еще можете использовать большинство функций **FastAPI** со знаниями из [Учебник - Руководство пользователя](../tutorial/index.md).
 
 И следующие разделы предполагают, что вы уже прочитали его, и предполагают, что вы знаете эти основные идеи.
diff --git a/docs/ru/docs/advanced/json-base64-bytes.md b/docs/ru/docs/advanced/json-base64-bytes.md
new file mode 100644 (file)
index 0000000..390dd17
--- /dev/null
@@ -0,0 +1,63 @@
+# 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] *}
index 1f1a160604c1087b4ce3a9d6088f3653cb219726..805866499ca2544b05644a4422980e67a1056a72 100644 (file)
@@ -1,8 +1,8 @@
 # Расширенное использование 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.
 
@@ -91,7 +91,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
 
 Например:
 
-- <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).
index de7e283017639f25f2d714ca2b0310ea8d357a02..3d791de2c680abd93ea208d7988c2d21c6dc0986 100644 (file)
@@ -35,7 +35,7 @@
 
 /// 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/).
 
 ///
 
@@ -66,7 +66,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
 
 Сам обратный вызов — это всего лишь 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/).
 
 ///
 
@@ -106,11 +106,11 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
 Есть 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`:
 
@@ -179,7 +179,7 @@ https://www.external.org/events/invoices/2expen51ve
 
 ### Проверьте документацию { #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*:
 
index b477075c113b74bd423fbfeb9ef2821735abdd26..9b1988ff31a52a46aeb50c761145aefae0643ddc 100644 (file)
@@ -10,7 +10,7 @@
 
 Обычно процесс таков: вы определяете в своем коде, какое сообщение вы будете отправлять, то есть тело запроса.
 
-Вы также определяете, в какие моменты (при каких событиях) ваше приложение будет отправлять эти запросы.
+Вы также определяете, в какие моменты (при каких событиях) ваше приложение будет отправлять эти запросы (события).
 
 А ваши пользователи каким-то образом (например, в веб‑панели) указывают URL-адрес, на который ваше приложение должно отправлять эти запросы.
 
@@ -48,7 +48,7 @@
 
 ### Посмотрите документацию { #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).
 
 Вы увидите, что в документации есть обычные операции пути, а также появились вебхуки:
 
index b8c879bf6f31bdeca5a66072fef17b86581713c4..fe2996362b7da811cccf957cbf2ef52c537425db 100644 (file)
@@ -60,7 +60,7 @@
 
 Также можно объявлять дополнительные ответы с их моделями, статус-кодами и т.д.
 
-В документации есть целая глава об этом — [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+В документации есть целая глава об этом — [Дополнительные ответы в OpenAPI](additional-responses.md).
 
 ## Дополнительные данные OpenAPI { #openapi-extra }
 
@@ -68,7 +68,7 @@
 
 /// 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).
 
 ///
 
@@ -82,7 +82,7 @@
 
 Это низкоуровневая возможность расширения.
 
-Если вам нужно лишь объявить дополнительные ответы, удобнее сделать это через [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}.
+Если вам нужно лишь объявить дополнительные ответы, удобнее сделать это через [Дополнительные ответы в OpenAPI](additional-responses.md).
 
 ///
 
index 273862bae92af0fbf0702a2107e5d4f5220a5273..3dd0c9446ec871eeb74e0d623f052f1ade8557d1 100644 (file)
@@ -1,6 +1,6 @@
 # Response - Изменение статус-кода { #response-change-status-code }
 
-Вы, вероятно, уже читали о том, что можно установить [статус-код ответа по умолчанию](../tutorial/response-status-code.md){.internal-link target=_blank}.
+Вы, вероятно, уже читали о том, что можно установить [статус-код ответа по умолчанию](../tutorial/response-status-code.md).
 
 Но в некоторых случаях нужно вернуть другой статус-код, отличный от значения по умолчанию.
 
index d3662ef8eddfeae1e08144c4db038ba87eb56e69..2adc1af85ac486b256f1e6b3d36a2381ca98c129 100644 (file)
@@ -20,7 +20,7 @@
 
 Вы также можете установить Cookies, если возвращаете `Response` напрямую в вашем коде.
 
-Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md){.internal-link target=_blank}.
+Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md).
 
 Затем установите cookies и верните этот объект:
 
@@ -48,4 +48,4 @@
 
 ///
 
-Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с <a href="https://www.starlette.dev/responses/#set-cookie" class="external-link" target="_blank">документацией Starlette</a>.
+Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с [документацией Starlette](https://www.starlette.dev/responses/#set-cookie).
index 60facdd8570175669ed567305d4741f7d0089605..fcb8d533db5470db4994187a93b088c8d845127a 100644 (file)
@@ -2,19 +2,23 @@
 
 Когда вы создаёте **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`.
 
@@ -26,6 +30,8 @@
 
 Это даёт вам большую гибкость. Вы можете возвращать любые типы данных, переопределять любые объявления или валидацию данных и т.д.
 
+Это также накладывает на вас ответственность. Вам нужно удостовериться, что возвращаемые данные корректны, в правильном формате, что их можно сериализовать и т.д.
+
 ## Использование `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`, при этом сохраняя автоматическое преобразование данных, документацию и т.д.
index dc821983bcf1bb0e5685d8f1e9826c37fe573e67..806b89e1f859ebf91b66505baff5b6171933504e 100644 (file)
@@ -20,7 +20,7 @@
 
 Вы также можете добавить HTTP-заголовки, когда возвращаете `Response` напрямую.
 
-Создайте ответ, как описано в [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}, и передайте заголовки как дополнительный параметр:
+Создайте ответ, как описано в [Вернуть Response напрямую](response-directly.md), и передайте заголовки как дополнительный параметр:
 
 {* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
 
@@ -36,6 +36,6 @@
 
 ## Пользовательские 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).
index a6bfb7c54615892cd37fa07be6580dab4c0d5009..b094fec7730deb3f474031713c00e93e28caa2f1 100644 (file)
@@ -32,7 +32,7 @@
 
 Используйте зависимость, чтобы проверить, корректны ли имя пользователя и пароль.
 
-Для этого используйте стандартный модуль 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`.
 
index 912e4812a5f6acabceec75984e23c95d6502934e..89a7236d81ee391282761a311f0a86e9d6fa29bd 100644 (file)
@@ -2,11 +2,11 @@
 
 ## Дополнительные возможности { #additional-features }
 
-Есть дополнительные возможности для работы с безопасностью помимо тех, что описаны в [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md){.internal-link target=_blank}.
+Есть дополнительные возможности для работы с безопасностью помимо тех, что описаны в [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md).
 
 /// tip | Совет
 
-Следующие разделы **не обязательно являются «продвинутыми»**.
+Следующие разделы не обязательно являются «продвинутыми».
 
 И возможно, что решение для вашего варианта использования находится в одном из них.
 
@@ -14,6 +14,6 @@
 
 ## Сначала прочитайте руководство { #read-the-tutorial-first }
 
-В следующих разделах предполагается, что вы уже прочитали основной [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md){.internal-link target=_blank}.
+В следующих разделах предполагается, что вы уже прочитали основной [Учебник — Руководство пользователя: Безопасность](../../tutorial/security/index.md).
 
 Все они основаны на тех же концепциях, но предоставляют дополнительные возможности.
index 8788df1991ead517f1665931d6428715f3b9ba0c..944baeeeb6f2b11d056bab1b9fc7d895f3c20b33 100644 (file)
@@ -1,6 +1,6 @@
 # OAuth2 scopes { #oauth2-scopes }
 
-Вы можете использовать OAuth2 scopes (scope - область, рамки) напрямую с **FastAPI** — они интегрированы и работают бесшовно.
+Вы можете использовать OAuth2 scopes напрямую с **FastAPI** — они интегрированы и работают бесшовно.
 
 Это позволит вам иметь более детальную систему разрешений по стандарту OAuth2, интегрированную в ваше OpenAPI‑приложение (и документацию API).
 
@@ -60,7 +60,7 @@ OAuth2 со scopes — это механизм, который использу
 
 ## Взгляд издалека { #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] *}
 
@@ -267,8 +267,8 @@ OAuth2 со scopes — это механизм, который использу
 
 ///
 
-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`.
index 15537e2b40ad2b7f83e48daf4a1fca900e161085..3ae063340bf1596cca734bc9db9cfe6907be166d 100644 (file)
@@ -8,7 +8,7 @@
 
 /// 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">
 
@@ -100,7 +100,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 ## Настройки в другом модуле { #settings-in-another-module }
 
-Вы можете вынести эти настройки в другой модуль, как показано в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+Вы можете вынести эти настройки в другой модуль, как показано в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md).
 
 Например, у вас может быть файл `config.py` со следующим содержимым:
 
@@ -112,7 +112,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 /// tip | Совет
 
-Вам также понадобится файл `__init__.py`, как в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md){.internal-link target=_blank}.
+Вам также понадобится файл `__init__.py`, как в разделе [Большие приложения — несколько файлов](../tutorial/bigger-applications.md).
 
 ///
 
@@ -172,7 +172,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 ///
 
-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 | Совет
 
@@ -197,7 +197,7 @@ APP_NAME="ChimichangApp"
 
 /// 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/).
 
 ///
 
@@ -291,7 +291,7 @@ participant execute as Execute function
 
 Таким образом, она ведет себя почти как глобальная переменная. Но так как используется функция‑зависимость, мы можем легко переопределить ее для тестирования.
 
-`@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 }
 
diff --git a/docs/ru/docs/advanced/stream-data.md b/docs/ru/docs/advanced/stream-data.md
new file mode 100644 (file)
index 0000000..4c373db
--- /dev/null
@@ -0,0 +1,117 @@
+# Потоковая передача данных { #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] *}
diff --git a/docs/ru/docs/advanced/strict-content-type.md b/docs/ru/docs/advanced/strict-content-type.md
new file mode 100644 (file)
index 0000000..1a0cbbc
--- /dev/null
@@ -0,0 +1,88 @@
+# Строгая проверка 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.
+
+///
index 4fd5649ce3e4c95610944df47861ffcbd1c6322c..37257e0f3be15ee6b1f7019cd83c02ad1d971b76 100644 (file)
 
 ### Проверьте автоматическую документацию 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`:
 
@@ -64,4 +64,4 @@ $ fastapi dev main.py
 
 У подприложения также могут быть свои собственные смонтированные подприложения, и всё будет работать корректно, потому что FastAPI автоматически обрабатывает все эти `root_path`.
 
-Вы узнаете больше о `root_path` и о том, как использовать его явно, в разделе [За прокси](behind-a-proxy.md){.internal-link target=_blank}.
+Вы узнаете больше о `root_path` и о том, как использовать его явно, в разделе [За прокси](behind-a-proxy.md).
index 68adcb5151ce32625bc0dd43627e4408175fcdae..5fc938eec2e7fe632002f3c2fc4d3c1f275553d3 100644 (file)
@@ -8,7 +8,7 @@
 
 ## Установка зависимостей { #install-dependencies }
 
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его и установили `jinja2`:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его и установили `jinja2`:
 
 <div class="termy">
 
@@ -123,4 +123,4 @@ Item ID: 42
 
 ## Подробнее { #more-details }
 
-Больше подробностей, включая то, как тестировать шаблоны, смотрите в <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">документации Starlette по шаблонам</a>.
+Больше подробностей, включая то, как тестировать шаблоны, смотрите в [документации Starlette по шаблонам](https://www.starlette.dev/templates/).
index f6fa6a04bec27da4f10bb82b1c8ffc662eee9fed..6ab395f8f4b7352e51a13264839071f9676de5d7 100644 (file)
@@ -8,6 +8,6 @@
 
 /// 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).
 
 ///
index 0c091cdeda97d5be5ad239d8f2dce2878febf0fa..99074bf7b690acebf8a40c6ff7650f7cbaa8791e 100644 (file)
@@ -15,7 +15,7 @@
 
 ## Подробности об объекте `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.
 
@@ -45,7 +45,7 @@
 
 ## Документация по `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 | Технические детали
 
index d565d507bc75e82fea0fa2aab2507939c1df38ae..abfd789a48508adc6eb727c0bf08545818857a95 100644 (file)
@@ -1,10 +1,10 @@
 # Веб-сокеты { #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">
 
@@ -64,19 +64,19 @@ $ pip install websockets
 
 ## Проверка в действии { #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).
 
 Вы увидите следующую простенькую страницу:
 
@@ -115,25 +115,25 @@ $ fastapi dev main.py
 
 В веб-сокете вызывать `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).
 
 Там вы можете задать:
 
@@ -152,7 +152,7 @@ $ fastapi dev main.py
 
 ## Обработка отключений и работа с несколькими клиентами { #handling-disconnections-and-multiple-clients }
 
-Если веб-сокет соединение закрыто, то `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере:
+Если веб-сокет соединение закрыто, то `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере.
 
 {* ../../docs_src/websockets_/tutorial003_py310.py hl[79:81] *}
 
@@ -174,7 +174,7 @@ Client #1596980209979 left the chat
 
 Но имейте в виду, что это будет работать только в одном процессе и только пока он активен, так как всё обрабатывается в простом списке в оперативной памяти.
 
-Если нужно что-то легко интегрируемое с 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).
 
 ///
 
@@ -182,5 +182,5 @@ Client #1596980209979 left the chat
 
 Для более глубокого изучения темы воспользуйтесь документацией 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).
index aa630c228e92c86711106b488903ec0a1ff5ebbe..3ed85d0e9526e56921aad7641c6bfb1c858bebc2 100644 (file)
@@ -1,6 +1,6 @@
 # Подключение 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
 {
index 1f713c3f39b8a089a95bb8c357e5d003deb9bc64..13bac7f92b8e6496b2c78d8463572e7bbc1ad402 100644 (file)
@@ -14,7 +14,7 @@
 
 ## Предшествующие инструменты { #previous-tools }
 
-### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a> { #django }
+### [Django](https://www.djangoproject.com/) { #django }
 
 Это самый популярный Python-фреймворк, ему широко доверяют. Он используется для построения систем вроде Instagram.
 
@@ -22,7 +22,7 @@
 
 Он был создан для генерации 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.
 
@@ -42,7 +42,7 @@ Django REST Framework был создан Томом Кристи. Он же с
 
 ///
 
-### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a> { #flask }
+### [Flask](https://flask.palletsprojects.com) { #flask }
 
 Flask — это «микрофреймворк», он не включает интеграции с базами данных и многие другие вещи, которые в Django идут «из коробки».
 
@@ -64,7 +64,7 @@ Flask — это «микрофреймворк», он не включает и
 
 ///
 
-### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a> { #requests }
+### [Requests](https://requests.readthedocs.io) { #requests }
 
 **FastAPI** на самом деле не альтернатива **Requests**. Их области применения очень различны.
 
@@ -106,7 +106,7 @@ def read_url():
 
 ///
 
-### <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.
 
@@ -124,8 +124,8 @@ def read_url():
 
 И интегрировать основанные на стандартах инструменты пользовательского интерфейса:
 
-* <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**).
 
@@ -135,7 +135,7 @@ def read_url():
 
 Существует несколько 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` в строки и т. п.
 
@@ -153,7 +153,7 @@ def read_url():
 
 ///
 
-### <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-запросов.
 
@@ -175,7 +175,7 @@ Webargs был создан теми же разработчиками, что 
 
 ///
 
-### <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 предоставляют валидацию, парсинг и сериализацию как плагины.
 
@@ -205,7 +205,7 @@ APISpec был создан теми же разработчиками, что 
 
 ///
 
-### <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.
 
@@ -219,11 +219,11 @@ 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 | Информация
 
@@ -237,7 +237,7 @@ Flask-apispec был создан теми же разработчиками, ч
 
 ///
 
-### <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.
 
@@ -259,13 +259,13 @@ Flask-apispec был создан теми же разработчиками, ч
 
 ///
 
-### <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 в открытых бенчмарках.
 
@@ -279,7 +279,7 @@ Flask-apispec был создан теми же разработчиками, ч
 
 ///
 
-### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a> { #falcon }
+### [Falcon](https://falconframework.org/) { #falcon }
 
 Falcon — ещё один высокопроизводительный Python-фреймворк, он минималистичен и служит основой для других фреймворков, таких как Hug.
 
@@ -297,7 +297,7 @@ Falcon — ещё один высокопроизводительный Python-
 
 ///
 
-### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a> { #molten }
+### [Molten](https://moltenframework.com/) { #molten }
 
 Я обнаружил Molten на ранних этапах создания **FastAPI**. И у него были очень похожие идеи:
 
@@ -321,7 +321,7 @@ Falcon — ещё один высокопроизводительный Python-
 
 ///
 
-### <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. Это была отличная идея, которая вдохновила и другие инструменты.
 
@@ -337,7 +337,7 @@ Hug был одним из первых фреймворков, реализов
 
 /// 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.
 
 ///
 
@@ -351,7 +351,7 @@ Hug вдохновил **FastAPI** объявлять параметр `response
 
 ///
 
-### <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**. В нём было почти всё, что я искал, и отличный дизайн.
 
@@ -401,7 +401,7 @@ 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.
 
@@ -417,7 +417,7 @@ Pydantic — это библиотека для определения вали
 
 ///
 
-### <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‑сервисов.
 
@@ -462,7 +462,7 @@ ASGI — это новый «стандарт», разрабатываемый
 
 ///
 
-### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
+### [Uvicorn](https://www.uvicorn.dev/) { #uvicorn }
 
 Uvicorn — молниеносный ASGI-сервер, построенный на uvloop и httptools.
 
@@ -476,10 +476,10 @@ Uvicorn — молниеносный ASGI-сервер, построенный 
 
 Также вы можете использовать опцию командной строки `--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).
index bff32aaf49dffcb71aa5686370c9fa7fa6e15a40..7fd702184c37fb8c4431b04758ebbb30beb62b02 100644 (file)
@@ -12,7 +12,7 @@
 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('/')
@@ -29,7 +29,7 @@ async def read_results():
 
 ---
 
\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('/')
@@ -48,7 +48,7 @@ def results():
 
 ---
 
-**Ð\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 всё равно работает асинхронно и очень быстро.
 
@@ -141,7 +141,7 @@ def results():
 
 /// info | Информация
 
-Прекрасные иллюстрации от <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
+Прекрасные иллюстрации от [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
 
 ///
 
@@ -207,7 +207,7 @@ def results():
 
 /// info | Информация
 
-Прекрасные иллюстрации от <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
+Прекрасные иллюстрации от [Ketrina Thompson](https://www.instagram.com/ketrinadrawsalot). 🎨
 
 ///
 
@@ -251,7 +251,7 @@ def results():
 
 Того же уровня производительности вы получаете с **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 }
 
@@ -298,7 +298,7 @@ def results():
 
 Плюс к этому простой факт, что Python — основной язык для **Data Science**, Машинного обучения и особенно Глубокого обучения, делает FastAPI очень хорошим выбором для веб-API и приложений в области Data Science / Машинного обучения (среди многих других).
 
-Как добиться такого параллелизма в продакшн, см. раздел [Развёртывание](deployment/index.md){.internal-link target=_blank}.
+Как добиться такого параллелизма в продакшн, см. раздел [Развёртывание](deployment/index.md).
 
 ## `async` и `await` { #async-and-await }
 
@@ -363,13 +363,13 @@ async def read_burgers():
 
 ### Пишите свой асинхронный код { #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 }
 
@@ -381,7 +381,7 @@ Starlette (и **FastAPI**) основаны на <a href="https://anyio.readthed
 
 До этого работа с асинхронным кодом была заметно сложнее и труднее для понимания.
 
-В предыдущих версиях 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» (ад обратных вызовов).
 
@@ -419,15 +419,15 @@ Starlette (и **FastAPI**) основаны на <a href="https://anyio.readthed
 
 Если вы пришли из другого 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 }
 
index c8cacae5f3a0d6e444707e7522efa402eef7c252..671baba76ce78aabaac8a6bda8b77c30968c6a0a 100644 (file)
@@ -1,6 +1,6 @@
 # Бенчмарки (тесты производительности) { #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).
 
 Но при просмотре бенчмарков и сравнений следует иметь в виду следующее.
 
index 955db2a1578ac82c6a9faeae4706e4cbd26c81cb..cbd517e36e4b3aedd79f2513c6091e17897ce897 100644 (file)
@@ -6,7 +6,7 @@
 
 ## 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 с минимальными усилиями.
 
@@ -16,9 +16,9 @@ FastAPI Cloud — основной спонсор и источник финан
 
 ## Облачные провайдеры — спонсоры { #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)
index 173dbb962d4fe544f3708d6cb28108b2fc8e7245..900b842f9a4cbc543e70d0f06763dabede612d28 100644 (file)
@@ -25,7 +25,7 @@
 
 ## Безопасность — 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).
 
 ///
 
index 5dfa2115991df01a73345a2e260c3d3ab087973c..3b16d7798bdaa498e4539103aa4f36bac64c7206 100644 (file)
@@ -1,6 +1,6 @@
 # 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-контейнеров даёт ряд преимуществ: **безопасность**, **воспроизводимость**, **простоту** и другие.
 
@@ -60,16 +60,16 @@ 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), и т.д.
 
 Используя готовые образы, очень легко **комбинировать** разные инструменты и использовать их. Например, чтобы попробовать новую базу данных. В большинстве случаев можно воспользоваться **официальными образами** и просто настроить их через переменные окружения.
 
@@ -111,7 +111,7 @@ Docker — один из основных инструментов для соз
 
 Чаще всего используется файл `requirements.txt` с именами пакетов и их версиями по одному на строку.
 
-Разумеется, вы будете придерживаться тех же идей, что описаны здесь: [О версиях FastAPI](versions.md){.internal-link target=_blank}, чтобы задать диапазоны версий.
+Разумеется, вы будете придерживаться тех же идей, что описаны здесь: [О версиях FastAPI](versions.md), чтобы задать диапазоны версий.
 
 Например, ваш `requirements.txt` может выглядеть так:
 
@@ -238,7 +238,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
 
 #### Используйте `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**-форма:
 
@@ -254,11 +254,11 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80"]
 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 }
 
@@ -352,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
 
 ## Проверка { #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-хоста).
 
 Вы увидите что-то вроде:
 
@@ -362,17 +362,17 @@ $ docker run -d --name mycontainer -p 80:80 myimage
 
 ## Интерактивная документация 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)):
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
 ## Альтернативная документация 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)):
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
@@ -413,7 +413,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
 
 ## Концепции развертывания { #deployment-concepts }
 
-Ещё раз рассмотрим [концепции развертывания](concepts.md){.internal-link target=_blank} применительно к контейнерам.
+Ещё раз рассмотрим [концепции развертывания](concepts.md) применительно к контейнерам.
 
 Контейнеры главным образом упрощают **сборку и развёртывание** приложения, но не навязывают конкретный подход к этим **концепциям развертывания**, и существует несколько стратегий.
 
@@ -432,7 +432,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
 
 Если мы рассматриваем только **образ контейнера** для приложения FastAPI (и далее запущенный **контейнер**), то HTTPS обычно обрабатывается **внешним** инструментом.
 
-Это может быть другой контейнер, например с <a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>, который берёт на себя **HTTPS** и **автоматическое** получение **сертификатов**.
+Это может быть другой контейнер, например с [Traefik](https://traefik.io/), который берёт на себя **HTTPS** и **автоматическое** получение **сертификатов**.
 
 /// tip | Подсказка
 
@@ -558,7 +558,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
 
 /// 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/).
 
 ///
 
@@ -570,7 +570,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
 
 ### Базовый 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). Сейчас он помечен как устаревший. ⛔️
 
 Скорее всего, вам **не стоит** использовать этот базовый образ (или какой-либо аналогичный).
 
@@ -600,7 +600,7 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
 
 ## 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 }
 
@@ -615,4 +615,4 @@ CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
 
 В большинстве случаев вы, вероятно, не захотите использовать какой-либо базовый образ, а вместо этого **соберёте образ контейнера с нуля** на основе официального Docker-образа Python.
 
-Заботясь о **порядке**  инструкций в `Dockerfile`и используя **кэш Docker**, вы можете **минимизировать время сборки**, чтобы повысить продуктивность (и не скучать). 😎
+Заботясь о **порядке**  инструкций в `Dockerfile` и используя **кэш Docker**, вы можете **минимизировать время сборки**, чтобы повысить продуктивность (и не скучать). 😎
index 9e7430ecb07103d14073b315ad126b2c080858f5..95db3387f2a26665ae4a05588525cf155a4c848f 100644 (file)
@@ -1,6 +1,6 @@
 # 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 }
 
@@ -40,7 +40,7 @@ Deploying to FastAPI Cloud...
 
 ## О 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 с минимальными усилиями.
 
index ffeccfd7dabc841fd9fc6230295094624499118f..181cac0d89f66b55caf9fa5ea9a42c0f8f7827b6 100644 (file)
@@ -10,7 +10,7 @@
 
 ///
 
-Чтобы **изучить основы 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-терминации:
 
@@ -49,7 +49,7 @@
 
 Процесс получения таких сертификатов был неудобным, требовал бумажной волокиты, а сами сертификаты были довольно дорогими.
 
-Затем появился **<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>**.
+Затем появился **[Let's Encrypt](https://letsencrypt.org/)**.
 
 Это проект Linux Foundation. Он предоставляет **HTTPS‑сертификаты бесплатно**, в автоматическом режиме. Эти сертификаты используют стандартные криптографические механизмы и имеют короткий срок действия (около 3 месяцев), поэтому **безопасность фактически выше** благодаря уменьшенному сроку жизни.
 
@@ -200,9 +200,9 @@ DNS‑серверы ответят браузеру, какой **конкре
 
 Заголовки прокси:
 
-* <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)
 
 ///
 
@@ -218,7 +218,7 @@ DNS‑серверы ответят браузеру, какой **конкре
 
 /// tip | Совет
 
-Подробнее об этом вы можете узнать в документации: [За прокси — Включить пересылаемые заголовки прокси](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
+Подробнее об этом вы можете узнать в документации: [За прокси — Включить пересылаемые заголовки прокси](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers)
 
 ///
 
index 7e735593be4c2e3a57dd0afe548bb1baa67256bc..a64366d4da728ff4ebdd9884b23e6cefe8b8bfbd 100644 (file)
@@ -16,7 +16,7 @@
 
 Вы можете **развернуть сервер** самостоятельно, используя различные инструменты. Например, можно использовать **облачный сервис**, который выполнит часть работы за вас. Также возможны и другие варианты.
 
-Например, мы, команда, стоящая за 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** (хотя большинство из них применимо к любому другому типу веб-приложений).
 
index 93287372a26aae49a92e5afe4fa2aff7da47d740..3169f3189381ec731bdec73b26400e8e5893bca8 100644 (file)
@@ -52,11 +52,11 @@ FastAPI использует стандарт для построения Python
 
 Есть несколько альтернатив, например:
 
-* <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 }
 
@@ -74,7 +74,7 @@ FastAPI использует стандарт для построения Python
 
 Но вы также можете установить ASGI‑сервер вручную.
 
-Создайте [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активируйте его и затем установите серверное приложение.
+Создайте [виртуальное окружение](../virtual-environments.md), активируйте его и затем установите серверное приложение.
 
 Например, чтобы установить Uvicorn:
 
index e756ab377483f49be1752e753362f6c22c472906..2caf79f7d84c4f34c2796b6889b57eda2d32319a 100644 (file)
 
 При деплое приложения вам, скорее всего, захочется использовать **репликацию процессов**, чтобы задействовать **несколько ядер** и иметь возможность обрабатывать больше запросов.
 
-Как вы видели в предыдущей главе о [Концепциях деплоя](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 на контейнер**, но об этом подробнее далее в той главе.
 
@@ -126,7 +126,7 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
 
 ## Контейнеры и Docker { #containers-and-docker }
 
-В следующей главе о [FastAPI в контейнерах — Docker](docker.md){.internal-link target=_blank} я объясню стратегии, которые можно использовать для решения остальных **концепций деплоя**.
+В следующей главе о [FastAPI в контейнерах — Docker](docker.md) я объясню стратегии, которые можно использовать для решения остальных **концепций деплоя**.
 
 Я покажу, как **собрать свой образ с нуля**, чтобы запускать один процесс Uvicorn. Это простой подход и, вероятно, именно то, что вам нужно при использовании распределённой системы управления контейнерами, такой как **Kubernetes**.
 
index 4195d689fee41e097cec02e02404e725d2258834..b52ca456f2b553f7eb0ae10575e24e1119317472 100644 (file)
@@ -4,7 +4,7 @@
 
 Часто добавляются новые функции, регулярно исправляются баги, код продолжает постоянно совершенствоваться.
 
-По указанным причинам текущие версии до сих пор `0.x.x`. Это говорит о том, что каждая версия может содержать обратно несовместимые изменения, следуя <a href="https://semver.org/" class="external-link" target="_blank">Семантическому версионированию</a>.
+По указанным причинам текущие версии до сих пор `0.x.x`. Это говорит о том, что каждая версия может содержать обратно несовместимые изменения, следуя [Семантическому версионированию](https://semver.org/).
 
 Уже сейчас вы можете создавать приложения в продакшн, используя **FastAPI** (и скорее всего так и делаете), главное убедиться в том, что вы используете версию, которая корректно работает с вашим кодом.
 
@@ -34,7 +34,7 @@ fastapi[standard]>=0.112.0,<0.113.0
 
 ## Доступные версии { #available-versions }
 
-Вы можете посмотреть доступные версии (например, проверить последнюю на данный момент) в [Примечаниях к выпуску](../release-notes.md){.internal-link target=_blank}.
+Вы можете посмотреть доступные версии (например, проверить последнюю на данный момент) в [Примечаниях к выпуску](../release-notes.md).
 
 ## О версиях { #about-versions }
 
@@ -66,7 +66,7 @@ fastapi>=0.45.0,<0.46.0
 
 Вам следует добавить тесты для вашего приложения.
 
-С помощью **FastAPI** это очень просто (благодаря Starlette), см. документацию: [Тестирование](../tutorial/testing.md){.internal-link target=_blank}
+С помощью **FastAPI** это очень просто (благодаря Starlette), см. документацию: [Тестирование](../tutorial/testing.md)
 
 После создания тестов вы можете обновить свою версию **FastAPI** до более новой. После этого следует убедиться, что ваш код работает корректно, запустив тесты.
 
diff --git a/docs/ru/docs/editor-support.md b/docs/ru/docs/editor-support.md
new file mode 100644 (file)
index 0000000..0543e71
--- /dev/null
@@ -0,0 +1,23 @@
+# Поддержка редактора кода { #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».
index 759127420f04657777dd02fa9f42dbfd2dedaac4..8db16d16c6343a41584b0009b6b70cc5cc8a3809 100644 (file)
@@ -65,7 +65,7 @@ print(f"Hello {name} from Python")
 
 /// 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»` в качестве значения по умолчанию.
 
@@ -153,7 +153,7 @@ Hello World from Python
 
 /// 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).
 
 ///
 
@@ -163,7 +163,7 @@ Hello World from Python
 
 Это означает, что **любое значение**, считанное в Python из переменной окружения, **будет `str`**, и любое преобразование к другому типу или любая валидация должны быть выполнены в коде.
 
-Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md){.internal-link target=_blank}.
+Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md).
 
 ## Переменная окружения `PATH` { #path-environment-variable }
 
@@ -285,13 +285,13 @@ $ C:\opt\custompython\bin\python
 
 ////
 
-Эта информация будет полезна при изучении [Виртуальных окружений](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).
 
 Во многих случаях не всегда очевидно, как переменные окружения могут быть полезны и применимы. Но они постоянно появляются в различных сценариях разработки, поэтому знать о них полезно.
 
index a46e0053eef89020a44d6ef2ace3259bf64a1b82..1dc558a8c1be1764912c762b225f96e3d027f144 100644 (file)
@@ -1,15 +1,15 @@
 # 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 🚀
 
@@ -46,13 +46,66 @@ $ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid
 
 </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 }
 
@@ -70,6 +123,6 @@ FastAPI CLI берет путь к вашей Python-программе (нап
 
 /// tip | Подсказка
 
-Вы можете больше узнать об этом в [документации по развертыванию](deployment/index.md){.internal-link target=_blank}.
+Вы можете больше узнать об этом в [документации по развертыванию](deployment/index.md).
 
 ///
index 0bc3dbb2d17df506ae8edcde0d826c5c06e36e99..f779c798cc4c47645b15be2fb147eac4bd27b3b1 100644 (file)
@@ -6,8 +6,8 @@
 
 ### Основано на открытых стандартах { #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 прямо из браузера.
 
 ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
 
-* Альтернативная документация API в <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
+* Альтернативная документация API в [**ReDoc**](https://github.com/Rebilly/ReDoc).
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
 
@@ -27,7 +27,7 @@
 
 Все основано на стандартных **аннотациях типов Python** (благодаря Pydantic). Не нужно изучать новый синтаксис. Только стандартный современный Python.
 
-Если вам нужно освежить знания о типах в Python (даже если вы не используете FastAPI), выделите 2 минуты и просмотрите краткое руководство: [Типы Python](python-types.md){.internal-link target=_blank}.
+Если вам нужно освежить знания о типах в Python (даже если вы не используете FastAPI), выделите 2 минуты и просмотрите краткое руководство: [Типы Python](python-types.md).
 
 Вы пишете стандартный Python с типами:
 
@@ -75,7 +75,7 @@ my_second_user: User = User(**second_user_data)
 
 Весь фреймворк был продуман так, чтобы быть простым и интуитивно понятным в использовании, все решения были проверены на множестве редакторов еще до начала разработки, чтобы обеспечить наилучшие условия при написании кода.
 
-В опросах 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** основана на удовлетворении этой возможности. Автозавершение работает везде.
 
@@ -83,11 +83,11 @@ my_second_user: User = User(**second_user_data)
 
 Вот как ваш редактор может вам помочь:
 
-* в <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
+* в [Visual Studio Code](https://code.visualstudio.com/):
 
 ![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
 
-* в <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
+* в [PyCharm](https://www.jetbrains.com/pycharm/):
 
 ![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
 
@@ -124,7 +124,7 @@ FastAPI имеет продуманные значения **по умолчан
 Все схемы безопасности, определённые в 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-заголовках.
     * Параметрах запросов.
@@ -159,13 +159,13 @@ FastAPI включает в себя чрезвычайно простую в и
 
 ## Возможности 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**.
 * Фоновые задачи в том же процессе.
 * События запуска и выключения.
@@ -177,7 +177,7 @@ FastAPI включает в себя чрезвычайно простую в и
 
 ## Возможности 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>’ы для баз данных.
 
index 6bfabb96cbd82a8bde89e039c415ef42762a7ed4..1d274e96a25d3d09c625b90f5816ca5e47758958 100644 (file)
@@ -12,7 +12,7 @@
 
 ## Подписаться на новостную рассылку { #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). В зависимости от уровня поддержки Вы можете получить дополнительные бонусы, например, бейдж в документации. 🎁
 
 ---
 
index 50191576004ad4f845e24ad53adcedb07ab3b328..00969461dc0e1f012b83906e6b4f2deddc756046 100644 (file)
@@ -1,6 +1,6 @@
 # История, проектирование и будущее { #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):
 
 > Какова история этого проекта? Создаётся впечатление, что он явился из ниоткуда и завоевал мир за несколько недель [...]
 
@@ -14,7 +14,7 @@
 
 Во многом история **FastAPI** - история его предшественников.
 
-Как написано в разделе [Альтернативы](alternatives.md){.internal-link target=_blank}:
+Как написано в разделе [Альтернативы](alternatives.md):
 
 <blockquote markdown="1">
 
@@ -44,7 +44,7 @@
 
 Я проверил несколько идей на самых популярных редакторах кода: 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 }
 
@@ -76,4 +76,4 @@
 
 У **FastAPI** великое будущее.
 
-И [ваш вклад в это](help-fastapi.md){.internal-link target=_blank} - очень ценен.
+И [ваша помощь](help-fastapi.md) очень ценится.
index 596563c541d7a66589232cac6a52107ee561d771..acbc18f336539e2fe837bafc3583e997d1267302 100644 (file)
@@ -2,7 +2,7 @@
 
 До версии 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-классах.
 
index 6efa30608e7c4219c063f9f62da47cf7cee65750..5fece06c140584fc93c969b6b81263de18a57c3f 100644 (file)
@@ -10,7 +10,7 @@
 
 Если в вашем коде есть уязвимость, она всё равно останется.
 
-Сокрытие документации лишь усложняет понимание того, как взаимодействовать с вашим 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, есть несколько более эффективных вещей, которые можно сделать, например:
 
index f4f2a0e549a959a10b38fb281e7e858a7347391a..b57a086b6ce616e1136137c68d43f6385748eb5f 100644 (file)
@@ -1,6 +1,6 @@
 # Настройка 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()`.
 
@@ -50,7 +50,7 @@ FastAPI включает некоторые параметры конфигур
 
 ## Другие параметры 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 }
 
index e3c31b32c5a6b64d5c1c19b5ffc64ac8eb902af7..b8398cdb0860865a32c2c1b7f9d0d79342eb711f 100644 (file)
@@ -54,7 +54,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 ### Тестирование { #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 }
 
@@ -93,12 +93,12 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 **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)
 
 После этого структура файлов может выглядеть так:
 
@@ -122,7 +122,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 ### Протестируйте статические файлы { #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**.
 
@@ -180,6 +180,6 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 ### Тестирование 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 и взаимодействовать с ним.
index feef9670ad1e8e97ecd63b813da208ca8161ebf1..1e3a608562577906cf250e9dddbd305438c1dfa5 100644 (file)
@@ -18,7 +18,7 @@
 
 Некоторые сценарии:
 
-* Преобразование тел запросов, не в формате 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.
 * Автоматическое логирование всех тел запросов.
 
@@ -32,7 +32,7 @@
 
 /// tip | Совет
 
-Это учебный пример, демонстрирующий принцип работы. Если вам нужна поддержка Gzip, вы можете использовать готовый [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank}.
+Это учебный пример, демонстрирующий принцип работы. Если вам нужна поддержка Gzip, вы можете использовать готовый [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware).
 
 ///
 
@@ -66,7 +66,7 @@
 
 Именно этих двух компонентов — `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/).
 
 ///
 
@@ -82,7 +82,7 @@
 
 /// 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)).
 
 Но этот пример всё равно актуален и показывает, как взаимодействовать с внутренними компонентами.
 
index 197a1790a25bfbe90ea37f53d7907f2bbbb061d1..c1e369f5e5ec82890ef01a0f7fd845a3ee4f684e 100644 (file)
@@ -37,7 +37,7 @@
 
 Используя информацию выше, вы можете той же вспомогательной функцией сгенерировать схему 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 }
 
@@ -75,6 +75,6 @@
 
 ### Проверьте { #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">
index 029ea1d274ea7fd138a5c2d090da1f53a5d4c532..886105eec459c9aac3bd549de8d5267a6939cca5 100644 (file)
@@ -4,36 +4,40 @@
 
 ## Фильтрация данных — Безопасность { #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).
index 9e28d61822bfe7f932971ffa73744539ce280ac7..1829a211c1548a39c88f2f23b909a09ee851dd24 100644 (file)
 
 Ниже приведены некоторые библиотеки **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/).
 
 Также можно почитать больше о каждой из указанных выше библиотек по приведённым ссылкам.
index 75e7fff265d0ebee13c18072ef40993787735b3e..23d95ba04c71730e163bfb74da7d02d07ed10e95 100644 (file)
@@ -8,6 +8,6 @@
 
 /// tip | Совет
 
-Если вы хотите **изучить FastAPI** структурированно (рекомендуется), вместо этого читайте [Учебник — Руководство пользователя](../tutorial/index.md){.internal-link target=_blank} по главам.
+Если вы хотите **изучить FastAPI** структурированно (рекомендуется), вместо этого читайте [Учебник - Руководство пользователя](../tutorial/index.md) по главам.
 
 ///
index 2b47c08f67f02cccb6affcdd1b837b1d83106793..46b4071da89a2fc76df2cd74f21a27ec5e2be5dc 100644 (file)
@@ -22,7 +22,7 @@ FastAPI 0.126.0 убрал поддержку Pydantic v1, при этом ещ
 
 ## Официальное руководство { #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.
 
 Там также описано, что изменилось, как валидации стали более корректными и строгими, возможные нюансы и т.д.
 
@@ -30,7 +30,7 @@ FastAPI 0.126.0 убрал поддержку Pydantic v1, при этом ещ
 
 ## Тесты { #tests }
 
-Убедитесь, что у вас есть [тесты](../tutorial/testing.md){.internal-link target=_blank} для вашего приложения и что вы запускаете их в системе непрерывной интеграции (CI).
+Убедитесь, что у вас есть [тесты](../tutorial/testing.md) для вашего приложения и что вы запускаете их в системе непрерывной интеграции (CI).
 
 Так вы сможете выполнить обновление и убедиться, что всё работает как ожидается.
 
@@ -38,7 +38,7 @@ FastAPI 0.126.0 убрал поддержку Pydantic v1, при этом ещ
 
 Во многих случаях, когда вы используете обычные 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.
 
 Этот инструмент поможет автоматически изменить большую часть кода, который нужно изменить.
 
index 18f4deeca55003b11e6e10bca51fc39beb4b5cac..09cd48fafd0f3e535dbce4f4e5e5b51ce7668d67 100644 (file)
@@ -1,7 +1,7 @@
 # Тестирование базы данных { #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/). 😎
index 877014a08623a38fd19e385bfeaca77833dbd605..5694b9f29eb027d16c0dee882fb5305b39d63344 100644 (file)
     <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)
 
 ---
 
@@ -44,7 +44,7 @@ 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>
 
@@ -55,51 +55,51 @@ FastAPI — это современный, быстрый (высокопрои
 ### Ключевой-спонсор { #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>
 
 ---
 
@@ -107,27 +107,27 @@ FastAPI — это современный, быстрый (высокопрои
 
 "_Мы переключились на **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**. ⌨️ 🚀
 
@@ -135,12 +135,12 @@ FastAPI — это современный, быстрый (высокопрои
 
 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">
 
@@ -199,7 +199,7 @@ async def read_item(item_id: int, q: str | None = None):
 
 **Примечание**:
 
-Если не уверены, посмотрите раздел _«Нет времени?»_ о <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>
 
@@ -210,7 +210,7 @@ async def read_item(item_id: int, q: str | None = None):
 <div class="termy">
 
 ```console
-$ fastapi dev main.py
+$ fastapi dev
 
  ╭────────── FastAPI CLI - Development mode ───────────╮
  │                                                     │
@@ -235,19 +235,19 @@ INFO:     Application startup complete.
 </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-ответ:
 
@@ -264,17 +264,17 @@ INFO:     Application startup complete.
 
 ### Интерактивная документация 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)):
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
 ### Альтернативная документация 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)):
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
@@ -316,7 +316,7 @@ def update_item(item_id: int, item: Item):
 
 ### Обновление интерактивной документации 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 будет автоматически обновлена, включая новое тело запроса:
 
@@ -332,7 +332,7 @@ def update_item(item_id: int, item: Item):
 
 ### Обновление альтернативной документации 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).
 
 * Альтернативная документация также отразит новый параметр запроса и тело запроса:
 
@@ -442,7 +442,7 @@ item: Item
 * Очень мощную и простую в использовании систему **<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`
@@ -452,24 +452,10 @@ item: Item
 
 ### Разверните приложение (опционально) { #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
@@ -488,7 +474,7 @@ Deploying to FastAPI Cloud...
 
 #### О 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 при минимальных усилиях.
 
@@ -504,9 +490,9 @@ FastAPI — это open source и стандартизированный фре
 
 ## Производительность { #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 }
 
@@ -518,19 +504,19 @@ FastAPI зависит от Pydantic и Starlette.
 
 Используется 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 }
 
@@ -546,13 +532,13 @@ FastAPI зависит от Pydantic и Starlette.
 
 Дополнительные опциональные зависимости 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 }
 
index 8155457e387e1152e9ae3cc75eab5622a1fe7275..7a46b210d6ed57ce13f43c8f9403312fceb207a5 100644 (file)
@@ -4,7 +4,7 @@
 
 Вы можете использовать этот шаблон для старта: в нём уже сделана значительная часть начальной настройки, безопасность, база данных и несколько эндпоинтов 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 }
 
index 95153c3882b33196231a91a939369c3d7aa2e500..61219704c0dd44648717ee7b6fc58677a28bb981 100644 (file)
@@ -269,7 +269,7 @@ def some_function(data: Any):
 
 ## Pydantic-модели { #pydantic-models }
 
-<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> — это библиотека Python для валидации данных.
+[Pydantic](https://docs.pydantic.dev/) — это библиотека Python для валидации данных.
 
 Вы объявляете «форму» данных как классы с атрибутами.
 
@@ -285,13 +285,13 @@ def some_function(data: Any):
 
 /// 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 }
 
@@ -337,12 +337,12 @@ def some_function(data: Any):
 * **Документирования** 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).
 
 ///
index 9fa7a850291b98821f46d36a2abade698b358bb5..22827b69f3e9e67468de2dbfe0def90c2ea6b1e3 100644 (file)
@@ -61,7 +61,7 @@
 
 ## Технические детали { #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), но позволяют запускать фоновые задачи в нескольких процессах и, что особенно важно, на нескольких серверах.
 
index 3fb36d5a227ac5f918ac0970b5b7562cbf0bc3e9..972313559ae2e49703a9e72d21d1f625447aca23 100644 (file)
@@ -123,7 +123,7 @@ from app.routers import items
 
 Для простоты мы воспользовались выдуманным заголовком.
 
-В реальных случаях для получения наилучших результатов используйте интегрированные [утилиты безопасности](security/index.md){.internal-link target=_blank}.
+В реальных случаях для получения наилучших результатов используйте интегрированные [утилиты безопасности](security/index.md).
 
 ///
 
@@ -169,7 +169,7 @@ async def read_item(item_id: str):
 
 /// tip | Подсказка
 
-Обратите внимание, что так же, как и в случае с [зависимостями в декораторах *операций пути*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, никакое значение не будет передано в вашу *функцию-обработчик пути*.
+Обратите внимание, что так же, как и в случае с [зависимостями в декораторах *операций пути*](dependencies/dependencies-in-path-operation-decorators.md), никакое значение не будет передано в вашу *функцию-обработчик пути*.
 
 ///
 
@@ -185,8 +185,8 @@ async def read_item(item_id: str):
 * Все они будут включать предопределённые `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 | Подсказка
 
@@ -303,7 +303,7 @@ from ...dependencies import get_token_header
 
 Вы импортируете и создаёте класс `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"] *}
 
@@ -353,7 +353,7 @@ from .routers import items, users
 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).
 
 ///
 
@@ -465,6 +465,37 @@ from .routers.users import router
 
 ///
 
+## Настройка `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 }
 
 Теперь запустите приложение:
@@ -472,14 +503,14 @@ from .routers.users import router
 <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, включая пути из всех подмодулей, с использованием корректных путей (и префиксов) и корректных тегов:
 
index 6610b209c233df7752ff821166f07801cf3d3291..fab025dbc96987b077996c8a8fc5ba60c1873253 100644 (file)
@@ -95,7 +95,7 @@ my_list: list[str]
 
 Помимо обычных простых типов, таких как `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`:
 
index 4a7adb2559da19dc5bc20c81f643c17746fcd8f4..7d970a7a93afdc5e71428aa30562b7c2cc2a7d5f 100644 (file)
@@ -1,8 +1,8 @@
-# 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).
 
 ///
index 3e55607da5db4ef1b13383b6190c350f95618cb1..8a67c8f51e0bd8d77a9dbf49991b9735f985baa2 100644 (file)
@@ -6,7 +6,7 @@
 
 Ваш API почти всегда должен отправлять тело **ответа**. Но клиентам не обязательно всегда отправлять **тело запроса**: иногда они запрашивают только путь, возможно с некоторыми параметрами запроса, но без тела.
 
-Чтобы объявить тело **запроса**, используйте модели <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, со всей их мощью и преимуществами.
+Чтобы объявить тело **запроса**, используйте модели [Pydantic](https://docs.pydantic.dev/), со всей их мощью и преимуществами.
 
 /// info | Информация
 
@@ -73,7 +73,7 @@
     * Если данные некорректны, вернёт понятную и наглядную ошибку, указывающую, где именно и что было некорректно.
 * Передаст полученные данные в параметр `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 }
@@ -102,15 +102,15 @@ JSON Schema ваших моделей будет частью сгенериро
 
 В сам 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 в редакторе кода, включая:
 
@@ -163,4 +163,4 @@ FastAPI понимает, что значение `q` не является об
 
 ## Без 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).
index feaa1596830cc1015a30f0f3c54eaf8d25173c51..b18b1ddf462a8e53e040ba410bc620426e361930 100644 (file)
@@ -1,6 +1,6 @@
 # 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`.
@@ -77,7 +77,7 @@
 
 ## Больше информации { #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 | Технические детали
 
index 483fe808696273da5e7f71e8131700b1b99475aa..330055be4dac2d9a30869e6964c48de3cf69a5d4 100644 (file)
@@ -74,7 +74,7 @@ from myapp import app
 
 /// 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).
 
 ///
 
index 4cfc4e699fa1aaa8fcfb0844f525be93233d62ba..b4b7ce6314b7a405813caad5b0ca2f1afddef508 100644 (file)
 
 В этом примере мы используем выдуманные пользовательские 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 }
 
 Вы можете использовать те же *функции* зависимостей, что и обычно.
 
@@ -62,7 +62,7 @@
 
 ## Зависимости для группы *операций путей* { #dependencies-for-a-group-of-path-operations }
 
-Позже, читая о том как структурировать большие приложения ([Большие приложения — несколько файлов](../../tutorial/bigger-applications.md){.internal-link target=_blank}), возможно, многофайловые, вы узнаете как объявить единый параметр `dependencies` для всей группы *операций путей*.
+Позже, читая о том как структурировать большие приложения ([Большие приложения — несколько файлов](../../tutorial/bigger-applications.md)), возможно, многофайловые, вы узнаете как объявить единый параметр `dependencies` для всей группы *операций путей*.
 
 ## Глобальные Зависимости { #global-dependencies }
 
index 03a7c083c431be99317c4d9d03c29c2be6ad4399..04c2c2da42e77e3f724dcd5a7e1126174a7fc348 100644 (file)
@@ -14,8 +14,8 @@ FastAPI поддерживает зависимости, которые выпо
 
 Любая функция, с которой можно корректно использовать:
 
-* <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**.
 
@@ -87,7 +87,7 @@ 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** использует их внутренне для достижения этого.
 
@@ -111,7 +111,7 @@ 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 }
 
@@ -233,14 +233,14 @@ participant operation as Функция-обработчик пути
 
 Зависимости с `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:
@@ -264,7 +264,7 @@ 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` внутри функции зависимости:
@@ -275,8 +275,8 @@ with open("./somefile.txt") as f:
 
 Другой способ создания менеджера контекста — с помощью:
 
-* <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`.
 
index f488322a9e8957b49cefc2ba45fbc226c51cd43a..1563d3e8fe43f98485de537fc4fa7d8ba7fe55d3 100644 (file)
@@ -2,14 +2,14 @@
 
 Для некоторых типов приложений может потребоваться добавить зависимости ко всему приложению.
 
-Подобно тому, как вы можете [добавлять `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` для целой группы *операций пути*.
index 29f735ab61c5c80cf57465b41837575a41cda870..4aed035541810e29e99b745ec7eb9aea8c3821d6 100644 (file)
@@ -14,7 +14,7 @@
 
 * Обеспечить общую логику (один и тот же алгоритм снова и снова).
 * Разделять соединения с базой данных.
-* Обеспечить безопасность, аутентификацию, требования к ролям и т. п.
+* Обеспечить безопасность, аутентификацию, требования к ролям и т.п.
 * И многое другое...
 
 Всё это при минимизации повторения кода.
@@ -57,7 +57,7 @@ FastAPI добавил поддержку `Annotated` (и начал реком
 
 Если у вас более старая версия, вы получите ошибки при попытке использовать `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`.
 
 ///
 
@@ -67,11 +67,11 @@ FastAPI добавил поддержку `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` вы передаёте только один параметр.
 
@@ -146,13 +146,13 @@ commons: Annotated[dict, Depends(common_parameters)]
 
 Вы можете использовать `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` в документации.
 
 ///
 
index 28e2a49c0ae69beec1115d49e5735c6d434917cd..f68b401cb42eddc5f1cdcf99b74c1c8c4b4b7d21 100644 (file)
@@ -12,7 +12,7 @@
 
 Например, она не принимает объекты `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`.
 
@@ -24,7 +24,7 @@
 
 В данном примере она преобразует 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.
 
index 3b52b5d74789884d0011a0d7d220cb84d7786339..062c1957423f9a974a8a39916e608f0264061d36 100644 (file)
@@ -36,7 +36,7 @@
 * `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`.
@@ -49,7 +49,7 @@
 * `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 }
 
index f9b63ca70ed1671ebae450e838bbc3c2bfd35d03..becb76bc3fb88ea4f50019839b326af92ac00d50 100644 (file)
@@ -12,7 +12,7 @@
 
 Никогда не храните пароли пользователей в чистом виде. Всегда храните "безопасный хэш", который вы затем сможете проверить.
 
-Если вам это не знакомо, вы можете узнать про "хэш пароля" в [главах о безопасности](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
+Если вам это не знакомо, вы можете узнать про "хэш пароля" в [главах о безопасности](security/simple-oauth2.md#password-hashing).
 
 ///
 
@@ -162,11 +162,11 @@ UserInDB(
 
 Он будет определён в 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]`.
 
 ///
 
index cee264ff4617d0def5290117a38f02c729d46c88..7216d4cb799dd39a169ba3ac53df78c9b5ff65e3 100644 (file)
@@ -11,7 +11,7 @@
 <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 🚀
 
@@ -58,7 +58,7 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 
 ### Проверьте { #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-ответ вида:
 
@@ -68,17 +68,17 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 
 ### Интерактивная документация 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)):
 
 ![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
 
 ### Альтернативная документация 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)):
 
 ![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
 
@@ -92,15 +92,15 @@ INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
 
 #### «Схема» 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 }
 
@@ -110,7 +110,7 @@ OpenAPI определяет схему API для вашего API. И эта 
 
 Если вам интересно, как выглядит исходная схема 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, начинающийся примерно так:
 
@@ -143,9 +143,58 @@ OpenAPI определяет схему API для вашего API. И эта 
 
 Вы также можете использовать её для автоматической генерации кода для клиентов, которые взаимодействуют с вашим 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** (мы пригласили вас из списка ожидания 😉), вы можете развернуть приложение одной командой.
 
@@ -191,7 +240,7 @@ Deploying to FastAPI Cloud...
 
 `FastAPI` — это класс, который напрямую наследуется от `Starlette`.
 
-Вы можете использовать весь функционал <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> и в `FastAPI`.
+Вы можете использовать весь функционал [Starlette](https://www.starlette.dev/) и в `FastAPI`.
 
 ///
 
@@ -336,7 +385,7 @@ https://example.com/items/foo
 
 /// note | Примечание
 
-Если вы не знаете, в чём разница, посмотрите [Асинхронность: *"Нет времени?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+Если вы не знаете, в чём разница, посмотрите [Асинхронность: *"Нет времени?"*](../async.md#in-a-hurry).
 
 ///
 
@@ -348,15 +397,15 @@ https://example.com/items/foo
 
 Также можно вернуть модели 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 с минимальными усилиями.
 
index fbd82cf28a4a6f89fb376e5c893eb3c2cc498ebb..fde188f09f79b4e2c80ec26dc962360c6f546e0b 100644 (file)
@@ -81,7 +81,7 @@
 
 ## Установка пользовательских обработчиков исключений { #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`, которое вы (или используемая вами библиотека) можете `вызвать`.
 
index 6674c6720f2a8194387944fa7c38700841923c56..eec217b75b77b654a3727f084e3fe5c3a5f07b84 100644 (file)
 
 Все блоки кода можно копировать и использовать напрямую (это действительно протестированные файлы 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 🚀
 
@@ -62,7 +62,7 @@ $ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid
 
 Первый шаг — установить FastAPI.
 
-Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, и затем **установите FastAPI**:
+Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md), активировали его, и затем **установите FastAPI**:
 
 <div class="termy">
 
@@ -76,7 +76,7 @@ $ pip install "fastapi[standard]"
 
 /// 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`.
 
@@ -84,6 +84,12 @@ $ pip install "fastapi[standard]"
 
 ///
 
+/// tip | Совет
+
+У FastAPI есть [официальное расширение для VS Code](https://marketplace.visualstudio.com/items?itemName=FastAPILabs.fastapi-vscode) (и Cursor), которое предоставляет множество функций, включая обзор операций пути, поиск операций пути, навигацию CodeLens в тестах (переход к определению из тестов), а также развертывание в FastAPI Cloud и просмотр логов - всё прямо из вашего редактора кода.
+
+///
+
 ## Продвинутое руководство пользователя { #advanced-user-guide }
 
 Существует также **Продвинутое руководство пользователя**, которое вы сможете прочитать после **Учебник - Руководство пользователя**.
index 221655aa5dd9d4ab3885a5a33a7c6788e2d2d41f..261cc43f500a396b7b54af2fa9d87ff8812ba12a 100644 (file)
@@ -14,7 +14,7 @@
 | `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> |
 
 Вы можете задать их следующим образом:
 
@@ -76,7 +76,7 @@
 
 /// info | Дополнительная информация
 
-Узнайте больше о тегах в [Конфигурации операции пути](path-operation-configuration.md#tags){.internal-link target=_blank}.
+Узнайте больше о тегах в [Конфигурации операции пути](path-operation-configuration.md#tags).
 
 ///
 
index 734545cd8befb4e559eb3612f5d8553960a59eae..81140051f2ff8be81cb63597ba0016a2b64d7016 100644 (file)
@@ -15,7 +15,7 @@
 
 Если у вас есть зависимости с `yield`, то код выхода (код после `yield`) будет выполняться *после* middleware.
 
-Если были какие‑либо фоновые задачи (рассматриваются в разделе [Фоновые задачи](background-tasks.md){.internal-link target=_blank}, вы увидите это позже), они будут запущены *после* всех middleware.
+Если были какие‑либо фоновые задачи (рассматриваются в разделе [Фоновые задачи](background-tasks.md), вы увидите это позже), они будут запущены *после* всех middleware.
 
 ///
 
@@ -35,9 +35,9 @@
 
 /// 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).
 
 ///
 
@@ -61,7 +61,7 @@
 
 /// 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()` для обеспечения большей точности в таких случаях. 🤓
 
 ///
 
@@ -90,6 +90,6 @@ app.add_middleware(MiddlewareB)
 
 ## Другие 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.
index 31531c67f1ab9a3b452802e136adb794b309a06a..965f2a1ba2f2ffcb55929fcbdf3d4e4629a25556 100644 (file)
@@ -14,7 +14,7 @@
 
 Вы можете передать только `int`-значение кода, например `404`.
 
-Но если вы не помните, для чего нужен каждый числовой код, вы можете использовать сокращенные константы в параметре `status`:
+Но если вы не помните, для чего нужен каждый числовой код, вы можете использовать сокращенные константы в `status`:
 
 {* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *}
 
@@ -58,7 +58,7 @@
 
 Так как описания обычно длинные и содержат много строк, вы можете объявить описание *операции пути* в <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] *}
 
index 6c1148b60cfbc89d4e098c34be5f4195b32b01d9..34eeb80cb2f6401d31ab92710ab794d8669e982a 100644 (file)
@@ -14,7 +14,7 @@
 
 Если вы используете более старую версию, вы столкнётесь с ошибками при попытке использовать `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`.
 
 ///
 
@@ -112,17 +112,17 @@ Python не будет ничего делать с `*`, но он будет з
 
 Валидация также применима к значениям типа `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).
 
 А также вы можете добавить валидацию числовых данных:
 
index 7295697487640ebe094e6e4dabe359fea5cdc65c..79343a1588ed5ec1f9a07eb8fadc070ffc8b0bbd 100644 (file)
@@ -6,7 +6,7 @@
 
 Значение параметра пути `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"}
@@ -28,7 +28,7 @@
 
 ## <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}
@@ -44,7 +44,7 @@
 
 ## Валидация данных { #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
 {
@@ -64,7 +64,7 @@
 
 из-за того, что параметр пути `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 | Заметка
 
@@ -78,7 +78,7 @@
 
 ## Документация { #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">
 
@@ -92,9 +92,9 @@
 
 ## Преимущества стандартизации, альтернативная документация { #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 }
 
index 43cbcad03ce14711370e1f91ab73942398a04031..08a5e11a54777f7a5b8bc8eea8fb67f2aa932444 100644 (file)
@@ -35,13 +35,13 @@ FastAPI поймёт, что значение `q` не обязательно, 
 
 Если у вас более старая версия, при попытке использовать `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. 🚀
 
@@ -157,7 +157,7 @@ q: str = Query(default="rick")
 
 Если вы не используете `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 }
 
@@ -369,11 +369,11 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
 
 В таких случаях можно использовать **кастомную функцию-валидатор**, которая применяется после обычной валидации (например, после проверки, что значение — это `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) и другие. 🤓
 
 ///
 
@@ -389,7 +389,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
 
 /// tip | Совет
 
-Если вам нужна валидация, требующая общения с каким‑либо **внешним компонентом** — базой данных или другим API — вместо этого используйте **Зависимости FastAPI** (FastAPI Dependencies), вы познакомитесь с ними позже.
+Если вам нужна валидация, требующая общения с каким‑либо **внешним компонентом** — базой данных или другим API — вместо этого используйте **Зависимости FastAPI**, вы познакомитесь с ними позже.
 
 Эти кастомные валидаторы предназначены для проверок, которые можно выполнить, имея **только** те же **данные**, что пришли в запросе.
 
index cbacb129c5193d787e5edf038c3fd22dbe94ce31..99f2a98aeb9fde949563a99394b1f7bc1f1c980e 100644 (file)
@@ -182,6 +182,6 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
 
 /// tip | Подсказка
 
-Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#predefined-values){.internal-link target=_blank}.
+Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#predefined-values).
 
 ///
index 41922333f86848b4c35f2ef6ec3a66530d4b9449..e8500adbac784a80962006903c6dfde1c30c4bd0 100644 (file)
@@ -4,9 +4,9 @@
 
 /// 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
@@ -63,8 +63,8 @@ $ 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 }
 
@@ -72,7 +72,7 @@ $ pip install python-multipart
 
 * `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`).
 
@@ -120,9 +120,9 @@ contents = myfile.file.read()
 
 Данные из форм обычно кодируются с использованием "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).
 
 ///
 
index f4411a27bc0c8e38c3dd4a0dfc36ae40173bffd0..c7f37c2baf5492199c527f952d38501deba72cac 100644 (file)
@@ -4,9 +4,9 @@
 
 /// 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
index 10836d74fdb3b46ff294f2fe3552b3b6f3ec9663..f291d53479cc557ff23dcd8ced117c56fe0353ba 100644 (file)
@@ -4,9 +4,9 @@
 
 /// 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
index 01f71ac2fc61d8bbb2610c814fc5cadb8d94e2e5..3760a8a3b95c8de92e0892c198f20859a14e9a58 100644 (file)
@@ -4,9 +4,9 @@
 
 /// 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
@@ -56,7 +56,7 @@ $ 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).
 
 ///
 
index cd99ce28c704c0e8a149d2ff30729ee6ca657c07..510143d7b4eaedc270ceb3a7d420d8d2ea36a427 100644 (file)
@@ -13,6 +13,7 @@ FastAPI будет использовать этот возвращаемый т
 * Добавить **JSON Schema** для ответа в OpenAPI *операции пути*.
     * Это будет использовано **автоматической документацией**.
     * Это также будет использовано инструментами автоматической генерации клиентского кода.
+* **Сериализовать** возвращаемые данные в JSON с помощью Pydantic, который написан на **Rust**, поэтому это будет **намного быстрее**.
 
 Но самое главное:
 
@@ -73,9 +74,9 @@ FastAPI будет использовать этот `response_model` для д
 
 /// 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
@@ -181,7 +182,7 @@ FastAPI делает несколько вещей внутри вместе с
 
 ### Возврат 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] *}
 
@@ -201,7 +202,7 @@ FastAPI делает несколько вещей внутри вместе с
 
 Но когда вы возвращаете произвольный объект, не являющийся валидным типом Pydantic (например, объект базы данных), и аннотируете его таким образом в функции, FastAPI попытается создать модель ответа Pydantic из этой аннотации типа и потерпит неудачу.
 
-То же произойдёт, если у вас будет что-то вроде <dfn title="Объединение нескольких типов означает «любой из этих типов».">union</dfn> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
+То же произойдёт, если у вас будет что-то вроде <dfn title="Объединение нескольких типов означает «любой из этих типов».">объединение</dfn> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
 
 {* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
 
@@ -257,7 +258,7 @@ FastAPI делает несколько вещей внутри вместе с
 * `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`.
 
 ///
 
index 13d982e803cc0766322263a56994abbfb457119d..f3144a33ab4f328635d953f38ae005bc18196257 100644 (file)
@@ -20,7 +20,7 @@
 
 /// 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.
 
 ///
 
@@ -66,7 +66,7 @@ FastAPI знает об этом и создаст документацию Open
 
 /// 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).
 
 ///
 
@@ -98,4 +98,4 @@ FastAPI знает об этом и создаст документацию Open
 
 ## Изменение кода статуса по умолчанию { #changing-the-default }
 
-Позже, в [Руководстве для продвинутых пользователей](../advanced/response-change-status-code.md){.internal-link target=_blank}, вы узнаете, как возвращать HTTP статус-код, отличный от значения по умолчанию, которое вы объявляете здесь.
+Позже, в [Руководстве для продвинутых пользователей](../advanced/response-change-status-code.md), вы узнаете, как возвращать HTTP статус-код, отличный от значения по умолчанию, которое вы объявляете здесь.
index c7381aae25fc22fe953731a66f1d1a5cf1fd9faa..ee2f5b99135dda1c105d93ddd35d847aedb88488 100644 (file)
@@ -12,7 +12,7 @@
 
 Эта дополнительная информация будет добавлена как есть в выходную **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`.
 
@@ -145,12 +145,12 @@ OpenAPI 3.1.0 (используется начиная с FastAPI 0.99.0) доб
 
 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()`
@@ -163,7 +163,7 @@ OpenAPI также добавила поля `example` и `examples` в друг
 
 ### Поле `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`.
 
index 9b9673b8420d3f6abdf534735be15d8d0bae4112..c55e832f40b7a5ef5689fcbee6684509da1a24ed 100644 (file)
 
 /// 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
@@ -45,7 +45,7 @@ $ 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)
 ```
@@ -54,7 +54,7 @@ $ fastapi dev main.py
 
 ## Проверка { #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).
 
 Вы увидите примерно следующее:
 
@@ -140,7 +140,7 @@ OAuth2 был спроектирован так, чтобы бэкенд или
 
 Поскольку мы используем относительный 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).
 
 ///
 
index f7853d48f77dcc06c7015d006829a5afe850fec8..e3729dfc83f9294a656517dc4494272887a63d74 100644 (file)
@@ -24,13 +24,13 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4
 
 Через неделю срок действия токена истечет, пользователь не будет авторизован и ему придется заново входить в систему, чтобы получить новый токен. А если пользователь (или третье лицо) попытается модифицировать токен, чтобы изменить срок действия, вы сможете это обнаружить, поскольку подписи не будут совпадать.
 
-Если вы хотите поиграть с 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">
 
@@ -46,7 +46,7 @@ $ pip install pyjwt
 
 Если вы планируете использовать алгоритмы цифровой подписи, такие как 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).
 
 ///
 
@@ -72,7 +72,7 @@ pwdlib — это отличный пакет Python для работы с хэ
 
 Рекомендуемый алгоритм — "Argon2".
 
-Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md){.internal-link target=_blank}, активируйте его, и затем установите pwdlib вместе с Argon2:
+Убедитесь, что вы создали [виртуальное окружение](../../virtual-environments.md), активируйте его, и затем установите pwdlib вместе с Argon2:
 
 <div class="termy">
 
@@ -200,7 +200,7 @@ JWT может использоваться и для других целей, 
 
 ## Проверка в действии { #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).
 
 Вы увидите пользовательский интерфейс вида:
 
index 4b86a40139debcf3db931041b19704f4a8b14887..4ef5109e4f6148c41adbc81bbd9a8703fedc8523 100644 (file)
@@ -137,7 +137,7 @@ UserInDB(
 ```
 
 /// 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 }
@@ -200,7 +200,7 @@ UserInDB(
 
 ## Посмотрим, как это работает { #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 }
 
diff --git a/docs/ru/docs/tutorial/server-sent-events.md b/docs/ru/docs/tutorial/server-sent-events.md
new file mode 100644 (file)
index 0000000..be6bd23
--- /dev/null
@@ -0,0 +1,120 @@
+# События, отправляемые сервером (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.
+
+Вам не нужно ничего настраивать, это работает из коробки. 🤓
index ed67739cc97d540428e4777c44eed3dcef7c6cd1..ae863733879e0e15016c610b8cbade209252f9b3 100644 (file)
@@ -2,9 +2,9 @@
 
 **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">
 
@@ -57,7 +57,7 @@ $ pip install sqlmodel
 
 {* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *}
 
-Класс `Hero` очень похож на модель Pydantic (фактически, под капотом, *это и есть модель Pydantic*).
+Класс `Hero` очень похож на модель Pydantic (фактически, под капотом, это и есть модель Pydantic).
 
 Есть несколько отличий:
 
@@ -65,7 +65,7 @@ $ pip install sqlmodel
 
 * `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 индекс** для этого столбца, что позволит быстрее выполнять выборки при чтении данных, отфильтрованных по этому столбцу.
 
@@ -81,7 +81,7 @@ $ pip install sqlmodel
 
 Параметр `check_same_thread=False` позволяет FastAPI использовать одну и ту же базу данных SQLite в разных потоках. Это необходимо, так как **один запрос** может использовать **больше одного потока** (например, в зависимостях).
 
-Не волнуйтесь, с такой структурой кода мы позже обеспечим использование **одной *сессии* SQLModel на запрос**, по сути именно этого и добивается `check_same_thread`.
+Не волнуйтесь, с такой структурой кода мы позже обеспечим использование **одной сессии SQLModel на запрос**, по сути именно этого и добивается `check_same_thread`.
 
 ### Создание таблиц { #create-the-tables }
 
@@ -111,7 +111,7 @@ $ pip install sqlmodel
 
 /// 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/) напрямую.
 
 ///
 
@@ -152,7 +152,7 @@ $ pip install sqlmodel
 <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)
 ```
@@ -337,7 +337,7 @@ $ fastapi dev main.py
 <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)
 ```
@@ -352,6 +352,6 @@ $ fastapi dev main.py
 
 ## Резюме { #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/). 🚀
index 3b0cab8313d2a217c219d3d9c9a781e47139c03e..dfcc77b6fd0e944f4dee0f7683969058b73bac7a 100644 (file)
@@ -24,7 +24,7 @@
 Это отличается от использования `APIRouter`, так как примонтированное приложение является полностью независимым.
 OpenAPI и документация из вашего главного приложения не будут содержать ничего из примонтированного приложения, и т.д.
 
-Вы можете прочитать больше об этом в [Расширенном руководстве пользователя](../advanced/index.md){.internal-link target=_blank}.
+Вы можете прочитать больше об этом в [Расширенном руководстве пользователя](../advanced/index.md).
 
 ## Детали { #details }
 
@@ -38,4 +38,4 @@ OpenAPI и документация из вашего главного прил
 
 ## Больше информации { #more-info }
 
-Для получения дополнительной информации о деталях и настройках ознакомьтесь с <a href="https://www.starlette.dev/staticfiles/" class="external-link" target="_blank">Документацией Starlette о статических файлах</a>.
+Для получения дополнительной информации о деталях и настройках ознакомьтесь с [документацией Starlette о статических файлах](https://www.starlette.dev/staticfiles/).
diff --git a/docs/ru/docs/tutorial/stream-json-lines.md b/docs/ru/docs/tutorial/stream-json-lines.md
new file mode 100644 (file)
index 0000000..d8bb913
--- /dev/null
@@ -0,0 +1,111 @@
+# Стриминг 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). 🤓
index 6dd2fe579a3d96328410fea82882a282d2a0bc71..aef7b86dedfcf003073d633ebf3a494be5eba27d 100644 (file)
@@ -1,18 +1,18 @@
 # Тестирование { #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
@@ -52,7 +52,7 @@ $ pip install httpx
 
 /// tip | Подсказка
 
-Если для тестирования Вам, помимо запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, для подключения к базе данных с помощью асинхронного драйвера), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md){.internal-link target=_blank} в расширенном руководстве.
+Если для тестирования Вам, помимо запросов к приложению FastAPI, необходимо вызывать асинхронные функции (например, для подключения к базе данных с помощью асинхронного драйвера), то ознакомьтесь со страницей [Асинхронное тестирование](../advanced/async-tests.md) в расширенном руководстве.
 
 ///
 
@@ -64,7 +64,7 @@ $ pip install httpx
 
 ### Файл приложения **FastAPI** { #fastapi-app-file }
 
-Допустим, структура файлов Вашего приложения похожа на ту, что описана на странице [Более крупные приложения](bigger-applications.md){.internal-link target=_blank}:
+Допустим, структура файлов Вашего приложения похожа на ту, что описана на странице [Более крупные приложения](bigger-applications.md):
 
 ```
 .
@@ -80,7 +80,7 @@ $ pip install httpx
 
 ### Файл тестов { #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"
 .
@@ -142,13 +142,13 @@ $ pip install httpx
 * Для передачи *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).
 
 ///
 
@@ -156,7 +156,7 @@ $ pip install httpx
 
 Далее Вам нужно установить `pytest`.
 
-Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его, а затем установили пакет, например:
+Убедитесь, что Вы создали [виртуальное окружение](../virtual-environments.md), активировали его, а затем установили пакет, например:
 
 <div class="termy">
 
index f931cc3c8273e0037f6cffdcb31c63446129bfea..633137d09eb4753584f722ee3fb28df804b2fed5 100644 (file)
@@ -22,7 +22,7 @@
 
 На этой странице вы узнаете, как пользоваться **виртуальными окружениями** и как они работают.
 
-Если вы готовы начать использовать **инструмент, который управляет всем** за вас (включая установку Python), попробуйте <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+Если вы готовы начать использовать **инструмент, который управляет всем** за вас (включая установку Python), попробуйте [uv](https://github.com/astral-sh/uv).
 
 ///
 
@@ -86,7 +86,7 @@ $ python -m venv .venv
 
 //// 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">
 
@@ -150,7 +150,7 @@ $ .venv\Scripts\Activate.ps1
 
 //// 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">
 
@@ -216,7 +216,7 @@ C:\Users\user\code\awesome-project\.venv\Scripts\python
 
 /// 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` не нужно. 😎
 
 ///
 
@@ -268,7 +268,7 @@ $ python -m ensurepip --upgrade
 
 /// tip | Подсказка
 
-Если вы использовали <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> для создания виртуального окружения, он уже сделал это за вас — можно пропустить этот шаг. 😎
+Если вы использовали [`uv`](https://github.com/astral-sh/uv) для создания виртуального окружения, он уже сделал это за вас — можно пропустить этот шаг. 😎
 
 ///
 
@@ -340,7 +340,7 @@ $ pip install "fastapi[standard]"
 
 //// 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">
 
@@ -372,7 +372,7 @@ $ pip install -r requirements.txt
 
 //// 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">
 
@@ -416,8 +416,8 @@ Hello World
 
 Например:
 
-* <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 | Подсказка
 
@@ -455,7 +455,7 @@ $ deactivate
 
 ## Зачем нужны виртуальные окружения { #why-virtual-environments }
 
-Чтобы работать с FastAPI, вам нужно установить <a href="https://www.python.org/" class="external-link" target="_blank">Python</a>.
+Чтобы работать с FastAPI, вам нужно установить [Python](https://www.python.org/).
 
 После этого вам нужно будет **установить** FastAPI и другие **пакеты**, которые вы хотите использовать.
 
@@ -564,7 +564,7 @@ $ pip install "fastapi[standard]"
 
 </div>
 
-Будет загружен сжатый файл с кодом FastAPI, обычно с <a href="https://pypi.org/project/fastapi/" class="external-link" target="_blank">PyPI</a>.
+Будет загружен сжатый файл с кодом FastAPI, обычно с [PyPI](https://pypi.org/project/fastapi/).
 
 Также будут **загружены** файлы для других пакетов, от которых зависит FastAPI.
 
@@ -627,7 +627,7 @@ $ .venv\Scripts\Activate.ps1
 
 //// 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">
 
@@ -639,13 +639,13 @@ $ source .venv/Scripts/activate
 
 ////
 
-Эта команда создаст или изменит некоторые [переменные окружения](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).
 
 ///
 
@@ -846,7 +846,7 @@ I solemnly swear 🐺
 
 Существует много **альтернатив** для управления виртуальными окружениями, зависимостями (requirements), проектами.
 
-Когда вы будете готовы и захотите использовать инструмент для **управления всем проектом** — зависимостями пакетов, виртуальными окружениями и т. п., я бы предложил попробовать <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+Когда вы будете готовы и захотите использовать инструмент для **управления всем проектом** — зависимостями пакетов, виртуальными окружениями и т.п., я бы предложил попробовать [uv](https://github.com/astral-sh/uv).
 
 `uv` может многое: