From 977abe239662203ab0ea3b089092f94d3526e8fd Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Tue, 30 Sep 2025 13:24:39 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=90=20Update=20Russian=20translations?= =?UTF-8?q?=20for=20existing=20pages=20(LLM-generated)=20(#14123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Russian translations for modified pages * docs: fix translation for multiprocessing * Update Russian translations for other existing pages * Apply changes from latest PRs: 13917 and 14099 --------- Co-authored-by: vldmrdev <70532790+vldmrdev@users.noreply.github.com> --- docs/ru/docs/about/index.md | 4 +- .../docs/advanced/additional-status-codes.md | 30 +- docs/ru/docs/advanced/async-tests.md | 14 +- docs/ru/docs/advanced/index.md | 8 +- .../advanced/response-change-status-code.md | 20 +- docs/ru/docs/advanced/response-cookies.md | 31 +- docs/ru/docs/advanced/response-directly.md | 12 +- docs/ru/docs/advanced/websockets.md | 42 +- docs/ru/docs/alternatives.md | 456 ++++++------- docs/ru/docs/async.md | 483 ++++++------- docs/ru/docs/benchmarks.md | 45 +- docs/ru/docs/deployment/concepts.md | 322 +++++---- docs/ru/docs/deployment/docker.md | 643 ++++++++---------- docs/ru/docs/deployment/https.md | 238 ++++--- docs/ru/docs/deployment/index.md | 10 +- docs/ru/docs/deployment/manually.md | 202 +++--- docs/ru/docs/deployment/versions.md | 44 +- docs/ru/docs/environment-variables.md | 23 +- docs/ru/docs/fastapi-cli.md | 18 +- docs/ru/docs/features.md | 133 ++-- docs/ru/docs/help-fastapi.md | 242 ++++--- docs/ru/docs/history-design-future.md | 28 +- docs/ru/docs/index.md | 321 +++++---- docs/ru/docs/learn/index.md | 2 +- docs/ru/docs/project-generation.md | 102 +-- docs/ru/docs/python-types.md | 501 ++++++++++---- docs/ru/docs/tutorial/background-tasks.md | 80 +-- docs/ru/docs/tutorial/bigger-applications.md | 53 +- docs/ru/docs/tutorial/body-fields.md | 21 +- docs/ru/docs/tutorial/body-multiple-params.md | 32 +- docs/ru/docs/tutorial/body-nested-models.md | 100 +-- docs/ru/docs/tutorial/body-updates.md | 42 +- docs/ru/docs/tutorial/body.md | 170 ++--- docs/ru/docs/tutorial/cookie-param-models.md | 12 +- docs/ru/docs/tutorial/cookie-params.md | 24 +- docs/ru/docs/tutorial/cors.md | 57 +- docs/ru/docs/tutorial/debugging.md | 10 +- .../dependencies/classes-as-dependencies.md | 123 ++-- ...pendencies-in-path-operation-decorators.md | 18 +- .../dependencies/dependencies-with-yield.md | 193 +++--- .../dependencies/global-dependencies.md | 10 +- docs/ru/docs/tutorial/dependencies/index.md | 194 +++--- .../tutorial/dependencies/sub-dependencies.md | 18 +- docs/ru/docs/tutorial/encoder.md | 12 +- docs/ru/docs/tutorial/extra-data-types.md | 18 +- docs/ru/docs/tutorial/extra-models.md | 40 +- docs/ru/docs/tutorial/first-steps.md | 264 ++++--- docs/ru/docs/tutorial/handling-errors.md | 34 +- docs/ru/docs/tutorial/header-param-models.md | 12 +- docs/ru/docs/tutorial/header-params.md | 14 +- docs/ru/docs/tutorial/index.md | 94 +-- docs/ru/docs/tutorial/metadata.md | 44 +- docs/ru/docs/tutorial/middleware.md | 35 +- .../tutorial/path-operation-configuration.md | 22 +- .../path-params-numeric-validations.md | 58 +- docs/ru/docs/tutorial/path-params.md | 87 +-- docs/ru/docs/tutorial/query-param-models.md | 12 +- .../tutorial/query-params-str-validations.md | 403 +++++------ docs/ru/docs/tutorial/query-params.md | 46 +- docs/ru/docs/tutorial/request-files.md | 39 +- docs/ru/docs/tutorial/request-form-models.md | 18 +- .../docs/tutorial/request-forms-and-files.md | 22 +- docs/ru/docs/tutorial/request-forms.md | 38 +- docs/ru/docs/tutorial/response-model.md | 270 ++++---- docs/ru/docs/tutorial/response-status-code.md | 38 +- docs/ru/docs/tutorial/schema-extra-example.md | 210 ++++-- docs/ru/docs/tutorial/security/first-steps.md | 152 +++-- .../tutorial/security/get-current-user.md | 82 +-- docs/ru/docs/tutorial/security/oauth2-jwt.md | 68 +- .../docs/tutorial/security/simple-oauth2.md | 165 ++--- docs/ru/docs/tutorial/sql-databases.md | 223 +++--- docs/ru/docs/tutorial/static-files.md | 18 +- docs/ru/docs/tutorial/testing.md | 40 +- docs/ru/docs/virtual-environments.md | 333 ++++----- 74 files changed, 4157 insertions(+), 3885 deletions(-) diff --git a/docs/ru/docs/about/index.md b/docs/ru/docs/about/index.md index 1015b667a..4f48266a7 100644 --- a/docs/ru/docs/about/index.md +++ b/docs/ru/docs/about/index.md @@ -1,3 +1,3 @@ -# О проекте +# О проекте { #about } -FastAPI: внутреннее устройство, повлиявшие технологии и всё такое прочее. 🤓 +О FastAPI, его дизайне, источниках вдохновения и многом другом. 🤓 diff --git a/docs/ru/docs/advanced/additional-status-codes.md b/docs/ru/docs/advanced/additional-status-codes.md index aab1f8ee3..7c73cf5d5 100644 --- a/docs/ru/docs/advanced/additional-status-codes.md +++ b/docs/ru/docs/advanced/additional-status-codes.md @@ -1,28 +1,28 @@ -# Дополнительные статус коды +# Дополнительные статус-коды { #additional-status-codes } -По умолчанию **FastAPI** возвращает ответы, используя `JSONResponse`, помещая содержимое, которое вы возвращаете из вашей *операции пути*, внутрь этого `JSONResponse`. +По умолчанию **FastAPI** будет возвращать ответы, используя `JSONResponse`, помещая содержимое, которое вы возвращаете из вашей *операции пути*, внутрь этого `JSONResponse`. -Он будет использовать код статуса по умолчанию или тот, который вы укажете в вашей *операции пути*. +Он будет использовать статус-код по умолчанию или тот, который вы укажете в вашей *операции пути*. -## Дополнительные статус коды +## Дополнительные статус-коды { #additional-status-codes_1 } -Если вы хотите возвращать дополнительный статус код помимо основного, вы можете сделать это, возвращая объект `Response` напрямую, как `JSONResponse`, и устанавливая нужный статус код напрямую. +Если вы хотите возвращать дополнительные статус-коды помимо основного, вы можете сделать это, возвращая `Response` напрямую, например `JSONResponse`, и устанавливая дополнительный статус-код напрямую. -Например, скажем, вы хотите создать *операцию пути*, которая позволяет обновлять элементы и возвращает HTTP-код 200 "OK" при успешном выполнении. +Например, предположим, что вы хотите иметь *операцию пути*, которая позволяет обновлять элементы и возвращает HTTP статус-код 200 «OK» при успешном выполнении. -Но вы также хотите, чтобы она принимала новые элементы. И если элемент ранее не существовал, он создаётся, и возвращался HTTP-код 201 "Created". +Но вы также хотите, чтобы она принимала новые элементы. И если элементы ранее не существовали, она создаёт их и возвращает HTTP статус-код 201 «Created». -Чтобы реализовать это, импортируйте `JSONResponse` и возвращайте ваш контент напрямую, устанавливая нужный `status_code`: +Чтобы добиться этого, импортируйте `JSONResponse` и верните туда свой контент напрямую, установив нужный вам `status_code`: {* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *} /// warning | Внимание -Когда вы возвращаете объект `Response` напрямую, как в примере выше, он будет возвращён как есть. +Когда вы возвращаете `Response` напрямую, как в примере выше, он будет возвращён как есть. -Он не будет сериализован при помощи модели и т.д. +Он не будет сериализован с помощью модели и т.п. -Убедитесь, что в нём содержатся именно те данные, которые вы хотите, и что значения являются валидным JSON (если вы используете `JSONResponse`). +Убедитесь, что в нём именно те данные, которые вы хотите, и что значения являются валидным JSON (если вы используете `JSONResponse`). /// @@ -30,12 +30,12 @@ Вы также можете использовать `from starlette.responses import JSONResponse`. -**FastAPI** предоставляет тот же `starlette.responses` через `fastapi.responses` просто для вашего удобства, как разработчика. Но большинство доступных Response-классов поступают напрямую из Starlette. То же самое касается и `status`. +**FastAPI** предоставляет тот же `starlette.responses` через `fastapi.responses` просто для вашего удобства как разработчика. Но большинство доступных Response-классов приходят напрямую из Starlette. То же самое со `status`. /// -## OpenAPI и документация API +## OpenAPI и документация API { #openapi-and-api-docs } -Если вы возвращаете дополнительные коды статусов и ответы напрямую, они не будут включены в схему OpenAPI (документацию API), потому что FastAPI не может заранее знать, что вы собираетесь вернуть. +Если вы возвращаете дополнительные статус-коды и ответы напрямую, они не будут включены в схему OpenAPI (документацию API), потому что у FastAPI нет способа заранее знать, что вы собираетесь вернуть. -Но вы можете задокументировать это в вашем коде, используя: [Дополнительные ответы в OpenAPI](additional-responses.md){.internal-link target=_blank}. +Но вы можете задокументировать это в своём коде, используя: [Дополнительные ответы](additional-responses.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/advanced/async-tests.md b/docs/ru/docs/advanced/async-tests.md index 7849ad109..5062bc52e 100644 --- a/docs/ru/docs/advanced/async-tests.md +++ b/docs/ru/docs/advanced/async-tests.md @@ -1,4 +1,4 @@ -# Асинхронное тестирование +# Асинхронное тестирование { #async-tests } Вы уже видели как тестировать **FastAPI** приложение, используя имеющийся класс `TestClient`. К этому моменту вы видели только как писать тесты в синхронном стиле без использования `async` функций. @@ -6,11 +6,11 @@ Давайте рассмотрим, как мы можем это реализовать. -## pytest.mark.anyio +## pytest.mark.anyio { #pytest-mark-anyio } Если мы хотим вызывать асинхронные функции в наших тестах, то наши тестовые функции должны быть асинхронными. AnyIO предоставляет для этого отличный плагин, который позволяет нам указывать, какие тестовые функции должны вызываться асинхронно. -## HTTPX +## HTTPX { #httpx } Даже если **FastAPI** приложение использует обычные функции `def` вместо `async def`, это все равно `async` приложение 'под капотом'. @@ -18,7 +18,7 @@ `TestClient` основан на HTTPX, и, к счастью, мы можем использовать его (`HTTPX`) напрямую для тестирования API. -## Пример +## Пример { #example } В качестве простого примера, давайте рассмотрим файловую структуру, схожую с описанной в [Большие приложения](../tutorial/bigger-applications.md){.internal-link target=_blank} и [Тестирование](../tutorial/testing.md){.internal-link target=_blank}: @@ -38,7 +38,7 @@ {* ../../docs_src/async_tests/test_main.py *} -## Запуск тестов +## Запуск тестов { #run-it } Вы можете запустить свои тесты как обычно: @@ -52,7 +52,7 @@ $ pytest -## Подробнее +## Подробнее { #in-detail } Маркер `@pytest.mark.anyio` говорит pytest, что тестовая функция должна быть вызвана асинхронно: @@ -88,7 +88,7 @@ response = client.get('/') /// -## Вызов других асинхронных функций +## Вызов других асинхронных функций { #other-asynchronous-function-calls } Теперь тестовая функция стала асинхронной, поэтому внутри нее вы можете вызывать также и другие `async` функции, не связанные с отправлением запросов в ваше FastAPI приложение. Как если бы вы вызывали их в любом другом месте вашего кода. diff --git a/docs/ru/docs/advanced/index.md b/docs/ru/docs/advanced/index.md index b5cb733e7..c0a52c6c1 100644 --- a/docs/ru/docs/advanced/index.md +++ b/docs/ru/docs/advanced/index.md @@ -1,12 +1,12 @@ -# Расширенное руководство пользователя +# Расширенное руководство пользователя { #advanced-user-guide } -## Дополнительные возможности +## Дополнительные возможности { #additional-features } Основное [Учебник - Руководство пользователя](../tutorial/index.md){.internal-link target=_blank} должно быть достаточно, чтобы познакомить вас со всеми основными функциями **FastAPI**. В следующих разделах вы увидите другие варианты, конфигурации и дополнительные возможности. -/// tip +/// tip | Совет Следующие разделы **не обязательно являются "продвинутыми"**. @@ -14,7 +14,7 @@ /// -## Сначала прочитайте Учебник - Руководство пользователя +## Сначала прочитайте Учебник - Руководство пользователя { #read-the-tutorial-first } Вы все еще можете использовать большинство функций **FastAPI** со знаниями из [Учебник - Руководство пользователя](../tutorial/index.md){.internal-link target=_blank}. diff --git a/docs/ru/docs/advanced/response-change-status-code.md b/docs/ru/docs/advanced/response-change-status-code.md index 37dade99f..e9e1c9470 100644 --- a/docs/ru/docs/advanced/response-change-status-code.md +++ b/docs/ru/docs/advanced/response-change-status-code.md @@ -1,22 +1,22 @@ -# Response - Изменение cтатус кода +# Response - Изменение статус-кода { #response-change-status-code } -Вы, вероятно, уже читали о том, что можно установить [Состояние ответа по умолчанию](../tutorial/response-status-code.md){.internal-link target=_blank}. +Вы, вероятно, уже читали о том, что можно установить [статус-код ответа по умолчанию](../tutorial/response-status-code.md){.internal-link target=_blank}. -Но в некоторых случаях вам нужно вернуть код состояния, отличный от установленного по умолчанию. +Но в некоторых случаях нужно вернуть другой статус-код, отличный от значения по умолчанию. -## Пример использования +## Пример использования { #use-case } -Например, представьте, что вы хотите возвращать HTTP код состояния "OK" `200` по умолчанию. +Например, представьте, что вы хотите по умолчанию возвращать HTTP статус-код «OK» `200`. -Но если данные не существовали, вы хотите создать их и вернуть HTTP код состояния "CREATED" `201`. +Но если данные не существовали, вы хотите создать их и вернуть HTTP статус-код «CREATED» `201`. При этом вы всё ещё хотите иметь возможность фильтровать и преобразовывать возвращаемые данные с помощью `response_model`. Для таких случаев вы можете использовать параметр `Response`. -## Использование параметра `Response` +## Использование параметра `Response` { #use-a-response-parameter } -Вы можете объявить параметр типа `Response` в вашей *функции обработки пути* (так же как для cookies и headers). +Вы можете объявить параметр типа `Response` в вашей *функции обработки пути* (как и для cookies и HTTP-заголовков). И затем вы можете установить `status_code` в этом *временном* объекте ответа. @@ -26,6 +26,6 @@ И если вы объявили `response_model`, он всё равно будет использоваться для фильтрации и преобразования возвращаемого объекта. -**FastAPI** будет использовать этот *временный* ответ для извлечения кода состояния (а также cookies и headers) и поместит их в финальный ответ, который содержит возвращаемое вами значение, отфильтрованное любым `response_model`. +**FastAPI** будет использовать этот *временный* ответ для извлечения статус-кода (а также cookies и HTTP-заголовков) и поместит их в финальный ответ, который содержит возвращаемое вами значение, отфильтрованное любым `response_model`. -Вы также можете объявить параметр `Response` в зависимостях и установить код состояния в них. Но помните, что последнее установленное значение будет иметь приоритет. +Вы также можете объявить параметр `Response` в зависимостях и установить в них статус-код. Но помните, что последнее установленное значение будет иметь приоритет. diff --git a/docs/ru/docs/advanced/response-cookies.md b/docs/ru/docs/advanced/response-cookies.md index e04ff577c..3aa32b9bb 100644 --- a/docs/ru/docs/advanced/response-cookies.md +++ b/docs/ru/docs/advanced/response-cookies.md @@ -1,9 +1,8 @@ +# Cookies в ответе { #response-cookies } -# Cookies в ответе +## Использование параметра `Response` { #use-a-response-parameter } -## Использование параметра `Response` - -Вы можете объявить параметр типа `Response` в вашей функции эндпоинта. +Вы можете объявить параметр типа `Response` в вашей функции-обработчике пути. Затем установить cookies в этом временном объекте ответа. @@ -13,36 +12,40 @@ Если вы указали `response_model`, он всё равно будет использоваться для фильтрации и преобразования возвращаемого объекта. -**FastAPI** извлечет cookies (а также заголовки и коды состояния) из временного ответа и включит их в окончательный ответ, содержащий ваше возвращаемое значение, отфильтрованное через `response_model`. +**FastAPI** извлечет cookies (а также HTTP-заголовки и статус-код) из временного ответа и включит их в окончательный ответ, содержащий ваше возвращаемое значение, отфильтрованное через `response_model`. -Вы также можете объявить параметр типа Response в зависимостях и устанавливать cookies (и заголовки) там. +Вы также можете объявить параметр типа `Response` в зависимостях и устанавливать cookies (и HTTP-заголовки) там. -## Возвращение `Response` напрямую +## Возвращение `Response` напрямую { #return-a-response-directly } -Вы также можете установить cookies, если возвращаете `Response` напрямую в вашем коде. +Вы также можете установить Cookies, если возвращаете `Response` напрямую в вашем коде. -Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md){.target=_blank}. +Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md){.internal-link target=_blank}. Затем установите cookies и верните этот объект: {* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *} -/// tip | Примечание -Имейте в виду, что если вы возвращаете ответ напрямую, вместо использования параметра `Response`, **FastAPI** отправит его без дополнительной обработки. +/// tip | Совет -Убедитесь, что ваши данные имеют корректный тип. Например, они должны быть совместимы с JSON, если вы используете `JSONResponse`. +Имейте в виду, что если вы возвращаете ответ напрямую, вместо использования параметра `Response`, FastAPI вернёт его напрямую. + +Убедитесь, что ваши данные имеют корректный тип. Например, они должны быть совместимы с JSON, если вы возвращаете `JSONResponse`. Также убедитесь, что вы не отправляете данные, которые должны были быть отфильтрованы через `response_model`. + /// -### Дополнительная информация +### Дополнительная информация { #more-info } /// note | Технические детали + Вы также можете использовать `from starlette.responses import Response` или `from starlette.responses import JSONResponse`. **FastAPI** предоставляет `fastapi.responses`, которые являются теми же объектами, что и `starlette.responses`, просто для удобства. Однако большинство доступных типов ответов поступает непосредственно из **Starlette**. -Для установки заголовков и cookies `Response` используется часто, поэтому **FastAPI** также предоставляет его через `fastapi.responses`. +И так как `Response` часто используется для установки HTTP-заголовков и cookies, **FastAPI** также предоставляет его как `fastapi.Response`. + /// Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с документацией Starlette. diff --git a/docs/ru/docs/advanced/response-directly.md b/docs/ru/docs/advanced/response-directly.md index ee83d22b1..febd40ed4 100644 --- a/docs/ru/docs/advanced/response-directly.md +++ b/docs/ru/docs/advanced/response-directly.md @@ -1,4 +1,4 @@ -# Возврат ответа напрямую +# Возврат ответа напрямую { #return-a-response-directly } Когда вы создаёте **FastAPI** *операцию пути*, вы можете возвращать из неё любые данные: `dict`, `list`, Pydantic-модель, модель базы данных и т.д. @@ -8,9 +8,9 @@ Но вы можете возвращать `JSONResponse` напрямую из ваших *операций пути*. -Это может быть полезно, например, если нужно вернуть пользовательские заголовки или куки. +Это может быть полезно, например, если нужно вернуть пользовательские HTTP-заголовки или cookie. -## Возврат `Response` +## Возврат `Response` { #return-a-response } На самом деле, вы можете возвращать любой объект `Response` или его подкласс. @@ -26,7 +26,7 @@ Это даёт вам большую гибкость. Вы можете возвращать любые типы данных, переопределять любые объявления или валидацию данных и т.д. -## Использование `jsonable_encoder` в `Response` +## Использование `jsonable_encoder` в `Response` { #using-the-jsonable-encoder-in-a-response } Поскольку **FastAPI** не изменяет объект `Response`, который вы возвращаете, вы должны убедиться, что его содержимое готово к отправке. @@ -44,7 +44,7 @@ /// -## Возврат пользовательского `Response` +## Возврат пользовательского `Response` { #returning-a-custom-response } Пример выше показывает все необходимые части, но он пока не очень полезен, так как вы могли бы просто вернуть `item` напрямую, и **FastAPI** поместил бы его в `JSONResponse`, преобразовав в `dict` и т.д. Всё это происходит по умолчанию. @@ -56,7 +56,7 @@ {* ../../docs_src/response_directly/tutorial002.py hl[1,18] *} -## Примечания +## Примечания { #notes } Когда вы возвращаете объект `Response` напрямую, его данные не валидируются, не преобразуются (не сериализуются) и не документируются автоматически. diff --git a/docs/ru/docs/advanced/websockets.md b/docs/ru/docs/advanced/websockets.md index bc9dfcbff..b73fa1ddb 100644 --- a/docs/ru/docs/advanced/websockets.md +++ b/docs/ru/docs/advanced/websockets.md @@ -1,10 +1,10 @@ -# Веб-сокеты +# Веб-сокеты { #websockets } Вы можете использовать веб-сокеты в **FastAPI**. -## Установка `WebSockets` +## Установка `websockets` { #install-websockets } -Убедитесь, что [виртуальная среда](../virtual-environments.md){.internal-link target=_blank} создана, активируйте её и установите `websockets`: +Убедитесь, что вы создали [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активировали его и установили `websockets` (библиотека Python, упрощающая работу с протоколом "WebSocket"):
-## Обработка отключений и работа с несколькими клиентами
+## Обработка отключений и работа с несколькими клиентами { #handling-disconnections-and-multiple-clients }
Если веб-сокет соединение закрыто, то `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере:
@@ -168,7 +168,7 @@ $ fastapi dev main.py
Client #1596980209979 left the chat
```
-/// tip | Примечание
+/// tip | Подсказка
Приложение выше - это всего лишь простой минимальный пример, демонстрирующий обработку и передачу сообщений нескольким веб-сокет соединениям.
@@ -178,7 +178,7 @@ Client #1596980209979 left the chat
///
-## Дополнительная информация
+## Дополнительная информация { #more-info }
Для более глубокого изучения темы воспользуйтесь документацией Starlette:
diff --git a/docs/ru/docs/alternatives.md b/docs/ru/docs/alternatives.md
index 3c5147e79..6380bcc45 100644
--- a/docs/ru/docs/alternatives.md
+++ b/docs/ru/docs/alternatives.md
@@ -1,104 +1,94 @@
-# Альтернативы, источники вдохновения и сравнения
+# Альтернативы, источники вдохновения и сравнения { #alternatives-inspiration-and-comparisons }
-Что вдохновило на создание **FastAPI**, сравнение его с альтернативами и чему он научился у них.
+Что вдохновило **FastAPI**, сравнение с альтернативами и чему он у них научился.
-## Введение
+## Введение { #intro }
-**FastAPI** не существовал бы, если б не было более ранних работ других людей.
+**FastAPI** не существовал бы без предыдущих работ других людей.
-Они создали большое количество инструментов, которые вдохновили меня на создание **FastAPI**.
+Было создано множество инструментов, которые вдохновили на его появление.
-Я всячески избегал создания нового фреймворка в течение нескольких лет.
-Сначала я пытался собрать все нужные функции, которые ныне есть в **FastAPI**, используя множество различных фреймворков, плагинов и инструментов.
+Я несколько лет избегал создания нового фреймворка. Сначала пытался закрыть все возможности, которые сейчас предоставляет **FastAPI**, с помощью множества разных фреймворков, плагинов и инструментов.
-Но в какой-то момент не осталось другого выбора, кроме как создать что-то, что предоставляло бы все эти функции сразу.
-Взять самые лучшие идеи из предыдущих инструментов и, используя новые возможности Python (которых не было до версии 3.6, то есть подсказки типов), объединить их.
+Но в какой-то момент не осталось другого варианта, кроме как создать что-то, что включает все эти возможности, взяв лучшие идеи из прежних инструментов и совместив их максимально удачным образом, используя возможности языка, которых прежде не было (аннотации типов в Python 3.6+).
-## Предшествующие инструменты
+## Предшествующие инструменты { #previous-tools }
-### Django
+### Django { #django }
-Это самый популярный Python-фреймворк, и он пользуется доверием.
-Он используется для создания проектов типа Instagram.
+Это самый популярный Python-фреймворк, ему широко доверяют. Он используется для построения систем вроде Instagram.
-Django довольно тесно связан с реляционными базами данных (такими как MySQL или PostgreSQL), потому использовать NoSQL базы данных (например, Couchbase, MongoDB, Cassandra и т.п.) в качестве основного хранилища данных - непросто.
+Он относительно тесно связан с реляционными базами данных (например, MySQL или PostgreSQL), поэтому использовать NoSQL-базу данных (например, Couchbase, MongoDB, Cassandra и т. п.) в качестве основного хранилища не очень просто.
-Он был создан для генерации HTML-страниц на сервере, а не для создания API, используемых современными веб-интерфейсами (React, Vue.js, Angular и т.п.) или другими системами (например, IoT) взаимодействующими с сервером.
+Он был создан для генерации HTML на бэкенде, а не для создания API, используемых современным фронтендом (например, React, Vue.js и Angular) или другими системами (например, устройствами IoT), которые с ним общаются.
-### Django REST Framework
+### Django REST Framework { #django-rest-framework }
-Фреймворк Django REST был создан, как гибкий инструментарий для создания веб-API на основе Django.
+Django REST Framework был создан как гибкий набор инструментов для построения веб-API поверх Django, чтобы улучшить его возможности в части API.
-DRF использовался многими компаниями, включая Mozilla, Red Hat и Eventbrite.
+Он используется многими компаниями, включая Mozilla, Red Hat и Eventbrite.
-Это был один из первых примеров **автоматического документирования API** и это была одна из первых идей, вдохновивших на создание **FastAPI**.
+Это был один из первых примеров **автоматической документации API**, и именно эта идея одной из первых вдохновила на «поиск» **FastAPI**.
/// note | Заметка
-Django REST Framework был создан Tom Christie.
-Он же создал Starlette и Uvicorn, на которых основан **FastAPI**.
+Django REST Framework был создан Томом Кристи. Он же создал Starlette и Uvicorn, на которых основан **FastAPI**.
///
-/// check | Идея для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Должно быть автоматическое создание документации API с пользовательским веб-интерфейсом.
+Наличие пользовательского веб-интерфейса с автоматической документацией API.
///
-### Flask
+### Flask { #flask }
-Flask - это "микрофреймворк", в нём нет интеграции с базами данных и многих других вещей, которые предустановлены в Django.
+Flask — это «микрофреймворк», он не включает интеграции с базами данных и многие другие вещи, которые в Django идут «из коробки».
-Его простота и гибкость дают широкие возможности, такие как использование баз данных NoSQL в качестве основной системы хранения данных.
+Эта простота и гибкость позволяет, например, использовать NoSQL-базы в качестве основной системы хранения данных.
-Он очень прост, его изучение интуитивно понятно, хотя в некоторых местах документация довольно техническая.
+Он очень прост, его относительно легко интуитивно освоить, хотя местами документация довольно техническая.
-Flask часто используется и для приложений, которым не нужна база данных, настройки прав доступа для пользователей и прочие из множества функций, предварительно встроенных в Django.
-Хотя многие из этих функций могут быть добавлены с помощью плагинов.
+Его также часто используют для приложений, которым не нужна база данных, управление пользователями или многие другие функции, предварительно встроенные в Django. Хотя многие из этих возможностей можно добавить плагинами.
-Такое разделение на части и то, что это "микрофреймворк", который можно расширить, добавляя необходимые возможности, было ключевой особенностью, которую я хотел сохранить.
+Такое разбиение на части и то, что это «микрофреймворк», который можно расширять ровно под нужды, — ключевая особенность, которую хотелось сохранить.
-Простота Flask, показалась мне подходящей для создания API.
-Но ещё нужно было найти "Django REST Framework" для Flask.
+С учётом простоты Flask он казался хорошим вариантом для создания API. Следующим было найти «Django REST Framework» для Flask.
-/// check | Идеи для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Это будет микрофреймворк. К нему легко будет добавить необходимые инструменты и части.
+Быть микро-фреймворком. Облегчить комбинирование необходимых инструментов и компонентов.
-Должна быть простая и лёгкая в использовании система маршрутизации запросов.
+Иметь простую и удобную систему маршрутизации.
///
-### Requests
+### Requests { #requests }
-На самом деле **FastAPI** не является альтернативой **Requests**.
-Их область применения очень разная.
+**FastAPI** на самом деле не альтернатива **Requests**. Их области применения очень различны.
-В принципе, можно использовать Requests *внутри* приложения FastAPI.
+Обычно Requests используют даже внутри приложения FastAPI.
-Но всё же я использовал в FastAPI некоторые идеи из Requests.
+И всё же **FastAPI** во многом вдохновлялся Requests.
-**Requests** - это библиотека для взаимодействия с API в качестве клиента,
-в то время как **FastAPI** - это библиотека для *создания* API (то есть сервера).
+**Requests** — это библиотека для взаимодействия с API (как клиент), а **FastAPI** — библиотека для создания API (как сервер).
-Они, так или иначе, диаметрально противоположны и дополняют друг друга.
+Они, в каком-то смысле, находятся на противоположных концах и дополняют друг друга.
-Requests имеет очень простой и понятный дизайн, очень прост в использовании и имеет разумные значения по умолчанию.
-И в то же время он очень мощный и настраиваемый.
+Requests имеет очень простой и понятный дизайн, им очень легко пользоваться, есть разумные значения по умолчанию. И при этом он очень мощный и настраиваемый.
-Вот почему на официальном сайте написано:
+Именно поэтому на официальном сайте сказано:
-> Requests - один из самых загружаемых пакетов Python всех времен
+> Requests — один из самых загружаемых Python-пакетов всех времён
-
-Использовать его очень просто. Например, чтобы выполнить запрос `GET`, Вы бы написали:
+Пользоваться им очень просто. Например, чтобы сделать запрос `GET`, вы бы написали:
```Python
response = requests.get("http://example.com/some/url")
```
-Противоположная *операция пути* в FastAPI может выглядеть следующим образом:
+Соответствующая в FastAPI API-операция пути могла бы выглядеть так:
```Python hl_lines="1"
@app.get("/some/url")
@@ -106,428 +96,390 @@ def read_url():
return {"message": "Hello World"}
```
-Глядите, как похоже `requests.get(...)` и `@app.get(...)`.
+Посмотрите, насколько похожи `requests.get(...)` и `@app.get(...)`.
-/// check | Идеи для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-* Должен быть простой и понятный API.
-* Нужно использовать названия HTTP-методов (операций) для упрощения понимания происходящего.
-* Должны быть разумные настройки по умолчанию и широкие возможности их кастомизации.
+* Иметь простой и понятный API.
+* Использовать названия HTTP-методов (операций) напрямую, простым и интуитивным образом.
+* Иметь разумные значения по умолчанию, но и мощные настройки.
///
-### Swagger / OpenAPI
+### Swagger / OpenAPI { #swagger-openapi }
-Главной функцией, которую я хотел унаследовать от Django REST Framework, была автоматическая документация API.
+Главной возможностью, которую хотелось взять из Django REST Framework, была автоматическая документация API.
-Но потом я обнаружил, что существует стандарт документирования API, использующий JSON (или YAML, расширение JSON) под названием Swagger.
+Затем я обнаружил, что есть стандарт для документирования API с использованием JSON (или YAML — расширения JSON), под названием Swagger.
-И к нему уже был создан пользовательский веб-интерфейс.
-Таким образом, возможность генерировать документацию Swagger для API позволила бы использовать этот интерфейс.
+И уже существовал веб-интерфейс для Swagger API. Поэтому возможность генерировать документацию Swagger для API позволила бы автоматически использовать этот веб-интерфейс.
В какой-то момент Swagger был передан Linux Foundation и переименован в OpenAPI.
-Вот почему, когда говорят о версии 2.0, обычно говорят "Swagger", а для версии 3+ "OpenAPI".
+Вот почему, говоря о версии 2.0, обычно говорят «Swagger», а о версии 3+ — «OpenAPI».
-/// check | Идеи для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Использовать открытые стандарты для спецификаций API вместо самодельных схем.
+Использовать открытый стандарт для спецификаций API вместо самодельной схемы.
-Совместимость с основанными на стандартах пользовательскими интерфейсами:
+И интегрировать основанные на стандартах инструменты пользовательского интерфейса:
* Swagger UI
* ReDoc
-Они были выбраны за популярность и стабильность.
-Но сделав беглый поиск, Вы можете найти десятки альтернативных пользовательских интерфейсов для OpenAPI, которые Вы можете использовать с **FastAPI**.
+Эти два инструмента выбраны за популярность и стабильность, но даже при беглом поиске можно найти десятки альтернативных интерфейсов для OpenAPI (которые можно использовать с **FastAPI**).
///
-### REST фреймворки для Flask
+### REST-фреймворки для Flask { #flask-rest-frameworks }
-Существует несколько REST фреймворков для Flask, но потратив время и усилия на их изучение, я обнаружил, что многие из них не обновляются или заброшены и имеют нерешённые проблемы из-за которых они непригодны к использованию.
+Существует несколько REST-фреймворков для Flask, но, вложив время и усилия в исследование, я обнаружил, что многие из них прекращены или заброшены, с несколькими нерешёнными Issue (тикет\обращение), из-за которых они непригодны.
-### Marshmallow
+### Marshmallow { #marshmallow }
-Одной из основных функций, необходимых системам API, является "сериализация" данных, то есть преобразование данных из кода (Python) во что-то, что может быть отправлено по сети.
-Например, превращение объекта содержащего данные из базы данных в объект JSON, конвертация объекта `datetime` в строку и т.п.
+Одна из основных возможностей, нужных системам API, — «сериализация» данных, то есть преобразование данных из кода (Python) во что-то, что можно отправить по сети. Например, преобразование объекта с данными из базы в JSON-объект. Преобразование объектов `datetime` в строки и т. п.
-Еще одна важная функция, необходимая API — проверка данных, позволяющая убедиться, что данные действительны и соответствуют заданным параметрам.
-Как пример, можно указать, что ожидаются данные типа `int`, а не какая-то произвольная строка.
-Это особенно полезно для входящих данных.
+Ещё одна важная возможность, востребованная API, — валидация данных: убеждаться, что данные валидны с учётом заданных параметров. Например, что какое-то поле — `int`, а не произвольная строка. Это особенно полезно для входящих данных.
-Без системы проверки данных Вам пришлось бы прописывать все проверки вручную.
+Без системы валидации данных вам пришлось бы выполнять все проверки вручную в коде.
-Именно для обеспечения этих функций и была создана Marshmallow.
-Это отличная библиотека и я много раз пользовался ею раньше.
+Именно для этих возможностей и был создан Marshmallow. Это отличная библиотека, я много ей пользовался раньше.
-Но она была создана до того, как появились подсказки типов Python.
-Итак, чтобы определить каждую схему,
-Вам нужно использовать определенные утилиты и классы, предоставляемые Marshmallow.
+Но она появилась до того, как в Python появились аннотации типов. Поэтому для определения каждой схемы нужно использовать специальные утилиты и классы, предоставляемые Marshmallow.
-/// check | Идея для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Использовать код программы для автоматического создания "схем", определяющих типы данных и их проверку.
+Использовать код для автоматического определения «схем», задающих типы данных и их валидацию.
///
-### Webargs
+### Webargs { #webargs }
-Другая немаловажная функция API - парсинг данных из входящих запросов.
+Ещё одна важная возможность для API — парсинг данных из входящих HTTP-запросов.
-Webargs - это инструмент, который был создан для этого и поддерживает несколько фреймворков, включая Flask.
+Webargs — это инструмент, созданный для этого поверх нескольких фреймворков, включая Flask.
-Для проверки данных он использует Marshmallow и создан теми же авторами.
+Он использует Marshmallow для валидации данных. И создан теми же разработчиками.
-Это превосходный инструмент и я тоже часто пользовался им до **FastAPI**.
+Это отличный инструмент, и я тоже много им пользовался до появления **FastAPI**.
/// info | Информация
-Webargs бы создан разработчиками Marshmallow.
+Webargs был создан теми же разработчиками, что и Marshmallow.
///
-/// check | Идея для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Должна быть автоматическая проверка входных данных.
+Автоматическую валидацию входящих данных HTTP-запроса.
///
-### APISpec
+### APISpec { #apispec }
-Marshmallow и Webargs осуществляют проверку, анализ и сериализацию данных как плагины.
+Marshmallow и Webargs предоставляют валидацию, парсинг и сериализацию как плагины.
-Но документации API всё ещё не было. Тогда был создан APISpec.
+Но документации всё ещё не было. Тогда появился APISpec.
-Это плагин для множества фреймворков, в том числе и для Starlette.
+Это плагин для многих фреймворков (есть плагин и для Starlette).
-Он работает так - Вы записываете определение схем, используя формат YAML, внутри докстринга каждой функции, обрабатывающей маршрут.
+Он работает так: вы пишете определение схемы в формате YAML внутри докстринга каждой функции, обрабатывающей маршрут.
-Используя эти докстринги, он генерирует схему OpenAPI.
+И он генерирует схемы OpenAPI.
-Так это работает для Flask, Starlette, Responder и т.п.
+Так это работает во Flask, Starlette, Responder и т. д.
-Но теперь у нас возникает новая проблема - наличие постороннего микро-синтаксиса внутри кода Python (большие YAML).
+Но у нас снова возникает проблема: появляется микро-синтаксис внутри строки Python (большой YAML).
-Редактор кода не особо может помочь в такой парадигме.
-А изменив какие-то параметры или схемы для Marshmallow можно забыть отредактировать докстринг с YAML и сгенерированная схема становится недействительной.
+Редактор кода мало чем может помочь. И если мы изменим параметры или схемы Marshmallow и забудем также изменить YAML в докстринге, сгенерированная схема устареет.
/// info | Информация
-APISpec тоже был создан авторами Marshmallow.
+APISpec был создан теми же разработчиками, что и Marshmallow.
///
-/// check | Идея для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Необходима поддержка открытого стандарта для API - OpenAPI.
+Поддержку открытого стандарта для API — OpenAPI.
///
-### Flask-apispec
+### Flask-apispec { #flask-apispec }
-Это плагин для Flask, который связан с Webargs, Marshmallow и APISpec.
+Это плагин для Flask, который связывает Webargs, Marshmallow и APISpec.
-Он получает информацию от Webargs и Marshmallow, а затем использует APISpec для автоматического создания схемы OpenAPI.
+Он использует информацию из Webargs и Marshmallow, чтобы автоматически генерировать схемы OpenAPI с помощью APISpec.
-Это отличный, но крайне недооценённый инструмент.
-Он должен быть более популярен, чем многие плагины для Flask.
-Возможно, это связано с тем, что его документация слишком скудна и абстрактна.
+Отличный и недооценённый инструмент. Он заслуживает большей популярности, чем многие плагины для Flask. Возможно, из-за слишком краткой и абстрактной документации.
-Он избавил от необходимости писать чужеродный синтаксис YAML внутри докстрингов.
+Это решило проблему необходимости писать YAML (ещё один синтаксис) в докстрингах Python.
-Такое сочетание Flask, Flask-apispec, Marshmallow и Webargs было моим любимым стеком при построении бэкенда до появления **FastAPI**.
+Комбинация Flask, Flask-apispec с Marshmallow и Webargs была моим любимым бэкенд-стеком до создания **FastAPI**.
-Использование этого стека привело к созданию нескольких генераторов проектов. Я и некоторые другие команды до сих пор используем их:
+Его использование привело к созданию нескольких full-stack генераторов на Flask. Это основные стеки, которые я (и несколько внешних команд) использовали до сих пор:
* https://github.com/tiangolo/full-stack
* https://github.com/tiangolo/full-stack-flask-couchbase
* https://github.com/tiangolo/full-stack-flask-couchdb
-Эти генераторы проектов также стали основой для [Генераторов проектов с **FastAPI**](project-generation.md){.internal-link target=_blank}.
+И эти же full-stack генераторы стали основой для [Генераторов проектов **FastAPI**](project-generation.md){.internal-link target=_blank}.
/// info | Информация
-Как ни странно, но Flask-apispec тоже создан авторами Marshmallow.
+Flask-apispec был создан теми же разработчиками, что и Marshmallow.
///
-/// check | Идея для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Схема OpenAPI должна создаваться автоматически и использовать тот же код, который осуществляет сериализацию и проверку данных.
+Автоматическую генерацию схемы OpenAPI из того же кода, который определяет сериализацию и валидацию.
///
-### NestJS (и Angular)
+### NestJS (и Angular) { #nestjs-and-angular }
-Здесь даже не используется Python. NestJS - этот фреймворк написанный на JavaScript (TypeScript), основанный на NodeJS и вдохновлённый Angular.
+Это даже не Python. NestJS — это JavaScript/TypeScript-фреймворк на NodeJS, вдохновлённый Angular.
-Он позволяет получить нечто похожее на то, что можно сделать с помощью Flask-apispec.
+Он достигает чего-то отчасти похожего на то, что можно сделать с Flask-apispec.
-В него встроена система внедрения зависимостей, ещё одна идея взятая от Angular.
-Однако требуется предварительная регистрация "внедрений" (как и во всех других известных мне системах внедрения зависимостей), что увеличивает количество и повторяемость кода.
+В нём встроена система внедрения зависимостей, вдохновлённая Angular 2. Требуется предварительная регистрация «инжектируемых» компонентов (как и во всех известных мне системах внедрения зависимостей), что добавляет многословности и повторяемости кода.
-Так как параметры в нём описываются с помощью типов TypeScript (аналогично подсказкам типов в Python), поддержка редактора работает довольно хорошо.
+Поскольку параметры описываются с помощью типов TypeScript (аналог аннотаций типов в Python), поддержка редактора весьма хороша.
-Но поскольку данные из TypeScript не сохраняются после компиляции в JavaScript, он не может полагаться на подсказки типов для определения проверки данных, сериализации и документации.
-Из-за этого и некоторых дизайнерских решений, для валидации, сериализации и автоматической генерации схем, приходится во многих местах добавлять декораторы.
-Таким образом, это становится довольно многословным.
+Но так как данные о типах TypeScript не сохраняются после компиляции в JavaScript, он не может полагаться на типы для одновременного определения валидации, сериализации и документации. Из‑за этого и некоторых проектных решений для получения валидации, сериализации и автоматической генерации схем приходится добавлять декораторы во многих местах. В итоге это становится довольно многословным.
-Кроме того, он не очень хорошо справляется с вложенными моделями.
-Если в запросе имеется объект JSON, внутренние поля которого, в свою очередь, являются вложенными объектами JSON, это не может быть должным образом задокументировано и проверено.
+Он плохо справляется с вложенными моделями. Если JSON-тело запроса — это объект JSON, содержащий внутренние поля, которые сами являются вложенными объектами JSON, это нельзя как следует задокументировать и провалидировать.
-/// check | Идеи для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Нужно использовать подсказки типов, чтоб воспользоваться поддержкой редактора кода.
+Использовать типы Python для отличной поддержки в редакторе кода.
-Нужна мощная система внедрения зависимостей. Необходим способ для уменьшения повторов кода.
+Иметь мощную систему внедрения зависимостей. Найти способ минимизировать повторение кода.
///
-### Sanic
+### Sanic { #sanic }
-Sanic был одним из первых чрезвычайно быстрых Python-фреймворков основанных на `asyncio`.
-Он был сделан очень похожим на Flask.
+Это был один из первых чрезвычайно быстрых Python-фреймворков на основе `asyncio`. Он был сделан очень похожим на Flask.
/// note | Технические детали
-В нём использован `uvloop` вместо стандартного цикла событий `asyncio`, что и сделало его таким быстрым.
+Он использовал `uvloop` вместо стандартного цикла `asyncio` в Python. Это и сделало его таким быстрым.
-Он явно вдохновил создателей Uvicorn и Starlette, которые в настоящее время быстрее Sanic в открытых бенчмарках.
+Он явно вдохновил Uvicorn и Starlette, которые сейчас быстрее Sanic в открытых бенчмарках.
///
-/// check | Идеи для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Должна быть сумасшедшая производительность.
+Поиск способа достичь сумасшедшей производительности.
-Для этого **FastAPI** основан на Starlette, самом быстром из доступных фреймворков (по замерам незаинтересованных лиц).
+Именно поэтому **FastAPI** основан на Starlette, так как это самый быстрый доступный фреймворк (по данным сторонних бенчмарков).
///
-### Falcon
+### Falcon { #falcon }
-Falcon - ещё один высокопроизводительный Python-фреймворк.
-В нём минимум функций и он создан, чтоб быть основой для других фреймворков, например, Hug.
+Falcon — ещё один высокопроизводительный Python-фреймворк, он минималистичен и служит основой для других фреймворков, таких как Hug.
-Функции в нём получают два параметра - "запрос к серверу" и "ответ сервера".
-Затем Вы "читаете" часть запроса и "пишите" часть ответа.
-Из-за такой конструкции невозможно объявить параметры запроса и тела сообщения со стандартными подсказками типов Python в качестве параметров функции.
+Он спроектирован так, что функции получают два параметра: «request» и «response». Затем вы «читаете» части из запроса и «пишете» части в ответ. Из‑за такого дизайна невозможно объявить параметры запроса и тело запроса стандартными аннотациями типов Python как параметры функции.
-Таким образом, и валидацию данных, и их сериализацию, и документацию нужно прописывать вручную.
-Либо эти функции должны быть встроены во фреймворк, сконструированный поверх Falcon, как в Hug.
-Такая же особенность присутствует и в других фреймворках, вдохновлённых идеей Falcon, использовать только один объект запроса и один объект ответа.
+Поэтому валидация данных, сериализация и документация должны выполняться в коде вручную, не автоматически. Либо должны быть реализованы во фреймворке поверх Falcon, как в Hug. Та же особенность есть и в других фреймворках, вдохновлённых дизайном Falcon — с одним объектом запроса и одним объектом ответа в параметрах.
-/// check | Идея для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Найдите способы добиться отличной производительности.
+Поиск способов получить отличную производительность.
-Объявлять параметры `ответа сервера` в функциях, как в Hug.
+Вместе с Hug (так как Hug основан на Falcon) вдохновило **FastAPI** объявлять параметр `response` в функциях.
-Хотя в FastAPI это необязательно и используется в основном для установки заголовков, куки и альтернативных кодов состояния.
+Хотя в FastAPI это необязательно, и используется в основном для установки HTTP-заголовков, cookie и альтернативных статус-кодов.
///
-### Molten
+### Molten { #molten }
-Molten мне попался на начальной стадии написания **FastAPI**. В нём были похожие идеи:
+Я обнаружил Molten на ранних этапах создания **FastAPI**. И у него были очень похожие идеи:
-* Использование подсказок типов.
-* Валидация и документация исходя из этих подсказок.
+* Основан на аннотациях типов Python.
+* Валидация и документация из этих типов.
* Система внедрения зависимостей.
-В нём не используются сторонние библиотеки (такие, как Pydantic) для валидации, сериализации и документации.
-Поэтому переиспользовать эти определения типов непросто.
+Он не использует стороннюю библиотеку для валидации, сериализации и документации, такую как Pydantic, — у него своя. Поэтому такие определения типов данных будет сложнее переиспользовать.
-Также требуется более подробная конфигурация и используется стандарт WSGI, который не предназначен для использования с высокопроизводительными инструментами, такими как Uvicorn, Starlette и Sanic, в отличие от ASGI.
+Требуются более многословные конфигурации. И так как он основан на WSGI (вместо ASGI), он не предназначен для использования преимуществ высокой производительности инструментов вроде Uvicorn, Starlette и Sanic.
-Его система внедрения зависимостей требует предварительной регистрации, и зависимости определяются, как объявления типов.
-Из-за этого невозможно объявить более одного "компонента" (зависимости), который предоставляет определенный тип.
+Система внедрения зависимостей требует предварительной регистрации зависимостей, а зависимости разрешаются по объявленным типам. Поэтому невозможно объявить более одного «компонента», предоставляющего определённый тип.
-Маршруты объявляются в единственном месте с использованием функций, объявленных в других местах (вместо использования декораторов, в которые могут быть обёрнуты функции, обрабатывающие конкретные ресурсы).
-Это больше похоже на Django, чем на Flask и Starlette.
-Он разделяет в коде вещи, которые довольно тесно связаны.
+Маршруты объявляются в одном месте, используя функции, объявленные в других местах (вместо декораторов, которые можно разместить прямо над функцией, обрабатывающей эндпоинт). Это ближе к тому, как это делает Django, чем Flask (и Starlette). Это разделяет в коде вещи, которые довольно тесно связаны.
-/// check | Идея для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Определить дополнительные проверки типов данных, используя значения атрибутов модели "по умолчанию".
-Это улучшает помощь редактора и раньше это не было доступно в Pydantic.
+Определять дополнительные проверки типов данных, используя значение «по умолчанию» атрибутов модели. Это улучшает поддержку в редакторе кода, и раньше этого не было в Pydantic.
-Фактически это подтолкнуло на обновление Pydantic для поддержки одинакового стиля проверок (теперь этот функционал уже доступен в Pydantic).
+Фактически это вдохновило на обновление частей Pydantic, чтобы поддерживать такой же стиль объявления валидации (вся эта функциональность теперь уже есть в Pydantic).
///
-### Hug
+### Hug { #hug }
-Hug был одним из первых фреймворков, реализовавших объявление параметров API с использованием подсказок типов Python.
-Эта отличная идея была использована и другими инструментами.
+Hug был одним из первых фреймворков, реализовавших объявление типов параметров API с использованием аннотаций типов Python. Это была отличная идея, которая вдохновила и другие инструменты.
-При объявлении параметров вместо стандартных типов Python использовались собственные типы, но всё же это был огромный шаг вперед.
+Он использовал собственные типы в объявлениях вместо стандартных типов Python, но это всё равно был огромный шаг вперёд.
-Это также был один из первых фреймворков, генерировавших полную API-схему в формате JSON.
+Он также был одним из первых фреймворков, генерировавших собственную схему, описывающую весь API в JSON.
-Данная схема не придерживалась стандартов вроде OpenAPI и JSON Schema.
-Поэтому было бы непросто совместить её с другими инструментами, такими как Swagger UI.
-Но опять же, это была очень инновационная идея.
+Он не был основан на стандартах вроде OpenAPI и JSON Schema. Поэтому интегрировать его с другими инструментами, такими как Swagger UI, было бы непросто. Но, опять же, это была очень инновационная идея.
-Ещё у него есть интересная и необычная функция: используя один и тот же фреймворк можно создавать и API, и CLI.
+У него есть интересная и необычная особенность: с помощью одного и того же фреймворка можно создавать и API, и CLI.
-Поскольку он основан на WSGI, старом стандарте для синхронных веб-фреймворков, он не может работать с веб-сокетами и другими модными штуками, но всё равно обладает высокой производительностью.
+Так как он основан на предыдущем стандарте для синхронных веб-фреймворков Python (WSGI), он не может работать с WebSocket и прочим, хотя также демонстрирует высокую производительность.
/// info | Информация
-Hug создан Timothy Crosley, автором `isort`, отличного инструмента для автоматической сортировки импортов в Python-файлах.
+Hug был создан Тимоти Кросли, тем же автором `isort`, отличного инструмента для автоматической сортировки импортов в файлах Python.
///
-/// check | Идеи для **FastAPI**
+/// check | Идеи, вдохновившие **FastAPI**
-Hug повлиял на создание некоторых частей APIStar и был одним из инструментов, которые я счел наиболее многообещающими, наряду с APIStar.
+Hug вдохновил части APIStar и был одним из наиболее многообещающих инструментов, которые я нашёл, наряду с APIStar.
-Hug натолкнул на мысли использовать в **FastAPI** подсказки типов Python для автоматического создания схемы, определяющей API и его параметры.
+Hug помог вдохновить **FastAPI** использовать аннотации типов Python для объявления параметров и автоматически генерировать схему, определяющую API.
-Hug вдохновил **FastAPI** объявить параметр `ответа` в функциях для установки заголовков и куки.
+Hug вдохновил **FastAPI** объявлять параметр `response` в функциях для установки HTTP-заголовков и cookie.
///
-### APIStar (<= 0.5)
+### APIStar (<= 0.5) { #apistar-0-5 }
-Непосредственно перед тем, как принять решение о создании **FastAPI**, я обнаружил **APIStar**.
-В нем было почти все, что я искал и у него был отличный дизайн.
+Прямо перед решением строить **FastAPI** я нашёл сервер **APIStar**. В нём было почти всё, что я искал, и отличный дизайн.
-Это была одна из первых реализаций фреймворка, использующего подсказки типов для объявления параметров и запросов, которые я когда-либо видел (до NestJS и Molten).
-Я нашёл его примерно в то же время, что и Hug, но APIStar использовал стандарт OpenAPI.
+Это была одна из первых реализаций фреймворка, использующего аннотации типов Python для объявления параметров и запросов (до NestJS и Molten), которые я видел. Я обнаружил его примерно в то же время, что и Hug. Но APIStar использовал стандарт OpenAPI.
-В нём были автоматические проверка и сериализация данных и генерация схемы OpenAPI основанные на подсказках типов в нескольких местах.
+В нём были автоматические валидация данных, сериализация данных и генерация схемы OpenAPI на основе тех же аннотаций типов в нескольких местах.
-При определении схемы тела сообщения не использовались подсказки типов, как в Pydantic, это больше похоже на Marshmallow, поэтому помощь редактора была недостаточно хорошей, но всё же APIStar был лучшим доступным вариантом.
+Определение схемы тела запроса не использовало те же аннотации типов Python, как в Pydantic, — это было ближе к Marshmallow, поэтому поддержка редактора была бы хуже, но всё равно APIStar оставался лучшим доступным вариантом.
-На тот момент у него были лучшие показатели производительности (проигрывающие только Starlette).
+На тот момент у него были лучшие показатели в бенчмарках (его превосходил только Starlette).
-Изначально у него не было автоматической документации API для веб-интерфейса, но я знал, что могу добавить к нему Swagger UI.
+Сначала у него не было веб‑UI для автоматической документации API, но я знал, что могу добавить к нему Swagger UI.
-В APIStar была система внедрения зависимостей, которая тоже требовала предварительную регистрацию компонентов, как и ранее описанные инструменты.
-Но, тем не менее, это была отличная штука.
+У него была система внедрения зависимостей. Она требовала предварительной регистрации компонентов, как и другие инструменты, обсуждавшиеся выше. Но всё же это была отличная возможность.
-Я не смог использовать его в полноценном проекте, так как были проблемы со встраиванием функций безопасности в схему OpenAPI, из-за которых невозможно было встроить все функции, применяемые в генераторах проектов на основе Flask-apispec.
-Я добавил в свой список задач создание пул-реквеста, добавляющего эту функциональность.
+Мне так и не удалось использовать его в полном проекте, поскольку не было интеграции с системой безопасности, поэтому я не мог заменить все возможности, которые имел с full-stack генераторами на основе Flask-apispec. В моём бэклоге было создать пулл-реквест (запрос на изменение), добавляющий эту функциональность.
-В дальнейшем фокус проекта сместился.
+Затем фокус проекта сместился.
-Это больше не был API-фреймворк, так как автор сосредоточился на Starlette.
+Это перестал быть веб-фреймворк для API, так как автору нужно было сосредоточиться на Starlette.
-Ныне APIStar - это набор инструментов для проверки спецификаций OpenAPI.
+Сейчас APIStar — это набор инструментов для валидации спецификаций OpenAPI, а не веб-фреймворк.
/// info | Информация
-APIStar был создан Tom Christie. Тот самый парень, который создал:
+APIStar был создан Томом Кристи. Тем самым человеком, который создал:
* Django REST Framework
* Starlette (на котором основан **FastAPI**)
-* Uvicorn (используемый в Starlette и **FastAPI**)
+* Uvicorn (используется Starlette и **FastAPI**)
///
-/// check | Идеи для **FastAPI**
+/// check | Вдохновило **FastAPI** на
-Воплощение.
+Существование.
-Мне казалось блестящей идеей объявлять множество функций (проверка данных, сериализация, документация) с помощью одних и тех же типов Python, которые при этом обеспечивают ещё и помощь редактора кода.
+Идея объявлять сразу несколько вещей (валидацию данных, сериализацию и документацию) с помощью одних и тех же типов Python, которые одновременно обеспечивают отличную поддержку в редакторе кода, показалась мне блестящей.
-После долгих поисков среди похожих друг на друга фреймворков и сравнения их различий, APIStar стал самым лучшим выбором.
+После долгих поисков похожего фреймворка и тестирования множества альтернатив APIStar был лучшим доступным вариантом.
-Но APIStar перестал быть фреймворком для создания веб-сервера, зато появился Starlette, новая и лучшая основа для построения подобных систем.
-Это была последняя капля, сподвигнувшая на создание **FastAPI**.
+Затем APIStar перестал существовать как сервер, а был создан Starlette — новая и лучшая основа для такой системы. Это стало окончательным вдохновением для создания **FastAPI**.
-Я считаю **FastAPI** "духовным преемником" APIStar, улучившим его возможности благодаря урокам, извлечённым из всех упомянутых выше инструментов.
+Я считаю **FastAPI** «духовным преемником» APIStar, который улучшает и расширяет возможности, систему типов и другие части, опираясь на уроки от всех этих предыдущих инструментов.
///
-## Что используется в **FastAPI**
+## Что используется в **FastAPI** { #used-by-fastapi }
-### Pydantic
+### Pydantic { #pydantic }
-Pydantic - это библиотека для валидации данных, сериализации и документирования (используя JSON Schema), основываясь на подсказках типов Python, что делает его чрезвычайно интуитивным.
+Pydantic — это библиотека для определения валидации данных, сериализации и документации (с использованием JSON Schema) на основе аннотаций типов Python.
-Его можно сравнить с Marshmallow, хотя в бенчмарках Pydantic быстрее, чем Marshmallow.
-И он основан на тех же подсказках типов, которые отлично поддерживаются редакторами кода.
+Благодаря этому он чрезвычайно интуитивен.
-/// check | **FastAPI** использует Pydantic
+Его можно сравнить с Marshmallow. Хотя в бенчмарках он быстрее Marshmallow. И поскольку он основан на тех же аннотациях типов Python, поддержка в редакторе кода отличная.
-Для проверки данных, сериализации данных и автоматической документации моделей (на основе JSON Schema).
+/// check | **FastAPI** использует его для
-Затем **FastAPI** берёт эти схемы JSON и помещает их в схему OpenAPI, не касаясь других вещей, которые он делает.
+Обработки всей валидации данных, сериализации данных и автоматической документации моделей (на основе JSON Schema).
+
+Затем **FastAPI** берёт эти данные JSON Schema и помещает их в OpenAPI, помимо всех прочих функций.
///
-### Starlette
+### Starlette { #starlette }
-Starlette - это легковесный ASGI фреймворк/набор инструментов, который идеален для построения высокопроизводительных асинхронных сервисов.
+Starlette — это лёгкий ASGI фреймворк/набор инструментов, идеально подходящий для создания высокопроизводительных asyncio‑сервисов.
-Starlette очень простой и интуитивный.
-Он разработан таким образом, чтобы быть легко расширяемым и иметь модульные компоненты.
+Он очень простой и интуитивный. Спроектирован так, чтобы его было легко расширять, и чтобы компоненты были модульными.
В нём есть:
* Впечатляющая производительность.
-* Поддержка веб-сокетов.
-* Фоновые задачи.
-* Обработка событий при старте и финише приложения.
-* Тестовый клиент на основе HTTPX.
-* Поддержка CORS, сжатие GZip, статические файлы, потоковая передача данных.
-* Поддержка сессий и куки.
+* Поддержка WebSocket.
+* Фоновые задачи, выполняемые в том же процессе.
+* События запуска и завершения.
+* Тестовый клиент на базе HTTPX.
+* CORS, GZip, статические файлы, потоковые ответы.
+* Поддержка сессий и cookie.
* 100% покрытие тестами.
-* 100% аннотированный код.
-* Несколько жёстких зависимостей.
+* 100% кодовой базы с аннотациями типов.
+* Мало жёстких зависимостей.
-В настоящее время Starlette показывает самую высокую скорость среди Python-фреймворков в тестовых замерах.
-Быстрее только Uvicorn, который является сервером, а не фреймворком.
+В настоящее время Starlette — самый быстрый из протестированных Python-фреймворков. Его превосходит только Uvicorn, который не фреймворк, а сервер.
-Starlette обеспечивает весь функционал микрофреймворка, но не предоставляет автоматическую валидацию данных, сериализацию и документацию.
+Starlette предоставляет весь базовый функционал веб-микрофреймворка.
-**FastAPI** добавляет эти функции используя подсказки типов Python и Pydantic.
-Ещё **FastAPI** добавляет систему внедрения зависимостей, утилиты безопасности, генерацию схемы OpenAPI и т.д.
+Но он не предоставляет автоматическую валидацию данных, сериализацию или документацию.
+
+Это одна из главных вещей, которые **FastAPI** добавляет поверх, всё на основе аннотаций типов Python (с использованием Pydantic). Плюс система внедрения зависимостей, утилиты безопасности, генерация схемы OpenAPI и т. д.
/// note | Технические детали
-ASGI - это новый "стандарт" разработанный участниками команды Django.
-Он пока что не является "стандартом в Python" (то есть принятым PEP), но процесс принятия запущен.
+ASGI — это новый «стандарт», разрабатываемый участниками core-команды Django. Он всё ещё не является «стандартом Python» (PEP), хотя процесс идёт.
-Тем не менее он уже используется в качестве "стандарта" несколькими инструментами.
-Это значительно улучшает совместимость, поскольку Вы можете переключиться с Uvicorn на любой другой ASGI-сервер (например, Daphne или Hypercorn) или Вы можете добавить ASGI-совместимые инструменты, такие как `python-socketio`.
+Тем не менее его уже используют как «стандарт» несколько инструментов. Это сильно улучшает совместимость: вы можете заменить Uvicorn на любой другой ASGI-сервер (например, Daphne или Hypercorn) или добавить совместимые с ASGI инструменты, такие как `python-socketio`.
///
-/// check | **FastAPI** использует Starlette
+/// check | **FastAPI** использует его для
-В качестве ядра веб-сервиса для обработки запросов, добавив некоторые функции сверху.
+Обработки всех основных веб-частей. Добавляя возможности поверх.
-Класс `FastAPI` наследуется напрямую от класса `Starlette`.
+Класс `FastAPI` напрямую наследуется от класса `Starlette`.
-Таким образом, всё что Вы могли делать со Starlette, Вы можете делать с **FastAPI**, по сути это прокачанный Starlette.
+Так что всё, что вы можете сделать со Starlette, вы можете сделать напрямую с **FastAPI**, по сути это «Starlette на стероидах».
///
-### Uvicorn
+### Uvicorn { #uvicorn }
-Uvicorn - это молниеносный ASGI-сервер, построенный на uvloop и httptools.
+Uvicorn — молниеносный ASGI-сервер, построенный на uvloop и httptools.
-Uvicorn является сервером, а не фреймворком.
-Например, он не предоставляет инструментов для маршрутизации запросов по ресурсам.
-Для этого нужна надстройка, такая как Starlette (или **FastAPI**).
+Это не веб-фреймворк, а сервер. Например, он не предоставляет инструменты для маршрутизации по путям. Это предоставляет сверху фреймворк, такой как Starlette (или **FastAPI**).
-Он рекомендуется в качестве сервера для Starlette и **FastAPI**.
+Это рекомендуемый сервер для Starlette и **FastAPI**.
-/// check | **FastAPI** рекомендует его
+/// check | **FastAPI** рекомендует его как
-Как основной сервер для запуска приложения **FastAPI**.
+Основной веб-сервер для запуска приложений **FastAPI**.
-Вы можете объединить его с Gunicorn, чтобы иметь асинхронный многопроцессный сервер.
+Также вы можете использовать опцию командной строки `--workers`, чтобы получить асинхронный многопроцессный сервер.
-Узнать больше деталей можно в разделе [Развёртывание](deployment/index.md){.internal-link target=_blank}.
+Подробнее см. раздел [Развёртывание](deployment/index.md){.internal-link target=_blank}.
///
-## Тестовые замеры и скорость
+## Бенчмарки и скорость { #benchmarks-and-speed }
-Чтобы понять, сравнить и увидеть разницу между Uvicorn, Starlette и FastAPI, ознакомьтесь с разделом [Тестовые замеры](benchmarks.md){.internal-link target=_blank}.
+Чтобы понять, сравнить и увидеть разницу между Uvicorn, Starlette и FastAPI, см. раздел о [Бенчмарках](benchmarks.md){.internal-link target=_blank}.
diff --git a/docs/ru/docs/async.md b/docs/ru/docs/async.md
index 813836d36..15d4e108a 100644
--- a/docs/ru/docs/async.md
+++ b/docs/ru/docs/async.md
@@ -1,18 +1,18 @@
-# Конкурентность и async / await
+# Конкурентность и async / await { #concurrency-and-async-await }
-Здесь приведена подробная информация об использовании синтаксиса `async def` при написании *функций обработки пути*, а также рассмотрены основы асинхронного программирования, конкурентности и параллелизма.
+Подробности о синтаксисе `async def` для *функций-обработчиков пути* и немного фона об асинхронном коде, конкурентности и параллелизме.
-## Нет времени?
+## Нет времени? { #in-a-hurry }
-TL;DR:
+TL;DR:
-Допустим, вы используете сторонюю библиотеку, которая требует вызова с ключевым словом `await`:
+Если вы используете сторонние библиотеки, которые нужно вызывать с `await`, например:
```Python
results = await some_library()
```
-В этом случае *функции обработки пути* необходимо объявлять с использованием синтаксиса `async def`:
+Тогда объявляйте *функции-обработчики пути* с `async def`, например:
```Python hl_lines="2"
@app.get('/')
@@ -21,18 +21,15 @@ async def read_results():
return results
```
-/// note
+/// note | Примечание
-`await` можно использовать только внутри функций, объявленных с использованием `async def`.
+`await` можно использовать только внутри функций, объявленных с `async def`.
///
---
-Если вы обращаетесь к сторонней библиотеке, которая с чем-то взаимодействует
-(с базой данных, API, файловой системой и т. д.), и не имеет поддержки синтаксиса `await`
-(что относится сейчас к большинству библиотек для работы с базами данных), то
-объявляйте *функции обработки пути* обычным образом с помощью `def`, например:
+Если вы используете стороннюю библиотеку, которая взаимодействует с чем-то (база данных, API, файловая система и т.д.) и не поддерживает использование `await` (сейчас это относится к большинству библиотек для БД), тогда объявляйте *функции-обработчики пути* как обычно, просто с `def`, например:
```Python hl_lines="2"
@app.get('/')
@@ -43,310 +40,283 @@ def results():
---
-Если вашему приложению (странным образом) не нужно ни с чем взаимодействовать и, соответственно,
-ожидать ответа, используйте `async def`.
+Если вашему приложению (по какой-то причине) не нужно ни с чем взаимодействовать и ждать ответа, используйте `async def`, даже если внутри не нужен `await`.
---
-Если вы не уверены, используйте обычный синтаксис `def`.
+Если вы просто не уверены, используйте обычный `def`.
---
-**Примечание**: при необходимости можно смешивать `def` и `async def` в *функциях обработки пути*
-и использовать в каждом случае наиболее подходящий синтаксис. А FastAPI сделает с этим всё, что нужно.
+**Примечание**: вы можете смешивать `def` и `async def` в *функциях-обработчиках пути* столько, сколько нужно, и объявлять каждую так, как лучше для вашего случая. FastAPI сделает с ними всё как надо.
-В любом из описанных случаев FastAPI работает асинхронно и очень быстро.
+В любом из случаев выше FastAPI всё равно работает асинхронно и очень быстро.
-Однако придерживаясь указанных советов, можно получить дополнительную оптимизацию производительности.
+Но следуя этим шагам, он сможет выполнить некоторые оптимизации производительности.
-## Технические подробности
+## Технические подробности { #technical-details }
-Современные версии Python поддерживают разработку так называемого **"асинхронного кода"** посредством написания **"сопрограмм"** с использованием синтаксиса **`async` и `await`**.
+Современные версии Python поддерживают **«асинхронный код»** с помощью **«сопрограмм»** (coroutines) и синтаксиса **`async` и `await`**.
-Ниже разберём эту фразу по частям:
+Разберём эту фразу по частям в разделах ниже:
* **Асинхронный код**
* **`async` и `await`**
* **Сопрограммы**
-## Асинхронный код
+## Асинхронный код { #asynchronous-code }
-Асинхронный код означает, что в языке 💬 есть возможность сообщить машине / программе 🤖,
-что в определённой точке кода ей 🤖 нужно будет ожидать завершения выполнения *чего-то ещё* в другом месте. Допустим это *что-то ещё* называется "медленный файл" 📝.
+Асинхронный код значит, что в языке 💬 есть способ сказать компьютеру/программе 🤖, что в некоторый момент кода ему 🤖 придётся подождать, пока *что-то ещё* где-то в другом месте завершится. Назовём это *что-то ещё* «медленный файл» 📝.
-И пока мы ждём завершения работы с "медленным файлом" 📝, компьютер может переключиться для выполнения других задач.
+И пока мы ждём завершения работы с «медленныи файлом» 📝, компьютер может заняться другой работой.
-Но при каждой возможности компьютер / программа 🤖 будет возвращаться обратно. Например, если он 🤖 опять окажется в режиме ожидания, или когда закончит всю работу. В этом случае компьютер 🤖 проверяет, не завершена ли какая-нибудь из текущих задач.
+Затем компьютер/программа 🤖 будет возвращаться каждый раз, когда появится возможность (пока снова где-то идёт ожидание), или когда 🤖 завершит всю текущую работу. И он 🤖 проверит, не завершилась ли какая-либо из задач, которых он ждал, и сделает то, что нужно.
-Потом он 🤖 берёт первую выполненную задачу (допустим, наш "медленный файл" 📝) и продолжает работу, производя с ней необходимые действия.
+Далее он 🤖 возьмёт первую завершившуюся задачу (скажем, наш «медленный файл» 📝) и продолжит делать с ней то, что требуется.
-Вышеупомянутое "что-то ещё", завершения которого приходится ожидать, обычно относится к достаточно "медленным" операциям I/O (по сравнению со скоростью работы процессора и оперативной памяти), например:
+Это «ожидание чего-то ещё» обычно относится к операциям I/O, которые относительно «медленные» (по сравнению со скоростью процессора и оперативной памяти), например ожидание:
-* отправка данных от клиента по сети
-* получение клиентом данных, отправленных вашей программой по сети
-* чтение системой содержимого файла с диска и передача этих данных программе
-* запись на диск данных, которые программа передала системе
-* обращение к удалённому API
-* ожидание завершения операции с базой данных
-* получение результатов запроса к базе данных
-* и т. д.
+* отправки данных клиентом по сети
+* получения клиентом данных, отправленных вашей программой по сети
+* чтения системой содержимого файла на диске и передачи этих данных вашей программе
+* записи на диск содержимого, которое ваша программа передала системе
+* операции удалённого API
+* завершения операции базы данных
+* возврата результатов запроса к базе данных
+* и т.д.
-Поскольку в основном время тратится на ожидание выполнения операций I/O,
-их обычно называют операциями, ограниченными скоростью ввода-вывода.
+Поскольку основное время выполнения уходит на ожидание операций I/O, их называют операциями, «ограниченными вводом-выводом» (I/O bound).
-Код называют "асинхронным", потому что компьютеру / программе не требуется "синхронизироваться" с медленной задачей и,
-будучи в простое, ожидать момента её завершения, с тем чтобы забрать результат и продолжить работу.
+Это называется «асинхронным», потому что компьютеру/программе не нужно «синхронизироваться» с медленной задачей, простаивая и выжидая точный момент её завершения, чтобы забрать результат и продолжить работу.
-Вместо этого в "асинхронной" системе завершённая задача может немного подождать (буквально несколько микросекунд),
-пока компьютер / программа занимается другими важными вещами, с тем чтобы потом вернуться,
-забрать результаты выполнения и начать их обрабатывать.
+Вместо этого, в «асинхронной» системе, уже завершившаяся задача может немного подождать (несколько микросекунд) в очереди, пока компьютер/программа завершит то, чем занимался, и затем вернётся, чтобы забрать результаты и продолжить работу с ними.
-"Синхронное" исполнение (в противовес "асинхронному") также называют "последовательным",
-потому что компьютер / программа последовательно выполняет все требуемые шаги перед тем, как перейти к следующей задаче,
-даже если в процессе приходится ждать.
+Для «синхронного» (в противоположность «асинхронному») исполнения часто используют термин «последовательный», потому что компьютер/программа выполняет все шаги по порядку, прежде чем переключиться на другую задачу, даже если эти шаги включают ожидание.
-### Конкурентность и бургеры
+### Конкурентность и бургеры { #concurrency-and-burgers }
-Тот **асинхронный** код, о котором идёт речь выше, иногда называют **"конкурентностью"**. Она отличается от **"параллелизма"**.
+Та идея **асинхронного** кода, описанная выше, иногда также называется **«конкурентностью»**. Она отличается от **«параллелизма»**.
-Да, **конкурентность** и **параллелизм** подразумевают, что разные вещи происходят примерно в одно время.
+И **конкурентность**, и **параллелизм** относятся к «разным вещам, происходящим примерно одновременно».
-Но внутреннее устройство **конкурентности** и **параллелизма** довольно разное.
+Но различия между *конкурентностью* и *параллелизмом* довольно существенные.
-Чтобы это понять, представьте такую картину:
+Чтобы их увидеть, представьте следующую историю про бургеры:
-### Конкурентные бургеры
+### Конкурентные бургеры { #concurrent-burgers }
-
+Вы идёте со своей возлюбленной за фастфудом, вы стоите в очереди, пока кассир принимает заказы у людей перед вами. 😍
-Вы идёте со своей возлюбленной 😍 в фастфуд 🍔 и становитесь в очередь, в это время кассир 💁 принимает заказы у посетителей перед вами.
+
-Когда наконец подходит очередь, вы заказываете парочку самых вкусных и навороченных бургеров 🍔, один для своей возлюбленной 😍, а другой себе.
+Наконец ваша очередь: вы заказываете 2 очень «навороченных» бургера — для вашей возлюбленной и для себя. 🍔🍔
-Отдаёте деньги 💸.
+
-Кассир 💁 что-то говорит поварам на кухне 👨🍳, теперь они знают, какие бургеры нужно будет приготовить 🍔
-(но пока они заняты бургерами предыдущих клиентов).
+Кассир говорит что-то повару на кухне, чтобы они знали, что нужно приготовить ваши бургеры (хотя сейчас они готовят бургеры для предыдущих клиентов).
-Кассир 💁 отдаёт вам чек с номером заказа.
+
-В ожидании еды вы идёте со своей возлюбленной 😍 выбрать столик, садитесь и довольно продолжительное время общаетесь 😍
-(поскольку ваши бургеры самые навороченные, готовятся они не так быстро ✨🍔✨).
+Вы платите. 💸
-Сидя за столиком с возлюбленной 😍 в ожидании бургеров 🍔, вы отлично проводите время,
-восхищаясь её великолепием, красотой и умом ✨😍✨.
+Кассир выдаёт вам номер вашей очереди.
-Всё ещё ожидая заказ и болтая со своей возлюбленной 😍, время от времени вы проверяете,
-какой номер горит над прилавком, и не подошла ли уже ваша очередь.
+
-И вот наконец настаёт этот момент, и вы идёте к стойке, чтобы забрать бургеры 🍔 и вернуться за столик.
+Пока вы ждёте, вы вместе со своей возлюбленной идёте и выбираете столик, садитесь и долго болтаете (ваши бургеры очень «навороченные», поэтому им нужно время на приготовление).
-Вы со своей возлюбленной 😍 едите бургеры 🍔 и отлично проводите время ✨.
+Сидя за столиком со своей возлюбленной в ожидании бургеров, вы можете провести это время, восхищаясь тем, какая она классная, милая и умная ✨😍✨.
+
+
+
+Пока вы ждёте и разговариваете, время от времени вы поглядываете на номер на табло, чтобы понять, не подошла ли уже ваша очередь.
+
+И вот в какой-то момент ваша очередь наступает. Вы подходите к стойке, забираете свои бургеры и возвращаетесь к столику.
+
+
+
+Вы со своей возлюбленной едите бургеры и отлично проводите время. ✨
+
+
+
+/// info | Информация
+
+Прекрасные иллюстрации от Ketrina Thompson. 🎨
+
+///
---
-А теперь представьте, что в этой небольшой истории вы компьютер / программа 🤖.
+Представьте, что в этой истории вы — компьютер/программа 🤖.
-В очереди вы просто глазеете по сторонам 😴, ждёте и ничего особо "продуктивного" не делаете.
-Но очередь движется довольно быстро, поскольку кассир 💁 только принимает заказы (а не занимается приготовлением еды), так что ничего страшного.
+Пока вы стоите в очереди, вы просто бездействуете 😴, ждёте своей очереди и не делаете ничего особо «продуктивного». Но очередь движется быстро, потому что кассир только принимает заказы (а не готовит их), так что это нормально.
-Когда подходит очередь вы наконец предпринимаете "продуктивные" действия 🤓: просматриваете меню, выбираете в нём что-то, узнаёте, что хочет ваша возлюбленная 😍, собираетесь оплатить 💸, смотрите, какую достали карту, проверяете, чтобы с вас списали верную сумму, и что в заказе всё верно и т. д.
+Когда приходит ваша очередь, вы выполняете действительно «продуктивную» работу: просматриваете меню, решаете, чего хотите, учитываете выбор своей возлюбленной, платите, проверяете, что дали правильную купюру/карту, что сумма списана корректно, что в заказе верные позиции и т.д.
-И хотя вы всё ещё не получили бургеры 🍔, ваша работа с кассиром 💁 ставится "на паузу" ⏸,
-поскольку теперь нужно ждать 🕙, когда заказ приготовят.
+Но затем, хотя у вас ещё нет бургеров, ваша «работа» с кассиром поставлена «на паузу» ⏸, потому что нужно подождать 🕙, пока бургеры будут готовы.
-Но отойдя с номерком от прилавка, вы садитесь за столик и можете переключить 🔀 внимание
-на свою возлюбленную 😍 и "работать" ⏯ 🤓 уже над этим. И вот вы снова очень
-"продуктивны" 🤓, мило болтаете вдвоём и всё такое 😍.
+Но, отойдя от стойки и сев за столик с номерком, вы можете переключить 🔀 внимание на свою возлюбленную и «поработать» ⏯ 🤓 над этим. Снова очень «продуктивно» — флирт с вашей возлюбленной 😍.
-В какой-то момент кассир 💁 поместит на табло ваш номер, подразумевая, что бургеры готовы 🍔, но вы не станете подскакивать как умалишённый, лишь только увидев на экране свою очередь. Вы уверены, что ваши бургеры 🍔 никто не утащит, ведь у вас свой номерок, а у других свой.
+Потом кассир 💁 «говорит»: «Я закончил делать бургеры», — выводя ваш номер на табло, но вы не подпрыгиваете как сумасшедший в ту же секунду, как только номер сменился на ваш. Вы знаете, что ваши бургеры никто не украдёт, потому что у вас есть номер вашей очереди, а у других — их.
-Поэтому вы подождёте, пока возлюбленная 😍 закончит рассказывать историю (закончите текущую работу ⏯ / задачу в обработке 🤓),
-и мило улыбнувшись, скажете, что идёте забирать заказ ⏸.
+Поэтому вы дожидаетесь, пока ваша возлюбленная закончит историю (завершится текущая работа ⏯ / выполняемая задача 🤓), мягко улыбаетесь и говорите, что идёте за бургерами ⏸.
-И вот вы подходите к стойке 🔀, к первоначальной задаче, которая уже завершена ⏯, берёте бургеры 🍔, говорите спасибо и относите заказ за столик. На этом заканчивается этап / задача взаимодействия с кассой ⏹.
-В свою очередь порождается задача "поедание бургеров" 🔀 ⏯, но предыдущая ("получение бургеров") завершена ⏹.
+Затем вы идёте к стойке 🔀, к исходной задаче, которая теперь завершена ⏯, забираете бургеры, благодарите и несёте их к столику. На этом шаг/задача взаимодействия со стойкой завершён ⏹. Это, в свою очередь, создаёт новую задачу — «есть бургеры» 🔀 ⏯, но предыдущая «получить бургеры» — завершена ⏹.
-### Параллельные бургеры
+### Параллельные бургеры { #parallel-burgers }
-Теперь представим, что вместо бургерной "Конкурентные бургеры" вы решили сходить в "Параллельные бургеры".
+Теперь представим, что это не «Конкурентные бургеры», а «Параллельные бургеры».
-И вот вы идёте со своей возлюбленной 😍 отведать параллельного фастфуда 🍔.
+Вы идёте со своей возлюбленной за параллельным фастфудом.
-Вы становитесь в очередь пока несколько (пусть будет 8) кассиров, которые по совместительству ещё и повары 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳, принимают заказы у посетителей перед вами.
+Вы стоите в очереди, пока несколько (скажем, 8) кассиров, которые одновременно являются поварами, принимают заказы у людей перед вами.
-При этом клиенты не отходят от стойки и ждут 🕙 получения еды, поскольку каждый
-из 8 кассиров идёт на кухню готовить бургеры 🍔, а только потом принимает следующий заказ.
+Все перед вами ждут, пока их бургеры будут готовы, не отходя от стойки, потому что каждый из 8 кассиров сразу идёт готовить бургер перед тем, как принять следующий заказ.
-Наконец настаёт ваша очередь, и вы просите два самых навороченных бургера 🍔, один для дамы сердца 😍, а другой себе.
+
-Ни о чём не жалея, расплачиваетесь 💸.
+Наконец ваша очередь: вы заказываете 2 очень «навороченных» бургера — для вашей возлюбленной и для себя.
-И кассир уходит на кухню 👨🍳.
+Вы платите 💸.
-Вам приходится ждать перед стойкой 🕙, чтобы никто по случайности не забрал ваши бургеры 🍔, ведь никаких номерков у вас нет.
+
-Поскольку вы с возлюбленной 😍 хотите получить заказ вовремя 🕙, и следите за тем, чтобы никто не вклинился в очередь,
-у вас не получается уделять должного внимание своей даме сердца 😞.
+Кассир уходит на кухню.
-Это "синхронная" работа, вы "синхронизированы" с кассиром/поваром 👨🍳. Приходится ждать 🕙 у стойки,
-когда кассир/повар 👨🍳 закончит делать бургеры 🍔 и вручит вам заказ, иначе его случайно может забрать кто-то другой.
+Вы ждёте, стоя у стойки 🕙, чтобы никто не забрал ваши бургеры раньше вас, так как никаких номерков нет.
-Наконец кассир/повар 👨🍳 возвращается с бургерами 🍔 после невыносимо долгого ожидания 🕙 за стойкой.
+
-Вы скорее забираете заказ 🍔 и идёте с возлюбленной 😍 за столик.
+Так как вы со своей возлюбленной заняты тем, чтобы никто не встал перед вами и не забрал ваши бургеры, как только они появятся, вы не можете уделить внимание своей возлюбленной. 😞
-Там вы просто едите эти бургеры, и на этом всё 🍔 ⏹.
+Это «синхронная» работа, вы «синхронизированы» с кассиром/поваром 👨🍳. Вам нужно ждать 🕙 и находиться там в точный момент, когда кассир/повар 👨🍳 закончит бургеры и вручит их вам, иначе их может забрать кто-то другой.
-Вам не особо удалось пообщаться, потому что большую часть времени 🕙 пришлось провести у кассы 😞.
+
+
+Затем ваш кассир/повар 👨🍳 наконец возвращается с вашими бургерами, после долгого ожидания 🕙 у стойки.
+
+
+
+Вы берёте бургеры и идёте со своей возлюбленной к столику.
+
+Вы просто их съедаете — и всё. ⏹
+
+
+
+Разговоров и флирта было немного, потому что большую часть времени вы ждали 🕙 у стойки. 😞
+
+/// info | Информация
+
+Прекрасные иллюстрации от Ketrina Thompson. 🎨
+
+///
---
-В описанном сценарии вы компьютер / программа 🤖 с двумя исполнителями (вы и ваша возлюбленная 😍),
-на протяжении долгого времени 🕙 вы оба уделяете всё внимание ⏯ задаче "ждать на кассе".
+В этом сценарии «параллельных бургеров» вы — компьютер/программа 🤖 с двумя процессорами (вы и ваша возлюбленная), оба ждут 🕙 и уделяют внимание ⏯ тому, чтобы «ждать у стойки» 🕙 долгое время.
-В этом ресторане быстрого питания 8 исполнителей (кассиров/поваров) 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳.
-Хотя в бургерной конкурентного типа было всего два (один кассир и один повар) 💁 👨🍳.
+В ресторане 8 процессоров (кассиров/поваров). Тогда как в «конкурентных бургерах» могло быть только 2 (один кассир и один повар).
-Несмотря на обилие работников, опыт в итоге получился не из лучших 😞.
+И всё же финальный опыт — не самый лучший. 😞
---
-Так бы выглядел аналог истории про бургерную 🍔 в "параллельном" мире.
+Это была параллельная версия истории про бургеры. 🍔
-Вот более реалистичный пример. Представьте себе банк.
+Для более «жизненного» примера представьте банк.
-До недавних пор в большинстве банков было несколько кассиров 👨💼👨💼👨💼👨💼 и длинные очереди 🕙🕙🕙🕙🕙🕙🕙🕙.
+До недавнего времени в большинстве банков было несколько кассиров 👨💼👨💼👨💼👨💼 и длинная очередь 🕙🕙🕙🕙🕙🕙🕙🕙.
-Каждый кассир обслуживал одного клиента, потом следующего 👨💼⏯.
+Все кассиры делают всю работу с одним клиентом за другим 👨💼⏯.
-Нужно было долгое время 🕙 стоять перед окошком вместе со всеми, иначе пропустишь свою очередь.
+И вам приходится долго 🕙 стоять в очереди, иначе вы потеряете свою очередь.
-Сомневаюсь, что у вас бы возникло желание прийти с возлюбленной 😍 в банк 🏦 оплачивать налоги.
+Вы вряд ли захотите взять свою возлюбленную 😍 с собой, чтобы заняться делами в банке 🏦.
-### Выводы о бургерах
+### Вывод про бургеры { #burger-conclusion }
-В нашей истории про поход в фастфуд за бургерами приходится много ждать 🕙,
-поэтому имеет смысл организовать конкурентную систему ⏸🔀⏯.
+В этом сценарии «фастфуда с вашей возлюбленной», так как много ожидания 🕙, гораздо логичнее иметь конкурентную систему ⏸🔀⏯.
-И то же самое с большинством веб-приложений.
+Так обстоит дело и с большинством веб-приложений.
-Пользователей очень много, но ваш сервер всё равно вынужден ждать 🕙 запросы по их слабому интернет-соединению.
+Очень много пользователей, но ваш сервер ждёт 🕙, пока их не самое хорошее соединение отправит их запросы.
-Потом снова ждать 🕙, пока вернётся ответ.
+А затем снова ждёт 🕙, пока отправятся ответы.
-
-Это ожидание 🕙 измеряется микросекундами, но если всё сложить, то набегает довольно много времени.
+Это «ожидание» 🕙 измеряется микросекундами, но если всё сложить, то в сумме получается много ожидания.
-Вот почему есть смысл использовать асинхронное ⏸🔀⏯ программирование при построении веб-API.
+Вот почему асинхронный ⏸🔀⏯ код очень уместен для веб-API.
-Большинство популярных фреймворков (включая Flask и Django) создавались
-до появления в Python новых возможностей асинхронного программирования. Поэтому
-их можно разворачивать с поддержкой параллельного исполнения или асинхронного
-программирования старого типа, которое не настолько эффективно.
+Именно такая асинхронность сделала NodeJS популярным (хотя NodeJS — не параллельный), и это сильная сторона Go как языка программирования.
-При том, что основная спецификация асинхронного взаимодействия Python с веб-сервером
-(ASGI)
-была разработана командой Django для внедрения поддержки веб-сокетов.
+Того же уровня производительности вы получаете с **FastAPI**.
-Именно асинхронность сделала NodeJS таким популярным (несмотря на то, что он не параллельный),
-и в этом преимущество Go как языка программирования.
+А так как можно одновременно использовать параллелизм и асинхронность, вы получаете производительность выше, чем у большинства протестированных фреймворков на NodeJS и на уровне Go, который — компилируемый язык, ближе к C (всё благодаря Starlette).
-И тот же уровень производительности даёт **FastAPI**.
+### Конкурентность лучше параллелизма? { #is-concurrency-better-than-parallelism }
-Поскольку можно использовать преимущества параллелизма и асинхронности вместе,
-вы получаете производительность лучше, чем у большинства протестированных NodeJS фреймворков
-и на уровне с Go, который является компилируемым языком близким к C (всё благодаря Starlette).
+Нет! Мораль истории не в этом.
-### Получается, конкурентность лучше параллелизма?
+Конкурентность отличается от параллелизма. И она лучше в **конкретных** сценариях, где много ожидания. Поэтому при разработке веб-приложений она обычно намного лучше параллелизма. Но не во всём.
-Нет! Мораль истории совсем не в этом.
+Чтобы уравновесить это, представьте такую короткую историю:
-Конкурентность отличается от параллелизма. Она лучше в **конкретных** случаях, где много времени приходится на ожидание.
-Вот почему она зачастую лучше параллелизма при разработке веб-приложений. Но это не значит, что конкурентность лучше в любых сценариях.
-
-Давайте посмотрим с другой стороны, представьте такую картину:
-
-> Вам нужно убраться в большом грязном доме.
+> Вам нужно убрать большой грязный дом.
*Да, это вся история*.
---
-Тут не нужно нигде ждать 🕙, просто есть куча работы в разных частях дома.
+Здесь нигде нет ожидания 🕙, просто очень много работы в разных местах дома.
-Можно организовать очередь как в примере с бургерами, сначала гостиная, потом кухня,
-но это ни на что не повлияет, поскольку вы нигде не ждёте 🕙, а просто трёте да моете.
+Можно организовать «очереди» как в примере с бургерами — сначала гостиная, потом кухня, — но так как вы ничего не ждёте 🕙, а просто убираете и убираете, очереди ни на что не повлияют.
-И понадобится одинаковое количество времени с очередью (конкурентностью) и без неё,
-и работы будет сделано тоже одинаковое количество.
+На завершение уйдёт одинаковое время — с очередями (конкурентностью) и без них — и объём выполненной работы будет одинаковым.
-Однако в случае, если бы вы могли привести 8 бывших кассиров/поваров, а ныне уборщиков 👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳👩🍳👨🍳,
-и каждый из них (вместе с вами) взялся бы за свой участок дома,
-с такой помощью вы бы закончили намного быстрее, делая всю работу **параллельно**.
+Но в этом случае, если бы вы могли привести 8 бывших кассиров/поваров, а теперь — уборщиков, и каждый из них (плюс вы) взял бы свою зону дома для уборки, вы могли бы сделать всю работу **параллельно**, с дополнительной помощью, и завершить гораздо быстрее.
-В описанном сценарии каждый уборщик (включая вас) был бы исполнителем, занятым на своём участке работы.
+В этом сценарии каждый уборщик (включая вас) был бы процессором, выполняющим свою часть работы.
-И поскольку большую часть времени выполнения занимает реальная работа (а не ожидание),
-а работу в компьютере делает ЦП,
-такие задачи называют ограниченными производительностью процессора.
+И так как основное время выполнения уходит на реальную работу (а не ожидание), а работу в компьютере выполняет CPU, такие задачи называют «ограниченными процессором» (CPU bound).
---
-Ограничение по процессору проявляется в операциях, где требуется выполнять сложные математические вычисления.
+Типичные примеры CPU-bound операций — те, которые требуют сложной математической обработки.
Например:
-* Обработка **звука** или **изображений**.
-* **Компьютерное зрение**: изображение состоит из миллионов пикселей, в каждом пикселе 3 составляющих цвета,
-обработка обычно требует проведения расчётов по всем пикселям сразу.
-* **Машинное обучение**: здесь обычно требуется умножение "матриц" и "векторов".
-Представьте гигантскую таблицу с числами в Экселе, и все их надо одновременно перемножить.
-* **Глубокое обучение**: это область *машинного обучения*, поэтому сюда подходит то же описание.
-Просто у вас будет не одна таблица в Экселе, а множество. В ряде случаев используется
-специальный процессор для создания и / или использования построенных таким образом моделей.
+* Обработка **аудио** или **изображений**.
+* **Компьютерное зрение**: изображение состоит из миллионов пикселей, каждый пиксель имеет 3 значения/цвета; обычно требуется вычислить что-то для всех этих пикселей одновременно.
+* **Машинное обучение**: обычно требует множества умножений «матриц» и «векторов». Представьте огромную таблицу с числами и умножение всех этих чисел «одновременно».
+* **Глубокое обучение**: это подполе Машинного обучения, так что всё вышесказанное применимо. Просто это не одна таблица чисел, а их огромный набор, и во многих случаях вы используете специальный процессор, чтобы строить и/или использовать такие модели.
-### Конкурентность + параллелизм: Веб + машинное обучение
+### Конкурентность + параллелизм: Веб + Машинное обучение { #concurrency-parallelism-web-machine-learning }
-**FastAPI** предоставляет возможности конкуретного программирования,
-которое очень распространено в веб-разработке (именно этим славится NodeJS).
+С **FastAPI** вы можете использовать преимущества конкурентности, что очень распространено в веб-разработке (это та же основная «фишка» NodeJS).
-Кроме того вы сможете использовать все преимущества параллелизма и
-многопроцессорности (когда несколько процессов работают параллельно),
-если рабочая нагрузка предполагает **ограничение по процессору**,
-как, например, в системах машинного обучения.
+Но вы также можете использовать выгоды параллелизма и многопроцессности (когда несколько процессов работают параллельно) для рабочих нагрузок, **ограниченных процессором** (CPU bound), как в системах Машинного обучения.
-Необходимо также отметить, что Python является главным языком в области
-**дата-сайенс**,
-машинного обучения и, особенно, глубокого обучения. Всё это делает FastAPI
-отличным вариантом (среди многих других) для разработки веб-API и приложений
-в области дата-сайенс / машинного обучения.
+Плюс к этому простой факт, что Python — основной язык для **Data Science**, Машинного обучения и особенно Глубокого обучения, делает FastAPI очень хорошим выбором для веб-API и приложений в области Data Science / Машинного обучения (среди многих других).
-Как добиться такого параллелизма в эксплуатации описано в разделе [Развёртывание](deployment/index.md){.internal-link target=_blank}.
+Как добиться такого параллелизма в продакшн, см. раздел [Развёртывание](deployment/index.md){.internal-link target=_blank}.
-## `async` и `await`
+## `async` и `await` { #async-and-await }
-В современных версиях Python разработка асинхронного кода реализована очень интуитивно.
-Он выглядит как обычный "последовательный" код и самостоятельно выполняет "ожидание", когда это необходимо.
+В современных версиях Python есть очень интуитивный способ определять асинхронный код. Это делает его похожим на обычный «последовательный» код, а «ожидание» выполняется за вас в нужные моменты.
-Если некая операция требует ожидания перед тем, как вернуть результат, и
-поддерживает современные возможности Python, код можно написать следующим образом:
+Когда есть операция, которой нужно подождать перед тем, как вернуть результат, и она поддерживает эти новые возможности Python, вы можете написать так:
```Python
burgers = await get_burgers(2)
```
-Главное здесь слово `await`. Оно сообщает интерпретатору, что необходимо дождаться ⏸
-пока `get_burgers(2)` закончит свои дела 🕙, и только после этого сохранить результат в `burgers`.
-Зная это, Python может пока переключиться на выполнение других задач 🔀 ⏯
-(например получение следующего запроса).
+Ключ здесь — `await`. Он говорит Python, что нужно подождать ⏸, пока `get_burgers(2)` закончит своё дело 🕙, прежде чем сохранять результат в `burgers`. Благодаря этому Python будет знать, что за это время можно заняться чем-то ещё 🔀 ⏯ (например, принять другой запрос).
-Чтобы ключевое слово `await` сработало, оно должно находиться внутри функции,
-которая поддерживает асинхронность. Для этого вам просто нужно объявить её как `async def`:
+Чтобы `await` работал, он должен находиться внутри функции, которая поддерживает такую асинхронность. Для этого просто объявите её с `async def`:
```Python hl_lines="1"
async def get_burgers(number: int):
- # Готовим бургеры по специальному асинхронному рецепту
+ # Сделать что-то асинхронное, чтобы приготовить бургеры
return burgers
```
@@ -355,26 +325,22 @@ async def get_burgers(number: int):
```Python hl_lines="2"
# Это не асинхронный код
def get_sequential_burgers(number: int):
- # Готовим бургеры последовательно по шагам
+ # Сделать что-то последовательное, чтобы приготовить бургеры
return burgers
```
-Объявление `async def` указывает интерпретатору, что внутри этой функции
-следует ожидать выражений `await`, и что можно поставить выполнение такой функции на "паузу" ⏸ и
-переключиться на другие задачи 🔀, с тем чтобы вернуться сюда позже.
+С `async def` Python знает, что внутри этой функции нужно учитывать выражения `await` и что выполнение такой функции можно «приостанавливать» ⏸ и идти делать что-то ещё 🔀, чтобы потом вернуться.
-Если вы хотите вызвать функцию с `async def`, вам нужно "ожидать" её.
-Поэтому такое не сработает:
+Когда вы хотите вызвать функцию, объявленную с `async def`, нужно её «ожидать». Поэтому вот так не сработает:
```Python
-# Это не заработает, поскольку get_burgers объявлена с использованием async def
+# Это не сработает, потому что get_burgers определена с: async def
burgers = get_burgers(2)
```
---
-Если сторонняя библиотека требует вызывать её с ключевым словом `await`,
-необходимо писать *функции обработки пути* с использованием `async def`, например:
+Итак, если вы используете библиотеку, которую можно вызывать с `await`, вам нужно создать *функцию-обработчик пути*, которая её использует, с `async def`, например:
```Python hl_lines="2-3"
@app.get('/burgers')
@@ -383,129 +349,96 @@ async def read_burgers():
return burgers
```
-### Технические подробности
+### Более технические подробности { #more-technical-details }
-Как вы могли заметить, `await` может применяться только в функциях, объявленных с использованием `async def`.
+Вы могли заметить, что `await` можно использовать только внутри функций, определённых с `async def`.
-
-Но выполнение такой функции необходимо "ожидать" с помощью `await`.
-Это означает, что её можно вызвать только из другой функции, которая тоже объявлена с `async def`.
+Но при этом функции, определённые с `async def`, нужно «ожидать». Значит, функции с `async def` тоже можно вызывать только из функций, определённых с `async def`.
-Но как же тогда появилась первая курица? В смысле... как нам вызвать первую асинхронную функцию?
+Так что же с «яйцом и курицей» — как вызвать первую `async` функцию?
-При работе с **FastAPI** просто не думайте об этом, потому что "первой" функцией является ваша *функция обработки пути*,
-и дальше с этим разберётся FastAPI.
+Если вы работаете с **FastAPI**, вам не о чем беспокоиться, потому что этой «первой» функцией будет ваша *функция-обработчик пути*, а FastAPI знает, как сделать всё правильно.
-Кроме того, если хотите, вы можете использовать синтаксис `async` / `await` и без FastAPI.
+Но если вы хотите использовать `async` / `await` без FastAPI, вы тоже можете это сделать.
-### Пишите свой асинхронный код
+### Пишите свой асинхронный код { #write-your-own-async-code }
-Starlette (и **FastAPI**) основаны на AnyIO, что делает их совместимыми как со стандартной библиотекой asyncio в Python, так и с Trio.
+Starlette (и **FastAPI**) основаны на AnyIO, что делает их совместимыми и со стандартной библиотекой Python asyncio, и с Trio.
-В частности, вы можете напрямую использовать AnyIO в тех проектах, где требуется более сложная логика работы с конкурентностью.
+В частности, вы можете напрямую использовать AnyIO для продвинутых сценариев конкурентности, где в вашем коде нужны более сложные паттерны.
-Даже если вы не используете FastAPI, вы можете писать асинхронные приложения с помощью AnyIO, чтобы они были максимально совместимыми и получали его преимущества (например *структурную конкурентность*).
+И даже если вы не используете FastAPI, вы можете писать свои асинхронные приложения с AnyIO, чтобы они были максимально совместимыми и получали его преимущества (например, *структурную конкурентность*).
-### Другие виды асинхронного программирования
+Я создал ещё одну библиотеку поверх AnyIO, тонкий слой, чтобы немного улучшить аннотации типов и получить более качественное **автозавершение**, **ошибки прямо в редакторе** и т.д. Там также есть дружелюбное введение и руководство, чтобы помочь вам **понять** и писать **свой собственный асинхронный код**: Asyncer. Она особенно полезна, если вам нужно **комбинировать асинхронный код с обычным** (блокирующим/синхронным) кодом.
-Стиль написания кода с `async` и `await` появился в языке Python относительно недавно.
+### Другие формы асинхронного кода { #other-forms-of-asynchronous-code }
-Но он сильно облегчает работу с асинхронным кодом.
+Такой стиль использования `async` и `await` относительно новый в языке.
-Ровно такой же синтаксис (ну или почти такой же) недавно был включён в современные версии JavaScript (в браузере и NodeJS).
+Но он сильно упрощает работу с асинхронным кодом.
-До этого поддержка асинхронного кода была реализована намного сложнее, и его было труднее воспринимать.
+Такой же (или почти такой же) синтаксис недавно появился в современных версиях JavaScript (в браузере и NodeJS).
-В предыдущих версиях Python для этого использовались потоки или Gevent. Но такой код намного сложнее понимать, отлаживать и мысленно представлять.
+До этого работа с асинхронным кодом была заметно сложнее и труднее для понимания.
-Что касается JavaScript (в браузере и NodeJS), раньше там использовали для этой цели
-"обратные вызовы". Что выливалось в
-"ад обратных вызовов".
+В предыдущих версиях Python можно было использовать потоки или Gevent. Но такой код гораздо сложнее понимать, отлаживать и держать в голове.
-## Сопрограммы
+В прежних версиях NodeJS/браузерного JavaScript вы бы использовали «callbacks» (обратные вызовы), что приводит к «callback hell» (ад обратных вызовов).
-**Корути́на** (или же сопрограмма) — это крутое словечко для именования той сущности,
-которую возвращает функция `async def`. Python знает, что её можно запустить, как и обычную функцию,
-но кроме того сопрограмму можно поставить на паузу ⏸ в том месте, где встретится слово `await`.
+## Сопрограммы { #coroutines }
-Всю функциональность асинхронного программирования с использованием `async` и `await`
-часто обобщают словом "корутины". Они аналогичны "горутинам", ключевой особенности
-языка Go.
+**Сопрограмма** (coroutine) — это просто «навороченное» слово для того, что возвращает функция `async def`. Python знает, что это похоже на функцию: её можно запустить, она когда-нибудь завершится, но её выполнение может приостанавливаться ⏸ внутри, когда встречается `await`.
-## Заключение
+Часто всю функциональность использования асинхронного кода с `async` и `await` кратко называют «сопрограммами». Это сопоставимо с ключевой особенностью Go — «goroutines».
-В самом начале была такая фраза:
+## Заключение { #conclusion }
-> Современные версии Python поддерживают разработку так называемого
-**"асинхронного кода"** посредством написания **"сопрограмм"** с использованием
-синтаксиса **`async` и `await`**.
+Вернёмся к той же фразе:
-Теперь всё должно звучать понятнее. ✨
+> Современные версии Python поддерживают **«асинхронный код»** с помощью **«сопрограмм»** (coroutines) и синтаксиса **`async` и `await`**.
-На этом основана работа FastAPI (посредством Starlette), и именно это
-обеспечивает его высокую производительность.
+Теперь это должно звучать понятнее. ✨
-## Очень технические подробности
+Именно это «движет» FastAPI (через Starlette) и обеспечивает столь впечатляющую производительность.
-/// warning
+## Очень технические подробности { #very-technical-details }
-Этот раздел читать не обязательно.
+/// warning | Предупреждение
-Здесь приводятся подробности внутреннего устройства **FastAPI**.
+Скорее всего, этот раздел можно пропустить.
-Но если вы обладаете техническими знаниями (корутины, потоки, блокировка и т. д.)
-и вам интересно, как FastAPI обрабатывает `async def` в отличие от обычных `def`,
-читайте дальше.
+Здесь — очень технические подробности о том, как **FastAPI** работает «под капотом».
+
+Если у вас есть достаточно технических знаний (сопрограммы, потоки, блокировки и т.д.) и вам интересно, как FastAPI обрабатывает `async def` по сравнению с обычным `def`, — вперёд.
///
-### Функции обработки пути
+### Функции-обработчики пути { #path-operation-functions }
-Когда вы объявляете *функцию обработки пути* обычным образом с ключевым словом `def`
-вместо `async def`, FastAPI ожидает её выполнения, запустив функцию во внешнем
-пуле потоков, а не напрямую (это бы заблокировало сервер).
+Когда вы объявляете *функцию-обработчик пути* обычным `def` вместо `async def`, она запускается во внешнем пуле потоков, который затем «ожидается», вместо прямого вызова (прямой вызов заблокировал бы сервер).
-Если ранее вы использовали другой асинхронный фреймворк, который работает иначе,
-и привыкли объявлять простые вычислительные *функции* через `def` ради
-незначительного прироста скорости (порядка 100 наносекунд), обратите внимание,
-что с **FastAPI** вы получите противоположный эффект. В таком случае больше подходит
-`async def`, если только *функция обработки пути* не использует код, приводящий
-к блокировке I/O.
-
+Если вы пришли из другого async-фреймворка, который работает иначе, и привыкли объявлять тривиальные *функции-обработчики пути*, выполняющие только вычисления, через простой `def` ради крошечной выгоды в производительности (около 100 наносекунд), обратите внимание: в **FastAPI** эффект будет противоположным. В таких случаях лучше использовать `async def`, если только ваши *функции-обработчики пути* не используют код, выполняющий блокирующий I/O.
-
-Но в любом случае велика вероятность, что **FastAPI** [окажется быстрее](index.md#_11){.internal-link target=_blank}
-другого фреймворка (или хотя бы на уровне с ним).
+Тем не менее, в обоих случаях велика вероятность, что **FastAPI** [всё равно будет быстрее](index.md#performance){.internal-link target=_blank} (или как минимум сопоставим) с вашим предыдущим фреймворком.
-### Зависимости
+### Зависимости { #dependencies }
-То же относится к зависимостям. Если это обычная функция `def`, а не `async def`,
-она запускается во внешнем пуле потоков.
+То же относится к [зависимостям](tutorial/dependencies/index.md){.internal-link target=_blank}. Если зависимость — это обычная функция `def`, а не `async def`, она запускается во внешнем пуле потоков.
-### Подзависимости
+### Подзависимости { #sub-dependencies }
-Вы можете объявить множество ссылающихся друг на друга зависимостей и подзависимостей
-(в виде параметров при определении функции). Какие-то будут созданы с помощью `async def`,
-другие обычным образом через `def`, и такая схема вполне работоспособна. Функции,
-объявленные с помощью `def` будут запускаться на внешнем потоке (из пула),
-а не с помощью `await`.
+У вас может быть несколько зависимостей и [подзависимостей](tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank}, которые требуют друг друга (в виде параметров определений функций): часть из них может быть объявлена с `async def`, а часть — обычным `def`. Всё будет работать, а те, что объявлены обычным `def`, будут вызываться во внешнем потоке (из пула), а не «ожидаться».
-### Другие служебные функции
+### Другие служебные функции { #other-utility-functions }
-Любые другие служебные функции, которые вы вызываете напрямую, можно объявлять
-с использованием `def` или `async def`. FastAPI не будет влиять на то, как вы
-их запускаете.
+Любые другие служебные функции, которые вы вызываете напрямую, можно объявлять обычным `def` или `async def`, и FastAPI не будет влиять на то, как вы их вызываете.
-Этим они отличаются от функций, которые FastAPI вызывает самостоятельно:
-*функции обработки пути* и зависимости.
+В отличие от функций, которые FastAPI вызывает за вас: *функции-обработчики пути* и зависимости.
-Если служебная функция объявлена с помощью `def`, она будет вызвана напрямую
-(как вы и написали в коде), а не в отдельном потоке. Если же она объявлена с
-помощью `async def`, её вызов должен осуществляться с ожиданием через `await`.
+Если служебная функция — обычная функция с `def`, она будет вызвана напрямую (как вы и пишете в коде), не в пуле потоков; если функция объявлена с `async def`, тогда при её вызове в вашем коде вы должны использовать `await`.
---
-
-Ещё раз повторим, что все эти технические подробности полезны, только если вы специально их искали.
+Снова: это очень технические подробности, полезные, вероятно, только если вы целенаправленно их ищете.
-В противном случае просто ознакомьтесь с основными принципами в разделе выше: Нет времени?.
+Иначе вам достаточно руководствоваться рекомендациями из раздела выше: Нет времени?.
diff --git a/docs/ru/docs/benchmarks.md b/docs/ru/docs/benchmarks.md
index 259dca8e6..612b39f70 100644
--- a/docs/ru/docs/benchmarks.md
+++ b/docs/ru/docs/benchmarks.md
@@ -1,37 +1,34 @@
-# Замеры производительности
+# Бенчмарки (тесты производительности) { #benchmarks }
-Независимые тесты производительности приложений от TechEmpower показывают, что **FastAPI** под управлением Uvicorn один из самых быстрых Python-фреймворков и уступает только Starlette и Uvicorn (которые используются в FastAPI). (*)
+Независимые бенчмарки TechEmpower показывают, что приложения **FastAPI** под управлением Uvicorn — одни из самых быстрых Python‑фреймворков, уступающие только Starlette и самому Uvicorn (используются внутри FastAPI).
-Но при просмотре и сравнении замеров производительности следует иметь в виду нижеописанное.
+Но при просмотре бенчмарков и сравнений следует иметь в виду следующее.
-## Замеры производительности и скорости
+## Бенчмарки и скорость { #benchmarks-and-speed }
-В подобных тестах часто можно увидеть, что инструменты разного типа сравнивают друг с другом, как аналогичные.
+При проверке бенчмарков часто можно увидеть, что инструменты разных типов сравнивают как эквивалентные.
-В частности, сравнивают вместе Uvicorn, Starlette и FastAPI (среди многих других инструментов).
+В частности, часто сравнивают вместе Uvicorn, Starlette и FastAPI (среди многих других инструментов).
-Чем проще проблема, которую решает инструмент, тем выше его производительность. И большинство тестов не проверяют дополнительные функции, предоставляемые инструментом.
+Чем проще задача, которую решает инструмент, тем выше его производительность. И большинство бенчмарков не тестируют дополнительные возможности, предоставляемые инструментом.
-Иерархия инструментов имеет следующий вид:
+Иерархия выглядит так:
* **Uvicorn**: ASGI-сервер
- * **Starlette** (использует Uvicorn): веб-микрофреймворк
- * **FastAPI** (использует Starlette): API-микрофреймворк с дополнительными функциями для создания API, с валидацией данных и т.д.
+ * **Starlette**: (использует Uvicorn) веб-микрофреймворк
+ * **FastAPI**: (использует Starlette) API-микрофреймворк с рядом дополнительных возможностей для создания API, включая валидацию данных и т. п.
* **Uvicorn**:
- * Будет иметь наилучшую производительность, так как не имеет большого количества дополнительного кода, кроме самого сервера.
- * Вы не будете писать приложение на Uvicorn напрямую. Это означало бы, что Ваш код должен включать как минимум весь
- код, предоставляемый Starlette (или **FastAPI**). И если Вы так сделаете, то в конечном итоге Ваше приложение будет иметь те же накладные расходы, что и при использовании фреймворка, минимизирующего код Вашего приложения и Ваши ошибки.
- * Uvicorn подлежит сравнению с Daphne, Hypercorn, uWSGI и другими веб-серверами.
-
+ * Будет иметь наилучшую производительность, так как помимо самого сервера у него немного дополнительного кода.
+ * Вы не будете писать приложение непосредственно на Uvicorn. Это означало бы, что Ваш код должен включать как минимум весь код, предоставляемый Starlette (или **FastAPI**). И если Вы так сделаете, то в конечном итоге Ваше приложение будет иметь те же накладные расходы, что и при использовании фреймворка, минимизирующего код Вашего приложения и Ваши ошибки.
+ * Если Вы сравниваете Uvicorn, сравнивайте его с Daphne, Hypercorn, uWSGI и т. д. — серверами приложений.
* **Starlette**:
- * Будет уступать Uvicorn по производительности. Фактически Starlette управляется Uvicorn и из-за выполнения большего количества кода он не может быть быстрее, чем Uvicorn.
- * Зато он предоставляет Вам инструменты для создания простых веб-приложений с обработкой маршрутов URL и т.д.
- * Starlette следует сравнивать с Sanic, Flask, Django и другими веб-фреймворками (или микрофреймворками).
-
+ * Будет на следующем месте по производительности после Uvicorn. Фактически Starlette запускается под управлением Uvicorn, поэтому он может быть только «медленнее» Uvicorn из‑за выполнения большего объёма кода.
+ * Зато он предоставляет Вам инструменты для создания простых веб‑приложений с маршрутизацией по путям и т. п.
+ * Если Вы сравниваете Starlette, сравнивайте его с Sanic, Flask, Django и т. д. — веб‑фреймворками (или микрофреймворками).
* **FastAPI**:
- * Так же как Starlette использует Uvicorn и не может быть быстрее него, **FastAPI** использует Starlette, то есть он не может быть быстрее Starlette.
- * FastAPI предоставляет больше возможностей поверх Starlette, которые наверняка Вам понадобятся при создании API, такие как проверка данных и сериализация. В довесок Вы ещё и получаете автоматическую документацию (автоматическая документация даже не увеличивает накладные расходы при работе приложения, так как она создается при запуске).
- * Если Вы не используете FastAPI, а используете Starlette напрямую (или другой инструмент вроде Sanic, Flask, Responder и т.д.), Вам пришлось бы самостоятельно реализовать валидацию и сериализацию данных. То есть, в итоге, Ваше приложение имело бы такие же накладные расходы, как если бы оно было создано с использованием FastAPI. И во многих случаях валидация и сериализация данных представляют собой самый большой объём кода, написанного в приложениях.
- * Таким образом, используя FastAPI Вы потратите меньше времени на разработку, уменьшите количество ошибок, строк кода и, вероятно, получите ту же производительность (или лучше), как и если бы не использовали его (поскольку Вам пришлось бы реализовать все его возможности в своем коде).
- * FastAPI должно сравнивать с фреймворками веб-приложений (или наборами инструментов), которые обеспечивают валидацию и сериализацию данных, а также предоставляют автоматическую документацию, такими как Flask-apispec, NestJS, Molten и им подобные.
+ * Точно так же, как Starlette использует Uvicorn и не может быть быстрее него, **FastAPI** использует Starlette, поэтому не может быть быстрее его.
+ * FastAPI предоставляет больше возможностей поверх Starlette — те, которые почти всегда нужны при создании API, такие как валидация и сериализация данных. В довесок Вы ещё и получаете автоматическую документацию (автоматическая документация даже не увеличивает накладные расходы при работе приложения, так как она создаётся при запуске).
+ * Если бы Вы не использовали FastAPI, а использовали Starlette напрямую (или другой инструмент вроде Sanic, Flask, Responder и т. д.), Вам пришлось бы самостоятельно реализовать валидацию и сериализацию данных. То есть, в итоге, Ваше приложение имело бы такие же накладные расходы, как если бы оно было создано с использованием FastAPI. И во многих случаях валидация и сериализация данных представляют собой самый большой объём кода, написанного в приложениях.
+ * Таким образом, используя FastAPI, Вы экономите время разработки, уменьшаете количество ошибок, строк кода и, вероятно, получите ту же производительность (или лучше), как и если бы не использовали его (поскольку Вам пришлось бы реализовать все его возможности в своём коде).
+ * Если Вы сравниваете FastAPI, сравнивайте его с фреймворком веб‑приложений (или набором инструментов), который обеспечивает валидацию данных, сериализацию и документацию, такими как Flask-apispec, NestJS, Molten и им подобные. Фреймворки с интегрированной автоматической валидацией данных, сериализацией и документацией.
diff --git a/docs/ru/docs/deployment/concepts.md b/docs/ru/docs/deployment/concepts.md
index acfa1f4fe..207d1604d 100644
--- a/docs/ru/docs/deployment/concepts.md
+++ b/docs/ru/docs/deployment/concepts.md
@@ -1,323 +1,321 @@
-# Концепции развёртывания
+# Концепции развёртывания { #deployments-concepts }
-Существует несколько концепций, применяемых для развёртывания приложений **FastAPI**, равно как и для любых других типов веб-приложений, среди которых вы можете выбрать **наиболее подходящий** способ.
+При развёртывании приложения **FastAPI** (и вообще любого веб‑API) есть несколько концепций, о которых стоит думать — с их помощью можно выбрать **наиболее подходящий** способ **развёртывания вашего приложения**.
-Самые важные из них:
+Некоторые из важных концепций:
-* Использование более безопасного протокола HTTPS
-* Настройки запуска приложения
-* Перезагрузка приложения
-* Запуск нескольких экземпляров приложения
-* Управление памятью
-* Использование перечисленных функций перед запуском приложения.
+* Безопасность — HTTPS
+* Запуск при старте
+* Перезапуски
+* Репликация (количество запущенных процессов)
+* Память
+* Предварительные шаги перед запуском
-Рассмотрим ниже влияние каждого из них на процесс **развёртывания**.
+Посмотрим, как они влияют на **развёртывания**.
-Наша конечная цель - **обслуживать клиентов вашего API безопасно** и **бесперебойно**, с максимально эффективным использованием **вычислительных ресурсов** (например, удалённых серверов/виртуальных машин). 🚀
+В конечном итоге цель — **обслуживать клиентов вашего API** безопасно, **избегать перебоев** и максимально эффективно использовать **вычислительные ресурсы** (например, удалённые серверы/виртуальные машины). 🚀
-Здесь я немного расскажу Вам об этих **концепциях** и надеюсь, что у вас сложится **интуитивное понимание**, какой способ выбрать при развертывании вашего API в различных окружениях, возможно, даже **ещё не существующих**.
+Здесь я немного расскажу о этих **концепциях**, чтобы у вас появилась **интуиция**, как развёртывать ваш API в разных окружениях, возможно даже в **будущих**, которых ещё не существует.
-Ознакомившись с этими концепциями, вы сможете **оценить и выбрать** лучший способ развёртывании **Вашего API**.
+Учитывая эти концепции, вы сможете **оценить и спроектировать** лучший способ развёртывания **своих API**.
-В последующих главах я предоставлю Вам **конкретные рецепты** развёртывания приложения FastAPI.
+В следующих главах я дам более **конкретные рецепты** по развёртыванию приложений FastAPI.
-А сейчас давайте остановимся на важных **идеях этих концепций**. Эти идеи можно также применить и к другим типам веб-приложений. 💡
+А пока давайте разберём важные **идеи**. Эти концепции применимы и к другим типам веб‑API. 💡
-## Использование более безопасного протокола HTTPS
+## Безопасность — HTTPS { #security-https }
-В [предыдущей главе об HTTPS](https.md){.internal-link target=_blank} мы рассмотрели, как HTTPS обеспечивает шифрование для вашего API.
+В [предыдущей главе про HTTPS](https.md){.internal-link target=_blank} мы разобрались, как HTTPS обеспечивает шифрование для вашего API.
-Также мы заметили, что обычно для работы с HTTPS вашему приложению нужен **дополнительный** компонент - **прокси-сервер завершения работы TLS**.
+Также мы увидели, что HTTPS обычно обеспечивает компонент, **внешний** по отношению к серверу вашего приложения — **TLS Termination Proxy**.
-И если прокси-сервер не умеет сам **обновлять сертификаты HTTPS**, то нужен ещё один компонент для этого действия.
+И должен быть компонент, отвечающий за **обновление HTTPS‑сертификатов** — это может быть тот же самый компонент или отдельный.
-### Примеры инструментов для работы с HTTPS
+### Примеры инструментов для HTTPS { #example-tools-for-https }
-Вот некоторые инструменты, которые вы можете применять как прокси-серверы:
+Некоторые инструменты, которые можно использовать как TLS Termination Proxy:
* Traefik
- * С автоматическим обновлением сертификатов ✨
+ * Автоматически обновляет сертификаты ✨
* Caddy
- * С автоматическим обновлением сертификатов ✨
+ * Автоматически обновляет сертификаты ✨
* Nginx
- * С дополнительным компонентом типа Certbot для обновления сертификатов
+ * С внешним компонентом (например, Certbot) для обновления сертификатов
* HAProxy
- * С дополнительным компонентом типа Certbot для обновления сертификатов
-* Kubernetes с Ingress Controller похожим на Nginx
- * С дополнительным компонентом типа cert-manager для обновления сертификатов
-* Использование услуг облачного провайдера (читайте ниже 👇)
+ * С внешним компонентом (например, Certbot) для обновления сертификатов
+* Kubernetes с Ingress Controller (например, Nginx)
+ * С внешним компонентом (например, cert-manager) для обновления сертификатов
+* Обрабатывается внутри облачного провайдера как часть его услуг (см. ниже 👇)
-В последнем варианте вы можете воспользоваться услугами **облачного сервиса**, который сделает большую часть работы, включая настройку HTTPS. Это может наложить дополнительные ограничения или потребовать дополнительную плату и т.п. Зато Вам не понадобится самостоятельно заниматься настройками прокси-сервера.
+Другой вариант — использовать **облачный сервис**, который возьмёт на себя больше задач, включая настройку HTTPS. Там могут быть ограничения или дополнительная стоимость и т.п., но в таком случае вам не придётся самим настраивать TLS Termination Proxy.
-В дальнейшем я покажу Вам некоторые конкретные примеры их применения.
+В следующих главах я покажу конкретные примеры.
---
-Следующие концепции рассматривают применение программы, запускающей Ваш API (такой как Uvicorn).
+Далее рассмотрим концепции, связанные с программой, которая запускает ваш реальный API (например, Uvicorn).
-## Программа и процесс
+## Программа и процесс { #program-and-process }
-Мы часто будем встречать слова **процесс** и **программа**, потому следует уяснить отличия между ними.
+Мы часто будем говорить о работающем "**процессе**", поэтому полезно чётко понимать, что это значит и чем отличается от "**программы**".
-### Что такое программа
+### Что такое программа { #what-is-a-program }
-Термином **программа** обычно описывают множество вещей:
+Словом **программа** обычно называют разные вещи:
-* **Код**, который вы написали, в нашем случае **Python-файлы**.
-* **Файл**, который может быть **исполнен** операционной системой, например `python`, `python.exe` или `uvicorn`.
-* Конкретная программа, **запущенная** операционной системой и использующая центральный процессор и память. В таком случае это также называется **процесс**.
+* **Код**, который вы пишете, то есть **Python‑файлы**.
+* **Файл**, который может быть **запущен** операционной системой, например: `python`, `python.exe` или `uvicorn`.
+* Конкретную программу в момент, когда она **работает** в операционной системе, используя CPU и память. Это также называют **процессом**.
-### Что такое процесс
+### Что такое процесс { #what-is-a-process }
-Термин **процесс** имеет более узкое толкование, подразумевая что-то, запущенное операционной системой (как в последнем пункте из вышестоящего абзаца):
+Слово **процесс** обычно используют более конкретно — только для того, что реально выполняется в операционной системе (как в последнем пункте выше):
-* Конкретная программа, **запущенная** операционной системой.
- * Это не имеет отношения к какому-либо файлу или коду, но нечто **определённое**, управляемое и **выполняемое** операционной системой.
-* Любая программа, любой код, **могут делать что-то** только когда они **выполняются**. То есть, когда являются **работающим процессом**.
-* Процесс может быть **прерван** (или "убит") Вами или вашей операционной системой. В результате чего он перестанет исполняться и **не будет продолжать делать что-либо**.
-* Каждое приложение, которое вы запустили на своём компьютере, каждая программа, каждое "окно" запускает какой-то процесс. И обычно на включенном компьютере **одновременно** запущено множество процессов.
-* И **одна программа** может запустить **несколько параллельных процессов**.
+* Конкретная программа в момент, когда она **запущена** в операционной системе.
+ * Речь не о файле и не о коде, а **конкретно** о том, что **исполняется** и управляется операционной системой.
+* Любая программа, любой код **могут что‑то делать** только когда **исполняются**, то есть когда есть **работающий процесс**.
+* Процесс можно **завершить** (или «убить») вами или операционной системой. В этот момент он перестаёт выполняться и **больше ничего делать не может**.
+* У каждого запущенного приложения на вашем компьютере есть свой процесс; у каждой программы, у каждого окна и т.д. Обычно одновременно **работает много процессов**, пока компьютер включён.
+* Могут **одновременно** работать **несколько процессов** одной и той же **программы**.
-Если вы заглянете в "диспетчер задач" или "системный монитор" (или аналогичные инструменты) вашей операционной системы, то увидите множество работающих процессов.
+Если вы посмотрите «диспетчер задач» или «системный монитор» (или аналогичные инструменты) в вашей операционной системе, то увидите множество работающих процессов.
-Вполне вероятно, что вы увидите несколько процессов с одним и тем же названием браузерной программы (Firefox, Chrome, Edge и т. Д.). Обычно браузеры запускают один процесс на вкладку и вдобавок некоторые дополнительные процессы.
+Например, вы, скорее всего, увидите несколько процессов одного и того же браузера (Firefox, Chrome, Edge и т.д.). Обычно браузеры запускают один процесс на вкладку плюс дополнительные процессы.
---
-Теперь, когда нам известна разница между **процессом** и **программой**, давайте продолжим обсуждение развёртывания.
+Теперь, когда мы понимаем разницу между **процессом** и **программой**, продолжим разговор о развёртываниях.
-## Настройки запуска приложения
+## Запуск при старте { #running-on-startup }
-В большинстве случаев когда вы создаёте веб-приложение, то желаете, чтоб оно **работало постоянно** и непрерывно, предоставляя клиентам доступ в любое время. Хотя иногда у вас могут быть причины, чтоб оно запускалось только при определённых условиях.
+В большинстве случаев, создавая веб‑API, вы хотите, чтобы он **работал постоянно**, без перерывов, чтобы клиенты всегда могли к нему обратиться. Разве что у вас есть особые причины запускать его только при определённых условиях, но обычно вы хотите, чтобы он был постоянно запущен и **доступен**.
-### Удалённый сервер
+### На удалённом сервере { #in-a-remote-server }
-Когда вы настраиваете удалённый сервер (облачный сервер, виртуальную машину и т.п.), самое простое, что можно сделать, запустить Uvicorn (или его аналог) вручную, как вы делаете при локальной разработке.
+Когда вы настраиваете удалённый сервер (облачный сервер, виртуальную машину и т.п.), самый простой вариант — вручную использовать `fastapi run` (он использует Uvicorn) или что‑то похожее, как вы делаете при локальной разработке.
-Это рабочий способ и он полезен **во время разработки**.
+Это будет работать и полезно **во время разработки**.
-Но если вы потеряете соединение с сервером, то не сможете отслеживать - работает ли всё ещё **запущенный Вами процесс**.
+Но если соединение с сервером прервётся, **запущенный процесс**, скорее всего, завершится.
-И если сервер перезагрузится (например, после обновления или каких-то действий облачного провайдера), вы скорее всего **этого не заметите**, чтобы снова запустить процесс вручную. Вследствие этого Ваш API останется мёртвым. 😱
+А если сервер перезагрузится (например, после обновлений или миграций у облачного провайдера), вы, вероятно, **даже не заметите этого**. Из‑за этого вы не узнаете, что нужно вручную перезапустить процесс — и ваш API просто будет «мёртв». 😱
-### Автоматический запуск программ
+### Автоматический запуск при старте { #run-automatically-on-startup }
-Вероятно вы захотите, чтоб Ваша серверная программа (такая, как Uvicorn) стартовала автоматически при включении сервера, без **человеческого вмешательства** и всегда могла управлять Вашим API (так как Uvicorn запускает приложение FastAPI).
+Как правило, вы захотите, чтобы серверная программа (например, Uvicorn) запускалась автоматически при старте сервера и без **участия человека**, чтобы всегда был процесс, запущенный с вашим API (например, Uvicorn, запускающий ваше приложение FastAPI).
-### Отдельная программа
+### Отдельная программа { #separate-program }
-Для этого у обычно используют отдельную программу, которая следит за тем, чтобы Ваши приложения запускались при включении сервера. Такой подход гарантирует, что другие компоненты или приложения также будут запущены, например, база данных
+Чтобы этого добиться, обычно используют **отдельную программу**, которая гарантирует запуск вашего приложения при старте. Во многих случаях она также запускает и другие компоненты/приложения, например базу данных.
-### Примеры инструментов, управляющих запуском программ
+### Примеры инструментов для запуска при старте { #example-tools-to-run-at-startup }
-Вот несколько примеров, которые могут справиться с такой задачей:
+Примеры инструментов, которые могут с этим справиться:
* Docker
* Kubernetes
* Docker Compose
-* Docker в режиме Swarm
+* Docker в режиме Swarm (Swarm Mode)
* Systemd
* Supervisor
-* Использование услуг облачного провайдера
+* Обработка внутри облачного провайдера как часть его услуг
* Прочие...
-Я покажу Вам некоторые примеры их использования в следующих главах.
+Более конкретные примеры будут в следующих главах.
-## Перезапуск
+## Перезапуски { #restarts }
-Вы, вероятно, также захотите, чтоб ваше приложение **перезапускалось**, если в нём произошёл сбой.
+Подобно тому как вы обеспечиваете запуск приложения при старте, вы, вероятно, захотите обеспечить его **перезапуск** после сбоев.
-### Мы ошибаемся
+### Мы ошибаемся { #we-make-mistakes }
-Все люди совершают **ошибки**. Программное обеспечение почти *всегда* содержит **баги** спрятавшиеся в разных местах. 🐛
+Мы, люди, постоянно совершаем **ошибки**. В программном обеспечении почти всегда есть **баги**, скрытые в разных местах. 🐛
-И мы, будучи разработчиками, продолжаем улучшать код, когда обнаруживаем в нём баги или добавляем новый функционал (возможно, добавляя при этом баги 😅).
+И мы, как разработчики, продолжаем улучшать код — находим баги и добавляем новые возможности (иногда добавляя новые баги 😅).
-### Небольшие ошибки обрабатываются автоматически
+### Небольшие ошибки обрабатываются автоматически { #small-errors-automatically-handled }
-Когда вы создаёте свои API на основе FastAPI и допускаете в коде ошибку, то FastAPI обычно остановит её распространение внутри одного запроса, при обработке которого она возникла. 🛡
+Создавая веб‑API с FastAPI, если в нашем коде возникает ошибка, FastAPI обычно «локализует» её в пределах одного запроса, который эту ошибку вызвал. 🛡
-Клиент получит ошибку **500 Internal Server Error** в ответ на свой запрос, но приложение не сломается и будет продолжать работать с последующими запросами.
+Клиент получит **500 Internal Server Error** для этого запроса, но приложение продолжит работать для последующих запросов, а не «упадёт» целиком.
-### Большие ошибки - Падение приложений
+### Большие ошибки — падения { #bigger-errors-crashes }
-Тем не менее, может случиться так, что ошибка вызовет **сбой всего приложения** или даже сбой в Uvicorn, а то и в самом Python. 💥
+Тем не менее возможны случаи, когда код **роняет всё приложение**, приводя к сбою Uvicorn и Python. 💥
-Но мы всё ещё хотим, чтобы приложение **продолжало работать** несмотря на эту единственную ошибку, обрабатывая, как минимум, запросы к *операциям пути* не имеющим ошибок.
+И вы, скорее всего, не захотите, чтобы приложение оставалось «мёртвым» из‑за ошибки в одном месте — вы захотите, чтобы оно **продолжало работать** хотя бы для *операций пути*, которые не сломаны.
-### Перезапуск после падения
+### Перезапуск после падения { #restart-after-crash }
-Для случаев, когда ошибки приводят к сбою в запущенном **процессе**, Вам понадобится добавить компонент, который **перезапустит** процесс хотя бы пару раз...
+В случаях действительно серьёзных ошибок, которые роняют работающий **процесс**, вам понадобится внешний компонент, отвечающий за **перезапуск** процесса, как минимум пару раз...
-/// tip | Заметка
+/// tip | Совет
-... Если приложение падает сразу же после запуска, вероятно бесполезно его бесконечно перезапускать. Но полагаю, вы заметите такое поведение во время разработки или, по крайней мере, сразу после развёртывания.
+...Хотя если приложение **падает сразу же**, вероятно, нет смысла перезапускать его бесконечно. Но такие случаи вы, скорее всего, заметите во время разработки или как минимум сразу после развёртывания.
-Так что давайте сосредоточимся на конкретных случаях, когда приложение может полностью выйти из строя, но всё ещё есть смысл его запустить заново.
+Давайте сосредоточимся на основных сценариях, когда в каких‑то конкретных ситуациях **в будущем** приложение может падать целиком, и при этом имеет смысл его перезапускать.
///
-Возможно вы захотите, чтоб был некий **внешний компонент**, ответственный за перезапуск вашего приложения даже если уже не работает Uvicorn или Python. То есть ничего из того, что написано в вашем коде внутри приложения, не может быть выполнено в принципе.
+Скорее всего, вы захотите, чтобы перезапуском вашего приложения занимался **внешний компонент**, потому что к тому моменту Uvicorn и Python уже упали, и внутри того же кода вашего приложения сделать уже ничего нельзя.
-### Примеры инструментов для автоматического перезапуска
+### Примеры инструментов для автоматического перезапуска { #example-tools-to-restart-automatically }
-В большинстве случаев инструменты **запускающие программы при старте сервера** умеют **перезапускать** эти программы.
+В большинстве случаев тот же инструмент, который **запускает программу при старте**, умеет обрабатывать и автоматические **перезапуски**.
-В качестве примера можно взять те же:
+Например, это может быть:
* Docker
* Kubernetes
* Docker Compose
-* Docker в режиме Swarm
+* Docker в режиме Swarm (Swarm Mode)
* Systemd
* Supervisor
-* Использование услуг облачного провайдера
+* Обработка внутри облачного провайдера как часть его услуг
* Прочие...
-## Запуск нескольких экземпляров приложения (Репликация) - Процессы и память
+## Репликация — процессы и память { #replication-processes-and-memory }
-Приложение FastAPI, управляемое серверной программой (такой как Uvicorn), запускается как **один процесс** и может обслуживать множество клиентов одновременно.
+В приложении FastAPI, используя серверную программу (например, команду `fastapi`, которая запускает Uvicorn), запуск в **одном процессе** уже позволяет обслуживать нескольких клиентов одновременно.
-Но часто Вам может понадобиться несколько одновременно работающих одинаковых процессов.
+Но во многих случаях вы захотите одновременно запустить несколько процессов‑воркеров.
-### Множество процессов - Воркеры (Workers)
+### Несколько процессов — Воркеры { #multiple-processes-workers }
-Если количество Ваших клиентов больше, чем может обслужить один процесс (допустим, что виртуальная машина не слишком мощная), но при этом Вам доступно **несколько ядер процессора**, то вы можете запустить **несколько процессов** одного и того же приложения параллельно и распределить запросы между этими процессами.
+Если клиентов больше, чем способен обслужить один процесс (например, если виртуальная машина не слишком мощная), и на сервере есть **несколько ядер CPU**, вы можете запустить **несколько процессов** одного и того же приложения параллельно и распределять запросы между ними.
-**Несколько запущенных процессов** одной и той же API-программы часто называют **воркерами**.
+Когда вы запускаете **несколько процессов** одной и той же программы API, их обычно называют **воркерами**.
-### Процессы и порты́
+### Процессы‑воркеры и порты { #worker-processes-and-ports }
-Помните ли Вы, как на странице [Об HTTPS](https.md){.internal-link target=_blank} мы обсуждали, что на сервере только один процесс может слушать одну комбинацию IP-адреса и порта?
+Помните из раздела [Об HTTPS](https.md){.internal-link target=_blank}, что на сервере только один процесс может слушать конкретную комбинацию порта и IP‑адреса?
-С тех пор ничего не изменилось.
+Это по‑прежнему так.
-Соответственно, чтобы иметь возможность работать с **несколькими процессами** одновременно, должен быть **один процесс, прослушивающий порт** и затем каким-либо образом передающий данные каждому рабочему процессу.
+Поэтому, чтобы одновременно работало **несколько процессов**, должен быть **один процесс, слушающий порт**, который затем каким‑то образом передаёт коммуникацию каждому воркер‑процессу.
-### У каждого процесса своя память
+### Память на процесс { #memory-per-process }
-Работающая программа загружает в память данные, необходимые для её работы, например, переменные содержащие модели машинного обучения или большие файлы. Каждая переменная **потребляет некоторое количество оперативной памяти (RAM)** сервера.
+Когда программа загружает что‑то в память (например, модель машинного обучения в переменную или содержимое большого файла в переменную), всё это **потребляет часть памяти (RAM)** сервера.
-Обычно процессы **не делятся памятью друг с другом**. Сие означает, что каждый работающий процесс имеет свои данные, переменные и свой кусок памяти. И если для выполнения вашего кода процессу нужно много памяти, то **каждый такой же процесс** запущенный дополнительно, потребует такого же количества памяти.
+И разные процессы обычно **не делят память**. Это значит, что у каждого процесса свои переменные и своя память. Если ваш код потребляет много памяти, то **каждый процесс** будет потреблять сопоставимый объём памяти.
-### Память сервера
+### Память сервера { #server-memory }
-Допустим, что Ваш код загружает модель машинного обучения **размером 1 ГБ**. Когда вы запустите своё API как один процесс, он займёт в оперативной памяти не менее 1 ГБ. А если вы запустите **4 таких же процесса** (4 воркера), то каждый из них займёт 1 ГБ оперативной памяти. В результате вашему API потребуется **4 ГБ оперативной памяти (RAM)**.
+Например, если ваш код загружает модель Машинного обучения размером **1 ГБ**, то при запуске одного процесса с вашим API он будет использовать как минимум 1 ГБ RAM. А если вы запустите **4 процесса** (4 воркера), каждый процесс будет использовать 1 ГБ RAM. Всего ваш API будет потреблять **4 ГБ RAM**.
-И если Ваш удалённый сервер или виртуальная машина располагает только 3 ГБ памяти, то попытка загрузить в неё 4 ГБ данных вызовет проблемы. 🚨
+И если у вашего удалённого сервера или виртуальной машины только 3 ГБ RAM, попытка загрузить более 4 ГБ вызовет проблемы. 🚨
-### Множество процессов - Пример
+### Несколько процессов — пример { #multiple-processes-an-example }
-В этом примере **менеджер процессов** запустит и будет управлять двумя **воркерами**.
+В этом примере есть **процесс‑менеджер**, который запускает и контролирует два **процесса‑воркера**.
-Менеджер процессов будет слушать определённый **сокет** (IP:порт) и передавать данные работающим процессам.
+Процесс‑менеджер, вероятно, будет тем, кто слушает **порт** на IP. И он будет передавать всю коммуникацию воркер‑процессам.
-Каждый из этих процессов будет запускать ваше приложение для обработки полученного **запроса** и возвращения вычисленного **ответа** и они будут использовать оперативную память.
+Эти воркеры будут запускать ваше приложение, выполнять основные вычисления для получения **запроса** и возврата **ответа**, и загружать всё, что вы кладёте в переменные, в RAM.