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 | Совет
+
+Имейте в виду, что если вы возвращаете ответ напрямую, вместо использования параметра `Response`, FastAPI вернёт его напрямую.
-Убедитесь, что ваши данные имеют корректный тип. Например, они должны быть совместимы с JSON, если вы используете `JSONResponse`.
+Убедитесь, что ваши данные имеют корректный тип. Например, они должны быть совместимы с 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"):
```console
$ pip install -r requirements.txt
---> 100%
-Successfully installed fastapi pydantic uvicorn
+Successfully installed fastapi pydantic
```
/// info | Информация
-Существуют и другие инструменты управления зависимостями.
-
-В этом же разделе, но позже, я покажу вам пример использования Poetry. 👇
+Существуют и другие форматы и инструменты для описания и установки зависимостей.
///
-### Создать приложение **FastAPI**
+### Создать код **FastAPI** { #create-the-fastapi-code }
* Создайте директорию `app` и перейдите в неё.
* Создайте пустой файл `__init__.py`.
-* Создайте файл `main.py` и заполните его:
+* Создайте файл `main.py` со следующим содержимым:
```Python
from typing import Union
@@ -167,77 +162,109 @@ def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
```
-### Dockerfile
+### Dockerfile { #dockerfile }
-В этой же директории создайте файл `Dockerfile` и заполните его:
+Теперь в той же директории проекта создайте файл `Dockerfile`:
```{ .dockerfile .annotate }
-# (1)
+# (1)!
FROM python:3.9
-# (2)
+# (2)!
WORKDIR /code
-# (3)
+# (3)!
COPY ./requirements.txt /code/requirements.txt
-# (4)
+# (4)!
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
-# (5)
+# (5)!
COPY ./app /code/app
-# (6)
-CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+# (6)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80"]
```
-1. Начните с официального образа Python, который будет основой для образа приложения.
+1. Начинаем с официального базового образа Python.
-2. Укажите, что в дальнейшем команды запускаемые в контейнере, будут выполняться в директории `/code`.
+2. Устанавливаем текущую рабочую директорию в `/code`.
- Инструкция создаст эту директорию внутри контейнера и мы поместим в неё файл `requirements.txt` и директорию `app`.
+ Здесь мы разместим файл `requirements.txt` и директорию `app`.
-3. Скопируете файл с зависимостями из текущей директории в `/code`.
+3. Копируем файл с зависимостями в директорию `/code`.
- Сначала копируйте **только** файл с зависимостями.
+ Сначала копируйте **только** файл с зависимостями, не остальной код.
- Этот файл **изменяется довольно редко**, Docker ищет изменения при постройке образа и если не находит, то использует **кэш**, в котором хранятся предыдущие версии сборки образа.
+ Так как этот файл **меняется нечасто**, Docker определит это и использует **кэш** на этом шаге, что позволит использовать кэш и на следующем шаге.
-4. Установите библиотеки перечисленные в файле с зависимостями.
+4. Устанавливаем зависимости из файла с требованиями.
- Опция `--no-cache-dir` указывает `pip` не сохранять загружаемые библиотеки на локальной машине для использования их в случае повторной загрузки. В контейнере, в случае пересборки этого шага, они всё равно будут удалены.
+ Опция `--no-cache-dir` указывает `pip` не сохранять загруженные пакеты локально, т.к. это нужно только если `pip` будет запускаться снова для установки тех же пакетов, а при работе с контейнерами это обычно не требуется.
/// note | Заметка
- Опция `--no-cache-dir` нужна только для `pip`, она никак не влияет на Docker или контейнеры.
+ `--no-cache-dir` относится только к `pip` и не имеет отношения к Docker или контейнерам.
///
- Опция `--upgrade` указывает `pip` обновить библиотеки, емли они уже установлены.
+ Опция `--upgrade` указывает `pip` обновлять пакеты, если они уже установлены.
- Как и в предыдущем шаге с копированием файла, этот шаг также будет использовать **кэш Docker** в случае отсутствия изменений.
+ Поскольку предыдущий шаг с копированием файла может быть обработан **кэшем Docker**, этот шаг также **использует кэш Docker**, когда это возможно.
- Использование кэша, особенно на этом шаге, позволит вам **сэкономить** кучу времени при повторной сборке образа, так как зависимости будут сохранены в кеше, а не **загружаться и устанавливаться каждый раз**.
+ Использование кэша на этом шаге **сэкономит** вам много **времени** при повторных сборках образа во время разработки, вместо того чтобы **загружать и устанавливать** все зависимости **каждый раз**.
-5. Скопируйте директорию `./app` внутрь директории `/code` (в контейнере).
+5. Копируем директорию `./app` внутрь директории `/code`.
- Так как в этой директории расположен код, который **часто изменяется**, то использование **кэша** на этом шаге будет наименее эффективно, а значит лучше поместить этот шаг **ближе к концу** `Dockerfile`, дабы не терять выгоду от оптимизации предыдущих шагов.
+ Так как здесь весь код, который **меняется чаще всего**, кэш Docker **вряд ли** будет использоваться для этого шагa или **последующих шагов**.
-6. Укажите **команду**, запускающую сервер `uvicorn`.
+ Поэтому важно разместить этот шаг **ближе к концу** `Dockerfile`, чтобы оптимизировать время сборки образа контейнера.
- `CMD` принимает список строк, разделённых запятыми, но при выполнении объединит их через пробел, собрав из них одну команду, которую вы могли бы написать в терминале.
+6. Указываем **команду** для запуска `fastapi run`, под капотом используется Uvicorn.
- Эта команда будет выполнена в **текущей рабочей директории**, а именно в директории `/code`, которая указана в команде `WORKDIR /code`.
+ `CMD` принимает список строк, каждая из которых — это то, что вы бы ввели в командной строке, разделяя пробелами.
- Так как команда выполняется внутри директории `/code`, в которую мы поместили папку `./app` с приложением, то **Uvicorn** сможет найти и **импортировать** объект `app` из файла `app.main`.
+ Эта команда будет выполнена из **текущей рабочей директории**, той самой `/code`, которую вы задали выше `WORKDIR /code`.
/// tip | Подсказка
-Если ткнёте на кружок с плюсом, то увидите пояснения. 👆
+Посмотрите, что делает каждая строка, кликнув по номеру рядом со строкой. 👆
+
+///
+
+/// warning | Предупреждение
+
+Всегда используйте **exec-форму** инструкции `CMD`, как описано ниже.
///
-На данном этапе структура проекта должны выглядеть так:
+#### Используйте `CMD` — exec-форма { #use-cmd-exec-form }
+
+Инструкцию Docker
@@ -308,15 +334,15 @@ $ docker build -t myimage .
/// tip | Подсказка
-Обратите внимание, что в конце написана точка - `.`, это то же самое что и `./`, тем самым мы указываем Docker директорию, из которой нужно выполнять сборку образа контейнера.
+Обратите внимание на точку `.` в конце — это то же самое, что `./`. Так мы указываем Docker, из какой директории собирать образ контейнера.
-В данном случае это та же самая директория (`.`).
+В данном случае это текущая директория (`.`).
///
-### Запуск Docker-контейнера
+### Запустить Docker-контейнер { #start-the-docker-container }
-* Запустите контейнер, основанный на вашем образе:
+* Запустите контейнер на основе вашего образа:
@@ -326,35 +352,35 @@ $ docker run -d --name mycontainer -p 80:80 myimage
-## Проверка
+## Проверка { #check-it }
-Вы можете проверить, что Ваш Docker-контейнер работает перейдя по ссылке:
http://192.168.99.100/items/5?q=somequery или
http://127.0.0.1/items/5?q=somequery (или похожей, которую использует Ваш Docker-хост).
+Проверьте работу по адресу вашего Docker-хоста, например:
http://192.168.99.100/items/5?q=somequery или
http://127.0.0.1/items/5?q=somequery (или аналогичный URL вашего Docker-хоста).
-Там вы увидите:
+Вы увидите что-то вроде:
```JSON
{"item_id": 5, "q": "somequery"}
```
-## Интерактивная документация API
+## Интерактивная документация API { #interactive-api-docs }
-Теперь перейдите по ссылке
http://192.168.99.100/docs или
http://127.0.0.1/docs (или похожей, которую использует Ваш Docker-хост).
+Теперь зайдите на
http://192.168.99.100/docs или
http://127.0.0.1/docs (или аналогичный URL вашего Docker-хоста).
-Здесь вы увидите автоматическую интерактивную документацию API (предоставляемую
Swagger UI):
+Вы увидите автоматическую интерактивную документацию API (на базе
Swagger UI):

-## Альтернативная документация API
+## Альтернативная документация API { #alternative-api-docs }
-Также вы можете перейти по ссылке
http://192.168.99.100/redoc or
http://127.0.0.1/redoc (или похожей, которую использует Ваш Docker-хост).
+Также можно открыть
http://192.168.99.100/redoc или
http://127.0.0.1/redoc (или аналогичный URL вашего Docker-хоста).
-Здесь вы увидите альтернативную автоматическую документацию API (предоставляемую
ReDoc):
+Вы увидите альтернативную автоматическую документацию (на базе
ReDoc):

-## Создание Docker-образа на основе однофайлового приложения FastAPI
+## Собрать Docker-образ для однофайлового FastAPI { #build-a-docker-image-with-a-single-file-fastapi }
-Если ваше приложение FastAPI помещено в один файл, например, `main.py` и структура Ваших файлов похожа на эту:
+Если ваше приложение FastAPI — один файл, например `main.py` без директории `./app`, структура файлов может быть такой:
```
.
@@ -363,7 +389,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
└── requirements.txt
```
-Вам нужно изменить в `Dockerfile` соответствующие пути копирования файлов:
+Тогда в `Dockerfile` нужно изменить пути копирования:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.9
@@ -374,360 +400,221 @@ COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
-# (1)
+# (1)!
COPY ./main.py /code/
-# (2)
-CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
+# (2)!
+CMD ["fastapi", "run", "main.py", "--port", "80"]
```
-1. Скопируйте непосредственно файл `main.py` в директорию `/code` (не указывайте `./app`).
+1. Копируем файл `main.py` напрямую в `/code` (без директории `./app`).
-2. При запуске Uvicorn укажите ему, что объект `app` нужно импортировать из файла `main` (вместо импортирования из `app.main`).
+2. Используем `fastapi run` для запуска приложения из одного файла `main.py`.
-Настройте Uvicorn на использование `main` вместо `app.main` для импорта объекта `app`.
+Когда вы передаёте файл в `fastapi run`, он автоматически определит, что это одиночный файл, а не часть пакета, и поймёт, как его импортировать и запустить ваше FastAPI-приложение. 😎
-## Концепции развёртывания
+## Концепции развертывания { #deployment-concepts }
-Давайте вспомним о [Концепциях развёртывания](concepts.md){.internal-link target=_blank} и применим их к контейнерам.
+Ещё раз рассмотрим [концепции развертывания](concepts.md){.internal-link target=_blank} применительно к контейнерам.
-Контейнеры - это, в основном, инструмент упрощающий **сборку и развёртывание** приложения и они не обязывают к применению какой-то определённой **концепции развёртывания**, а значит мы можем выбирать нужную стратегию.
+Контейнеры главным образом упрощают **сборку и развёртывание** приложения, но не навязывают конкретный подход к этим **концепциям развертывания**, и существует несколько стратегий.
-**Хорошая новость** в том, что независимо от выбранной стратегии, мы всё равно можем покрыть все концепции развёртывания. 🎉
+**Хорошая новость** в том, что при любой стратегии есть способ охватить все концепции развертывания. 🎉
-Рассмотрим эти **концепции развёртывания** применительно к контейнерам:
+Рассмотрим эти **концепции развертывания** в терминах контейнеров:
-* Использование более безопасного протокола HTTPS
-* Настройки запуска приложения
-* Перезагрузка приложения
-* Запуск нескольких экземпляров приложения
-* Управление памятью
-* Использование перечисленных функций перед запуском приложения
+* HTTPS
+* Запуск при старте
+* Перезапуски
+* Репликация (количество запущенных процессов)
+* Память
+* Предварительные шаги перед запуском
-## Использование более безопасного протокола HTTPS
+## HTTPS { #https }
-Если мы определимся, что **образ контейнера** будет содержать только приложение FastAPI, то работу с HTTPS можно организовать **снаружи** контейнера при помощи другого инструмента.
+Если мы рассматриваем только **образ контейнера** для приложения FastAPI (и далее запущенный **контейнер**), то HTTPS обычно обрабатывается **внешним** инструментом.
-Это может быть другой контейнер, в котором есть, например,
Traefik, работающий с **HTTPS** и **самостоятельно** обновляющий **сертификаты**.
+Это может быть другой контейнер, например с
Traefik, который берёт на себя **HTTPS** и **автоматическое** получение **сертификатов**.
/// tip | Подсказка
-Traefik совместим с Docker, Kubernetes и им подобными инструментами. Он очень прост в установке и настройке использования HTTPS для Ваших контейнеров.
+У Traefik есть интеграции с Docker, Kubernetes и другими, поэтому очень легко настроить и сконфигурировать HTTPS для ваших контейнеров.
///
-В качестве альтернативы, работу с HTTPS можно доверить облачному провайдеру, если он предоставляет такую услугу.
+В качестве альтернативы HTTPS может быть реализован как сервис облачного провайдера (при этом приложение всё равно работает в контейнере).
-## Настройки запуска и перезагрузки приложения
+## Запуск при старте и перезапуски { #running-on-startup-and-restarts }
-Обычно **запуском контейнера с приложением** занимается какой-то отдельный инструмент.
+Обычно есть другой инструмент, отвечающий за **запуск и работу** вашего контейнера.
-Это может быть сам **Docker**, **Docker Compose**, **Kubernetes**, **облачный провайдер** и т.п.
+Это может быть сам **Docker**, **Docker Compose**, **Kubernetes**, **облачный сервис** и т.п.
-В большинстве случаев это простейшие настройки запуска и перезагрузки приложения (при падении). Например, команде запуска Docker-контейнера можно добавить опцию `--restart`.
+В большинстве (или во всех) случаев есть простая опция, чтобы включить запуск контейнера при старте системы и перезапуски при сбоях. Например, в Docker это опция командной строки `--restart`.
-Управление запуском и перезагрузкой приложений без использования контейнеров - весьма затруднительно. Но при **работе с контейнерами** - это всего лишь функционал доступный по умолчанию. ✨
+Без контейнеров обеспечить запуск при старте и перезапуски может быть сложно. Но при **работе с контейнерами** в большинстве случаев этот функционал доступен по умолчанию. ✨
-## Запуск нескольких экземпляров приложения - Указание количества процессов
+## Репликация — количество процессов { #replication-number-of-processes }
-Если у вас есть
кластер машин под управлением **Kubernetes**, Docker Swarm Mode, Nomad или аналогичной сложной системой оркестрации контейнеров, скорее всего, вместо использования менеджера процессов (типа Gunicorn и его воркеры) в каждом контейнере, вы захотите **управлять количеством запущенных экземпляров приложения** на **уровне кластера**.
+Если у вас есть
кластер машин с **Kubernetes**, Docker Swarm Mode, Nomad или другой похожей системой для управления распределёнными контейнерами на нескольких машинах, скорее всего вы будете **управлять репликацией** на **уровне кластера**, а не использовать **менеджер процессов** (например, Uvicorn с воркерами) в каждом контейнере.
-В любую из этих систем управления контейнерами обычно встроен способ управления **количеством запущенных контейнеров** для распределения **нагрузки** от входящих запросов на **уровне кластера**.
+Одна из таких систем управления распределёнными контейнерами, как Kubernetes, обычно имеет встроенный способ управлять **репликацией контейнеров**, поддерживая **балансировку нагрузки** для входящих запросов — всё это на **уровне кластера**.
-В такой ситуации Вы, вероятно, захотите создать **образ Docker**, как [описано выше](#dockerfile), с установленными зависимостями и запускающий **один процесс Uvicorn** вместо того, чтобы запускать Gunicorn управляющий несколькими воркерами Uvicorn.
+В таких случаях вы, скорее всего, захотите собрать **Docker-образ с нуля**, как [описано выше](#dockerfile), установить зависимости и запускать **один процесс Uvicorn** вместо множества воркеров Uvicorn.
-### Балансировщик нагрузки
+### Балансировщик нагрузки { #load-balancer }
-Обычно при использовании контейнеров один компонент **прослушивает главный порт**. Это может быть контейнер содержащий **прокси-сервер завершения работы TLS** для работы с **HTTPS** или что-то подобное.
+При использовании контейнеров обычно есть компонент, **слушающий главный порт**. Это может быть другой контейнер — **прокси завершения TLS** для обработки **HTTPS** или похожий инструмент.
-Поскольку этот компонент **принимает запросы** и равномерно **распределяет** их между компонентами, его также называют **балансировщиком нагрузки**.
+Поскольку этот компонент принимает **нагрузку** запросов и распределяет её между воркерами **сбалансированно**, его часто называют **балансировщиком нагрузки**.
/// tip | Подсказка
-**Прокси-сервер завершения работы TLS** одновременно может быть **балансировщиком нагрузки**.
+Тот же компонент **прокси завершения TLS**, который обрабатывает HTTPS, скорее всего также будет **балансировщиком нагрузки**.
///
-Система оркестрации, которую вы используете для запуска и управления контейнерами, имеет встроенный инструмент **сетевого взаимодействия** (например, для передачи HTTP-запросов) между контейнерами с Вашими приложениями и **балансировщиком нагрузки** (который также может быть **прокси-сервером**).
+При работе с контейнерами система, которую вы используете для запуска и управления ими, уже имеет внутренние средства для передачи **сетевого взаимодействия** (например, HTTP-запросов) от **балансировщика нагрузки** (который также может быть **прокси завершения TLS**) к контейнеру(-ам) с вашим приложением.
-### Один балансировщик - Множество контейнеров
+### Один балансировщик — несколько контейнеров-воркеров { #one-load-balancer-multiple-worker-containers }
-При работе с **Kubernetes** или аналогичными системами оркестрации использование их внутренней сети позволяет иметь один **балансировщик нагрузки**, который прослушивает **главный** порт и передаёт запросы **множеству запущенных контейнеров** с Вашими приложениями.
+При работе с **Kubernetes** или похожими системами управления распределёнными контейнерами их внутренние механизмы сети позволяют одному **балансировщику нагрузки**, слушающему главный **порт**, передавать запросы в **несколько контейнеров**, где запущено ваше приложение.
-В каждом из контейнеров обычно работает **только один процесс** (например, процесс Uvicorn управляющий Вашим приложением FastAPI). Контейнеры могут быть **идентичными**, запущенными на основе одного и того же образа, но у каждого будут свои отдельные процесс, память и т.п. Таким образом мы получаем преимущества **распараллеливания** работы по **разным ядрам** процессора или даже **разным машинам**.
+Каждый такой контейнер с вашим приложением обычно имеет **только один процесс** (например, процесс Uvicorn с вашим приложением FastAPI). Все они — **одинаковые контейнеры**, запускающие одно и то же, но у каждого свой процесс, память и т.п. Так вы используете **параллелизм** по **разным ядрам** CPU или даже **разным машинам**.
-Система управления контейнерами с **балансировщиком нагрузки** будет **распределять запросы** к контейнерам с приложениями **по очереди**. То есть каждый запрос будет обработан одним из множества **одинаковых контейнеров** с одним и тем же приложением.
+Система распределённых контейнеров с **балансировщиком нагрузки** будет **распределять запросы** между контейнерами с вашим приложением **по очереди**. То есть каждый запрос может обрабатываться одним из нескольких **реплицированных контейнеров**.
-**Балансировщик нагрузки** может обрабатывать запросы к *разным* приложениям, расположенным в вашем кластере (например, если у них разные домены или префиксы пути) и передавать запросы нужному контейнеру с требуемым приложением.
+Обычно такой **балансировщик нагрузки** может также обрабатывать запросы к *другим* приложениям в вашем кластере (например, к другому домену или под другим префиксом пути URL) и направлять их к нужным контейнерам этого *другого* приложения.
-### Один процесс на контейнер
+### Один процесс на контейнер { #one-process-per-container }
-В этом варианте **в одном контейнере будет запущен только один процесс (Uvicorn)**, а управление изменением количества запущенных копий приложения происходит на уровне кластера.
+В таком сценарии, скорее всего, вы захотите иметь **один (Uvicorn) процесс на контейнер**, так как репликация уже управляется на уровне кластера.
-Здесь **не нужен** менеджер процессов типа Gunicorn, управляющий процессами Uvicorn, или же Uvicorn, управляющий другими процессами Uvicorn. Достаточно **только одного процесса Uvicorn** на контейнер (но запуск нескольких процессов не запрещён).
+Поэтому в контейнере **не нужно** поднимать несколько воркеров, например через опцию командной строки `--workers`. Нужен **один процесс Uvicorn** на контейнер (но, возможно, несколько контейнеров).
-Использование менеджера процессов (Gunicorn или Uvicorn) внутри контейнера только добавляет **излишнее усложнение**, так как управление следует осуществлять системой оркестрации.
+Наличие отдельного менеджера процессов внутри контейнера (как при нескольких воркерах) только добавит **лишнюю сложность**, которую, вероятно, уже берёт на себя ваша кластерная система.
-### Множество процессов внутри контейнера для особых случаев
+### Контейнеры с несколькими процессами и особые случаи { #containers-with-multiple-processes-and-special-cases }
-Безусловно, бывают **особые случаи**, когда может понадобиться внутри контейнера запускать **менеджер процессов Gunicorn**, управляющий несколькими **процессами Uvicorn**.
+Конечно, есть **особые случаи**, когда может понадобиться **контейнер** с несколькими **воркерами Uvicorn** внутри.
-Для таких случаев вы можете использовать **официальный Docker-образ** (прим. пер: - *здесь и далее на этой странице, если вы встретите сочетание "официальный Docker-образ" без уточнений, то автор имеет в виду именно предоставляемый им образ*), где в качестве менеджера процессов используется **Gunicorn**, запускающий несколько **процессов Uvicorn** и некоторые настройки по умолчанию, автоматически устанавливающие количество запущенных процессов в зависимости от количества ядер вашего процессора. Я расскажу вам об этом подробнее тут: [Официальный Docker-образ со встроенными Gunicorn и Uvicorn](#docker-gunicorn-uvicorn).
+В таких случаях вы можете использовать опцию командной строки `--workers`, чтобы указать нужное количество воркеров:
-Некоторые примеры подобных случаев:
+```{ .dockerfile .annotate }
+FROM python:3.9
-#### Простое приложение
+WORKDIR /code
-Вы можете использовать менеджер процессов внутри контейнера, если ваше приложение **настолько простое**, что у вас нет необходимости (по крайней мере, пока нет) в тщательных настройках количества процессов и вам достаточно имеющихся настроек по умолчанию (если используется официальный Docker-образ) для запуска приложения **только на одном сервере**, а не в кластере.
+COPY ./requirements.txt /code/requirements.txt
-#### Docker Compose
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
-С помощью **Docker Compose** можно разворачивать несколько контейнеров на **одном сервере** (не кластере), но при это у вас не будет простого способа управления количеством запущенных контейнеров с одновременным сохранением общей сети и **балансировки нагрузки**.
+COPY ./app /code/app
-В этом случае можно использовать **менеджер процессов**, управляющий **несколькими процессами**, внутри **одного контейнера**.
+# (1)!
+CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
+```
-#### Prometheus и прочие причины
+1. Здесь мы используем опцию `--workers`, чтобы установить число воркеров равным 4.
-У вас могут быть и **другие причины**, когда использование **множества процессов** внутри **одного контейнера** будет проще, нежели запуск **нескольких контейнеров** с **единственным процессом** в каждом из них.
+Примеры, когда это может быть уместно:
-Например (в зависимости от конфигурации), у вас могут быть инструменты подобные экспортёру Prometheus, которые должны иметь доступ к **каждому запросу** приходящему в контейнер.
+#### Простое приложение { #a-simple-app }
-Если у вас будет **несколько контейнеров**, то Prometheus, по умолчанию, **при сборе метрик** получит их **только с одного контейнера**, который обрабатывает конкретный запрос, вместо **сбора метрик** со всех работающих контейнеров.
+Вам может понадобиться менеджер процессов в контейнере, если приложение **достаточно простое**, чтобы запускаться на **одном сервере**, а не в кластере.
-В таком случае может быть проще иметь **один контейнер** со **множеством процессов**, с нужным инструментом (таким как экспортёр Prometheus) в этом же контейнере и собирающем метрики со всех внутренних процессов этого контейнера.
+#### Docker Compose { #docker-compose }
+
+Вы можете развёртывать на **одном сервере** (не кластере) с **Docker Compose**, и у вас не будет простого способа управлять репликацией контейнеров (в Docker Compose), сохраняя общую сеть и **балансировку нагрузки**.
+
+Тогда вы можете захотеть **один контейнер** с **менеджером процессов**, который запускает **несколько воркеров** внутри.
---
-Самое главное - **ни одно** из перечисленных правил не является **высеченным на камне** и вы не обязаны слепо их повторять. вы можете использовать эти идеи при **рассмотрении вашего конкретного случая** и самостоятельно решать, какая из концепции подходит лучше:
+Главное — **ни одно** из этих правил не является **строго обязательным**. Используйте эти идеи, чтобы **оценить свой конкретный случай** и решить, какой подход лучше для вашей системы, учитывая:
-* Использование более безопасного протокола HTTPS
-* Настройки запуска приложения
-* Перезагрузка приложения
-* Запуск нескольких экземпляров приложения
-* Управление памятью
-* Использование перечисленных функций перед запуском приложения
+* Безопасность — HTTPS
+* Запуск при старте
+* Перезапуски
+* Репликацию (количество запущенных процессов)
+* Память
+* Предварительные шаги перед запуском
-## Управление памятью
+## Память { #memory }
-При **запуске одного процесса на контейнер** вы получаете относительно понятный, стабильный и ограниченный объём памяти, потребляемый одним контейнером.
+Если вы запускаете **один процесс на контейнер**, у каждого контейнера будет более-менее чётко определённый, стабильный и ограниченный объём потребляемой памяти (контейнеров может быть несколько при репликации).
-Вы можете установить аналогичные ограничения по памяти при конфигурировании своей системы управления контейнерами (например, **Kubernetes**). Таким образом система сможет **изменять количество контейнеров** на **доступных ей машинах** приводя в соответствие количество памяти нужной контейнерам с количеством памяти доступной в кластере (наборе доступных машин).
+Затем вы можете задать такие же лимиты и требования по памяти в конфигурации вашей системы управления контейнерами (например, в **Kubernetes**). Так система сможет **реплицировать контейнеры** на **доступных машинах**, учитывая объём необходимой памяти и доступной памяти в машинах кластера.
-Если у вас **простенькое** приложение, вероятно у вас не будет **необходимости** устанавливать жёсткие ограничения на выделяемую ему память. Но если приложение **использует много памяти** (например, оно использует модели **машинного обучения**), вам следует проверить, как много памяти ему требуется и отрегулировать **количество контейнеров** запущенных на **каждой машине** (может быть даже добавить машин в кластер).
+Если приложение **простое**, это, вероятно, **не будет проблемой**, и жёсткие лимиты памяти можно не указывать. Но если вы **используете много памяти** (например, с моделями **Машинного обучения**), проверьте, сколько памяти потребляется, и отрегулируйте **число контейнеров** на **каждой машине** (и, возможно, добавьте машины в кластер).
-Если вы запускаете **несколько процессов в контейнере**, то должны быть уверены, что эти процессы не **займут памяти больше**, чем доступно для контейнера.
+Если вы запускаете **несколько процессов в контейнере**, нужно убедиться, что их суммарное потребление **не превысит доступную память**.
-## Подготовительные шаги при запуске контейнеров
+## Предварительные шаги перед запуском и контейнеры { #previous-steps-before-starting-and-containers }
-Есть два основных подхода, которые вы можете использовать при запуске контейнеров (Docker, Kubernetes и т.п.).
+Если вы используете контейнеры (например, Docker, Kubernetes), есть два основных подхода.
-### Множество контейнеров
+### Несколько контейнеров { #multiple-containers }
-Когда вы запускаете **множество контейнеров**, в каждом из которых работает **только один процесс** (например, в кластере **Kubernetes**), может возникнуть необходимость иметь **отдельный контейнер**, который осуществит **предварительные шаги перед запуском** остальных контейнеров (например, применяет миграции к базе данных).
+Если у вас **несколько контейнеров**, и, вероятно, каждый запускает **один процесс** (например, в кластере **Kubernetes**), то вы, скорее всего, захотите иметь **отдельный контейнер**, выполняющий **предварительные шаги** в одном контейнере и одном процессе **до** запуска реплицированных контейнеров-воркеров.
/// info | Информация
-При использовании Kubernetes, это может быть
Инициализирующий контейнер.
+Если вы используете Kubernetes, это, вероятно, будет
Init Container.
///
-При отсутствии такой необходимости (допустим, не нужно применять миграции к базе данных, а только проверить, что она готова принимать соединения), вы можете проводить такую проверку в каждом контейнере перед запуском его основного процесса и запускать все контейнеры **одновременно**.
-
-### Только один контейнер
-
-Если у вас несложное приложение для работы которого достаточно **одного контейнера**, но в котором работает **несколько процессов** (или один процесс), то прохождение предварительных шагов можно осуществить в этом же контейнере до запуска основного процесса. Официальный Docker-образ поддерживает такие действия.
+Если в вашем случае нет проблемы с тем, чтобы выполнять эти предварительные шаги **многократно и параллельно** (например, вы не запускаете миграции БД, а только проверяете готовность БД), вы можете просто выполнить их в каждом контейнере прямо перед стартом основного процесса.
-## Официальный Docker-образ с Gunicorn и Uvicorn
+### Один контейнер { #single-container }
-Я подготовил для вас Docker-образ, в который включён Gunicorn управляющий процессами (воркерами) Uvicorn, в соответствии с концепциями рассмотренными в предыдущей главе: [Рабочие процессы сервера (воркеры) - Gunicorn совместно с Uvicorn](server-workers.md){.internal-link target=_blank}.
+Если у вас простая схема с **одним контейнером**, который затем запускает несколько **воркеров** (или один процесс), можно выполнить подготовительные шаги в этом же контейнере непосредственно перед запуском процесса с приложением.
-Этот образ может быть полезен для ситуаций описанных тут: [Множество процессов внутри контейнера для особых случаев](#_11).
-
-*
tiangolo/uvicorn-gunicorn-fastapi.
-
-/// warning | Предупреждение
+### Базовый Docker-образ { #base-docker-image }
-Скорее всего у вас **нет необходимости** в использовании этого образа или подобного ему и лучше создать свой образ с нуля как описано тут: [Создать Docker-образ для FastAPI](#docker-fastapi).
+Ранее существовал официальный Docker-образ FastAPI:
tiangolo/uvicorn-gunicorn-fastapi. Сейчас он помечен как устаревший. ⛔️
-///
+Скорее всего, вам **не стоит** использовать этот базовый образ (или какой-либо аналогичный).
-В этом образе есть **автоматический** механизм подстройки для запуска **необходимого количества процессов** в соответствии с доступным количеством ядер процессора.
+Если вы используете **Kubernetes** (или другое) и уже настраиваете **репликацию** на уровне кластера через несколько **контейнеров**, в этих случаях лучше **собрать образ с нуля**, как описано выше: [Создать Docker-образ для FastAPI](#build-a-docker-image-for-fastapi).
-В нём установлены **разумные значения по умолчанию**, но можно изменять и обновлять конфигурацию с помощью **переменных окружения** или конфигурационных файлов.
+А если вам нужны несколько воркеров, просто используйте опцию командной строки `--workers`.
-Он также поддерживает прохождение
**Подготовительных шагов при запуске контейнеров** при помощи скрипта.
+/// note | Технические подробности
-/// tip | Подсказка
+Этот Docker-образ был создан в то время, когда Uvicorn не умел управлять и перезапускать «упавших» воркеров, и приходилось использовать Gunicorn вместе с Uvicorn, что добавляло заметную сложность, лишь бы Gunicorn управлял и перезапускал воркеров Uvicorn.
-Для просмотра всех возможных настроек перейдите на страницу этого Docker-образа:
tiangolo/uvicorn-gunicorn-fastapi.
+Но теперь, когда Uvicorn (и команда `fastapi`) поддерживают `--workers`, нет причин использовать базовый Docker-образ вместо сборки своего (кода получается примерно столько же 😅).
///
-### Количество процессов в официальном Docker-образе
-
-**Количество процессов** в этом образе **вычисляется автоматически** и зависит от доступного количества **ядер** центрального процессора.
-
-Это означает, что он будет пытаться **выжать** из процессора как можно больше **производительности**.
-
-Но вы можете изменять и обновлять конфигурацию с помощью **переменных окружения** и т.п.
-
-Поскольку количество процессов зависит от процессора, на котором работает контейнер, **объём потребляемой памяти** также будет зависеть от этого.
-
-А значит, если вашему приложению требуется много оперативной памяти (например, оно использует модели машинного обучения) и Ваш сервер имеет центральный процессор с большим количеством ядер, но **не слишком большим объёмом оперативной памяти**, то может дойти до того, что контейнер попытается занять памяти больше, чем доступно, из-за чего будет падение производительности (или сервер вовсе упадёт). 🚨
-
-
-### Написание `Dockerfile`
-
-Итак, теперь мы можем написать `Dockerfile` основанный на этом официальном Docker-образе:
-
-```Dockerfile
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
-
-COPY ./requirements.txt /app/requirements.txt
-
-RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
-
-COPY ./app /app
-```
-
-### Большие приложения
-
-Если вы успели ознакомиться с разделом [Приложения содержащие много файлов](../tutorial/bigger-applications.md){.internal-link target=_blank}, состоящие из множества файлов, Ваш Dockerfile может выглядеть так:
-
-```Dockerfile hl_lines="7"
-FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
-
-COPY ./requirements.txt /app/requirements.txt
+## Развёртывание образа контейнера { #deploy-the-container-image }
-RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
-
-COPY ./app /app/app
-```
-
-### Как им пользоваться
-
-Если вы используете **Kubernetes** (или что-то вроде того), скорее всего вам **не нужно** использовать официальный Docker-образ (или другой похожий) в качестве основы, так как управление **количеством запущенных контейнеров** должно быть настроено на уровне кластера. В таком случае лучше **создать образ с нуля**, как описано в разделе Создать [Docker-образ для FastAPI](#docker-fastapi).
-
-Официальный образ может быть полезен в отдельных случаях, описанных выше в разделе [Множество процессов внутри контейнера для особых случаев](#_11). Например, если ваше приложение **достаточно простое**, не требует запуска в кластере и способно уместиться в один контейнер, то его настройки по умолчанию будут работать довольно хорошо. Или же вы развертываете его с помощью **Docker Compose**, работаете на одном сервере и т. д
-
-## Развёртывание образа контейнера
-
-После создания образа контейнера существует несколько способов его развёртывания.
+После того как у вас есть образ контейнера (Docker), его можно развёртывать несколькими способами.
Например:
-* С использованием **Docker Compose** при развёртывании на одном сервере
-* С использованием **Kubernetes** в кластере
-* С использованием режима Docker Swarm в кластере
-* С использованием других инструментов, таких как Nomad
-* С использованием облачного сервиса, который будет управлять разворачиванием вашего контейнера
-
-## Docker-образ и Poetry
-
-Если вы пользуетесь
Poetry для управления зависимостями вашего проекта, то можете использовать многоэтапную сборку образа:
-
-```{ .dockerfile .annotate }
-# (1)
-FROM python:3.9 as requirements-stage
-
-# (2)
-WORKDIR /tmp
-
-# (3)
-RUN pip install poetry
-
-# (4)
-COPY ./pyproject.toml ./poetry.lock* /tmp/
-
-# (5)
-RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
-
-# (6)
-FROM python:3.9
-
-# (7)
-WORKDIR /code
-
-# (8)
-COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt
-
-# (9)
-RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
-
-# (10)
-COPY ./app /code/app
-
-# (11)
-CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
-```
-
-1. Это первый этап, которому мы дадим имя `requirements-stage`.
-
-2. Установите директорию `/tmp` в качестве рабочей директории.
+* С **Docker Compose** на одном сервере
+* В кластере **Kubernetes**
+* В кластере Docker Swarm Mode
+* С другим инструментом, например Nomad
+* С облачным сервисом, который принимает ваш образ контейнера и разворачивает его
- В ней будет создан файл `requirements.txt`
-
-3. На этом шаге установите Poetry.
-
-4. Скопируйте файлы `pyproject.toml` и `poetry.lock` в директорию `/tmp`.
-
- Поскольку название файла написано как `./poetry.lock*` (с `*` в конце), то ничего не сломается, если такой файл не будет найден.
-
-5. Создайте файл `requirements.txt`.
-
-6. Это второй (и последний) этап сборки, который и создаст окончательный образ контейнера.
-
-7. Установите директорию `/code` в качестве рабочей.
-
-8. Скопируйте файл `requirements.txt` в директорию `/code`.
-
- Этот файл находится в образе, созданном на предыдущем этапе, которому мы дали имя requirements-stage, потому при копировании нужно написать `--from-requirements-stage`.
-
-9. Установите зависимости, указанные в файле `requirements.txt`.
-
-10. Скопируйте папку `app` в папку `/code`.
-
-11. Запустите `uvicorn`, указав ему использовать объект `app`, расположенный в `app.main`.
-
-/// tip | Подсказка
-
-Если ткнёте на кружок с плюсом, то увидите объяснения, что происходит в этой строке.
-
-///
-
-**Этапы сборки Docker-образа** являются частью `Dockerfile` и работают как **временные образы контейнеров**. Они нужны только для создания файлов, используемых в дальнейших этапах.
-
-Первый этап был нужен только для **установки Poetry** и **создания файла `requirements.txt`**, в которым прописаны зависимости вашего проекта, взятые из файла `pyproject.toml`.
-
-На **следующем этапе** `pip` будет использовать файл `requirements.txt`.
-
-В итоговом образе будет содержаться **только последний этап сборки**, предыдущие этапы будут отброшены.
-
-При использовании Poetry, имеет смысл использовать **многоэтапную сборку Docker-образа**, потому что на самом деле вам не нужен Poetry и его зависимости в окончательном образе контейнера, вам **нужен только** сгенерированный файл `requirements.txt` для установки зависимостей вашего проекта.
-
-А на последнем этапе, придерживаясь описанных ранее правил, создаётся итоговый образ
-
-### Использование прокси-сервера завершения TLS и Poetry
-
-И снова повторюсь, если используете прокси-сервер (балансировщик нагрузки), такой как Nginx или Traefik, добавьте в команду запуска опцию `--proxy-headers`:
-
-```Dockerfile
-CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
-```
+## Docker-образ с `uv` { #docker-image-with-uv }
-## Резюме
+Если вы используете
uv для установки и управления проектом, следуйте их
руководству по Docker для uv.
-При помощи систем контейнеризации (таких, как **Docker** и **Kubernetes**), становится довольно просто обрабатывать все **концепции развертывания**:
+## Резюме { #recap }
-* Использование более безопасного протокола HTTPS
-* Настройки запуска приложения
-* Перезагрузка приложения
-* Запуск нескольких экземпляров приложения
-* Управление памятью
-* Использование перечисленных функций перед запуском приложения
+Используя системы контейнеризации (например, **Docker** и **Kubernetes**), довольно просто закрыть все **концепции развертывания**:
-В большинстве случаев Вам, вероятно, не нужно использовать какой-либо базовый образ, **лучше создать образ контейнера с нуля** на основе официального Docker-образа Python.
+* HTTPS
+* Запуск при старте
+* Перезапуски
+* Репликация (количество запущенных процессов)
+* Память
+* Предварительные шаги перед запуском
-Позаботившись о **порядке написания** инструкций в `Dockerfile`, вы сможете использовать **кэш Docker'а**, **минимизировав время сборки**, максимально повысив свою производительность (и не заскучать). 😎
+В большинстве случаев вы, вероятно, не захотите использовать какой-либо базовый образ, а вместо этого **соберёте образ контейнера с нуля** на основе официального Docker-образа Python.
-В некоторых особых случаях вы можете использовать официальный образ Docker для FastAPI. 🤓
+Заботясь о **порядке** инструкций в `Dockerfile`и используя **кэш Docker**, вы можете **минимизировать время сборки**, чтобы повысить продуктивность (и не скучать). 😎
diff --git a/docs/ru/docs/deployment/https.md b/docs/ru/docs/deployment/https.md
index d8877a9a1..05a03255e 100644
--- a/docs/ru/docs/deployment/https.md
+++ b/docs/ru/docs/deployment/https.md
@@ -1,207 +1,231 @@
-# Об HTTPS
+# Об HTTPS { #about-https }
-Обычно представляется, что HTTPS это некая опция, которая либо "включена", либо нет.
+Легко предположить, что HTTPS — это что-то, что просто «включено» или нет.
-Но всё несколько сложнее.
+Но на самом деле всё гораздо сложнее.
-/// tip | Заметка
+/// tip | Совет
-Если вы торопитесь или вам не интересно, можете перейти на следующую страницу этого пошагового руководства по размещению приложений на серверах с использованием различных технологий.
+Если вы торопитесь или вам это не важно, переходите к следующим разделам с пошаговыми инструкциями по настройке всего разными способами.
///
-Чтобы **изучить основы HTTPS** для клиента, перейдите по ссылке
https://howhttps.works/.
-
-Здесь же представлены некоторые концепции, которые **разработчик** должен иметь в виду при размышлениях об HTTPS:
-
-* Протокол HTTPS предполагает, что **серверу** нужно **располагать "сертификатами"** сгенерированными **третьей стороной**.
- * На самом деле эти сертификаты **приобретены** у третьей стороны, а не "сгенерированы".
-* У сертификатов есть **срок годности**.
- * Срок годности **истекает**.
- * По истечении срока годности их нужно **обновить**, то есть **снова получить** у третьей стороны.
-* Шифрование соединения происходит **на уровне протокола TCP**.
- * Протокол TCP находится на один уровень **ниже протокола HTTP**.
- * Поэтому **проверка сертификатов и шифрование** происходит **до HTTP**.
-* **TCP не знает о "доменах"**, но знает об IP-адресах.
- * Информация о **запрашиваемом домене** извлекается из запроса **на уровне HTTP**.
-* **Сертификаты HTTPS** "сертифицируют" **конкретный домен**, но проверка сертификатов и шифрование данных происходит на уровне протокола TCP, то есть **до того**, как станет известен домен-получатель данных.
-* **По умолчанию** это означает, что у вас может быть **только один сертификат HTTPS на один IP-адрес**.
- * Не важно, насколько большой у вас сервер и насколько маленькие приложения на нём могут быть.
- * Однако, у этой проблемы есть **решение**.
-* Существует **расширение** протокола **TLS** (который работает на уровне TCP, то есть до HTTP) называемое **
SNI**.
- * Расширение SNI позволяет одному серверу (с **одним IP-адресом**) иметь **несколько сертификатов HTTPS** и обслуживать **множество HTTPS-доменов/приложений**.
- * Чтобы эта конструкция работала, **один** её компонент (программа) запущенный на сервере и слушающий **публичный IP-адрес**, должен иметь **все сертификаты HTTPS** для этого сервера.
-* **После** установления защищённого соединения, протоколом передачи данных **остаётся HTTP**.
- * Но данные теперь **зашифрованы**, несмотря на то, что они передаются по **протоколу HTTP**.
-
-Обычной практикой является иметь **одну программу/HTTP-сервер** запущенную на сервере (машине, хосте и т.д.) и **ответственную за всю работу с HTTPS**:
-
-* получение **зашифрованных HTTPS-запросов**
-* отправка **расшифрованных HTTP запросов** в соответствующее HTTP-приложение, работающее на том же сервере (в нашем случае, это приложение **FastAPI**)
-* получение **HTTP-ответа** от приложения
-* **шифрование ответа** используя подходящий **сертификат HTTPS**
-* отправка зашифрованного **HTTPS-ответа клиенту**.
-Такой сервер часто называют **
Прокси-сервер завершения работы TLS** или просто "прокси-сервер".
-
-Вот некоторые варианты, которые вы можете использовать в качестве такого прокси-сервера:
-
-* Traefik (может обновлять сертификаты)
-* Caddy (может обновлять сертификаты)
+Чтобы **изучить основы HTTPS** с точки зрения пользователя, загляните на
https://howhttps.works/.
+
+Теперь, со стороны **разработчика**, вот несколько вещей, которые стоит держать в голове, размышляя об HTTPS:
+
+* Для HTTPS **серверу** нужно **иметь «сертификаты»**, сгенерированные **третьей стороной**.
+ * Эти сертификаты на самом деле **приобретаются** у третьей стороны, а не «генерируются».
+* У сертификатов есть **срок действия**.
+ * Они **истекают**.
+ * После этого их нужно **обновлять**, то есть **получать заново** у третьей стороны.
+* Шифрование соединения происходит на **уровне TCP**.
+ * Это на один уровень **ниже HTTP**.
+ * Поэтому **сертификаты и шифрование** обрабатываются **до HTTP**.
+* **TCP не знает о «доменах»**. Только об IP-адресах.
+ * Информация о **конкретном домене** передаётся в **данных HTTP**.
+* **HTTPS-сертификаты** «сертифицируют» **определённый домен**, но протокол и шифрование происходят на уровне TCP, **до того как** становится известен домен, с которым идёт работа.
+* **По умолчанию** это означает, что вы можете иметь **лишь один HTTPS-сертификат на один IP-адрес**.
+ * Неважно, насколько мощный у вас сервер или насколько маленькие приложения на нём работают.
+ * Однако у этого есть **решение**.
+* Есть **расширение** протокола **TLS** (того самого, что занимается шифрованием на уровне TCP, до HTTP) под названием **
SNI**.
+ * Это расширение SNI позволяет одному серверу (с **одним IP-адресом**) иметь **несколько HTTPS-сертификатов** и обслуживать **несколько HTTPS-доменов/приложений**.
+ * Чтобы это работало, **один** компонент (программа), запущенный на сервере и слушающий **публичный IP-адрес**, должен иметь **все HTTPS-сертификаты** на этом сервере.
+* **После** установления защищённого соединения, протокол обмена данными — **всё ещё HTTP**.
+ * Содержимое **зашифровано**, несмотря на то, что оно отправляется по **протоколу HTTP**.
+
+Обычно на сервере (машине, хосте и т.п.) запускают **одну программу/HTTP‑сервер**, которая **управляет всей частью, связанной с HTTPS**: принимает **зашифрованные HTTPS-запросы**, отправляет **расшифрованные HTTP-запросы** в само HTTP‑приложение, работающее на том же сервере (в нашем случае это приложение **FastAPI**), получает **HTTP-ответ** от приложения, **шифрует его** с использованием подходящего **HTTPS‑сертификата** и отправляет клиенту по **HTTPS**. Такой сервер часто называют **
прокси‑сервером TLS-терминации**.
+
+Некоторые варианты, которые вы можете использовать как прокси‑сервер TLS-терминации:
+
+* Traefik (умеет обновлять сертификаты)
+* Caddy (умеет обновлять сертификаты)
* Nginx
* HAProxy
-## Let's Encrypt (центр сертификации)
+## Let's Encrypt { #lets-encrypt }
-До появления Let's Encrypt **сертификаты HTTPS** приходилось покупать у третьих сторон.
+До появления Let's Encrypt эти **HTTPS-сертификаты** продавались доверенными третьими сторонами.
-Процесс получения такого сертификата был трудоёмким, требовал предоставления подтверждающих документов и сертификаты стоили дорого.
+Процесс получения таких сертификатов был неудобным, требовал бумажной волокиты, а сами сертификаты были довольно дорогими.
-Но затем консорциумом Linux Foundation был создан проект **
Let's Encrypt**.
+Затем появился **
Let's Encrypt**.
-Он автоматически предоставляет **бесплатные сертификаты HTTPS**. Эти сертификаты используют все стандартные криптографические способы шифрования. Они имеют небольшой срок годности (около 3 месяцев), благодаря чему они даже **более безопасны**.
+Это проект Linux Foundation. Он предоставляет **HTTPS‑сертификаты бесплатно**, в автоматическом режиме. Эти сертификаты используют стандартные криптографические механизмы и имеют короткий срок действия (около 3 месяцев), поэтому **безопасность фактически выше** благодаря уменьшенному сроку жизни.
-При запросе на получение сертификата, он автоматически генерируется и домен проверяется на безопасность. Это позволяет обновлять сертификаты автоматически.
+Домены безопасно проверяются, а сертификаты выдаются автоматически. Это также позволяет автоматизировать процесс их продления.
-Суть идеи в автоматическом получении и обновлении этих сертификатов, чтобы все могли пользоваться **безопасным HTTPS. Бесплатно. В любое время.**
+Идея — автоматизировать получение и продление сертификатов, чтобы у вас был **безопасный HTTPS, бесплатно и навсегда**.
-## HTTPS для разработчиков
+## HTTPS для разработчиков { #https-for-developers }
-Ниже, шаг за шагом, с заострением внимания на идеях, важных для разработчика, описано, как может выглядеть HTTPS API.
+Ниже приведён пример того, как может выглядеть HTTPS‑API, шаг за шагом, с акцентом на идеях, важных для разработчиков.
-### Имя домена
+### Имя домена { #domain-name }
-Чаще всего, всё начинается с **приобретения имени домена**. Затем нужно настроить DNS-сервер (вероятно у того же провайдера, который выдал вам домен).
+Чаще всего всё начинается с **приобретения** **имени домена**. Затем вы настраиваете его на DNS‑сервере (возможно, у того же облачного провайдера).
-Далее, возможно, вы получаете "облачный" сервер (виртуальную машину) или что-то типа этого, у которого есть
постоянный **публичный IP-адрес**.
+Скорее всего, вы получите облачный сервер (виртуальную машину) или что-то подобное, и у него будет
постоянный **публичный IP-адрес**.
-На DNS-сервере (серверах) вам следует настроить соответствующую ресурсную запись ("`запись A`"), указав, что **Ваш домен** связан с публичным **IP-адресом вашего сервера**.
+На DNS‑сервере(ах) вы настроите запись («`A record`» - запись типа A), указывающую, что **ваш домен** должен указывать на публичный **IP‑адрес вашего сервера**.
-Обычно эту запись достаточно указать один раз, при первоначальной настройке всего сервера.
+Обычно это делается один раз — при первоначальной настройке всего.
-/// tip | Заметка
+/// tip | Совет
-Уровни протоколов, работающих с именами доменов, намного ниже HTTPS, но об этом следует упомянуть здесь, так как всё зависит от доменов и IP-адресов.
+Часть про доменное имя относится к этапам задолго до HTTPS, но так как всё зависит от домена и IP‑адреса, здесь стоит это упомянуть.
///
-### DNS
+### DNS { #dns }
-Теперь давайте сфокусируемся на работе с HTTPS.
+Теперь сфокусируемся на собственно частях, связанных с HTTPS.
-Всё начинается с того, что браузер спрашивает у **DNS-серверов**, какой **IP-адрес связан с доменом**, для примера возьмём домен `someapp.example.com`.
+Сначала браузер спросит у **DNS‑серверов**, какой **IP соответствует домену**, в нашем примере `someapp.example.com`.
-DNS-сервера присылают браузеру определённый **IP-адрес**, тот самый публичный IP-адрес вашего сервера, который вы указали в ресурсной "записи А" при настройке.
+DNS‑серверы ответят браузеру, какой **конкретный IP‑адрес** использовать. Это будет публичный IP‑адрес вашего сервера, который вы указали в настройках DNS.

-### Рукопожатие TLS
+### Начало TLS-рукопожатия { #tls-handshake-start }
-В дальнейшем браузер будет взаимодействовать с этим IP-адресом через **port 443** (общепринятый номер порта для HTTPS).
+Далее браузер будет общаться с этим IP‑адресом на **порту 443** (порт HTTPS).
-Первым шагом будет установление соединения между клиентом (браузером) и сервером и выбор криптографического ключа (для шифрования).
+Первая часть взаимодействия — установить соединение между клиентом и сервером и договориться о криптографических ключах и т.п.

-Эта часть клиент-серверного взаимодействия устанавливает TLS-соединение и называется **TLS-рукопожатием**.
+Это взаимодействие клиента и сервера для установления TLS‑соединения называется **TLS‑рукопожатием**.
-### TLS с расширением SNI
+### TLS с расширением SNI { #tls-with-sni-extension }
-На сервере **только один процесс** может прослушивать определённый **порт** определённого **IP-адреса**. На сервере могут быть и другие процессы, слушающие другие порты этого же IP-адреса, но никакой процесс не может быть привязан к уже занятой комбинации IP-адрес:порт. Эта комбинация называется "сокет".
+На сервере **только один процесс** может слушать конкретный **порт** на конкретном **IP‑адресе**. Могут быть другие процессы, слушающие другие порты на том же IP‑адресе, но не более одного процесса на каждую комбинацию IP‑адреса и порта.
-По умолчанию TLS (HTTPS) использует порт `443`. Потому этот же порт будем использовать и мы.
+По умолчанию TLS (HTTPS) использует порт `443`. Значит, он нам и нужен.
-И раз уж только один процесс может слушать этот порт, то это будет процесс **прокси-сервера завершения работы TLS**.
+Так как только один процесс может слушать этот порт, делать это будет **прокси‑сервер TLS-терминации**.
-Прокси-сервер завершения работы TLS будет иметь доступ к одному или нескольким **TLS-сертификатам** (сертификаты HTTPS).
+У прокси‑сервера TLS-терминации будет доступ к одному или нескольким **TLS‑сертификатам** (HTTPS‑сертификатам).
-Используя **расширение SNI** упомянутое выше, прокси-сервер из имеющихся сертификатов TLS (HTTPS) выберет тот, который соответствует имени домена, указанному в запросе от клиента.
+Используя **расширение SNI**, упомянутое выше, прокси‑сервер TLS-терминации определит, какой из доступных TLS (HTTPS)‑сертификатов нужно использовать для этого соединения, выбрав тот, который соответствует домену, ожидаемому клиентом.
-То есть будет выбран сертификат для домена `someapp.example.com`.
+В нашем случае это будет сертификат для `someapp.example.com`.

-Клиент уже **доверяет** тому, кто выдал этот TLS-сертификат (в нашем случае - Let's Encrypt, но мы ещё обсудим это), потому может **проверить**, действителен ли полученный от сервера сертификат.
+Клиент уже **доверяет** организации, выдавшей этот TLS‑сертификат (в нашем случае — Let's Encrypt, но об этом позже), поэтому может **проверить**, что сертификат действителен.
-Затем, используя этот сертификат, клиент и прокси-сервер **выбирают способ шифрования** данных для устанавливаемого **TCP-соединения**. На этом операция **TLS-рукопожатия** завершена.
+Затем, используя сертификат, клиент и прокси‑сервер TLS-терминации **договариваются о способе шифрования** остальной **TCP‑коммуникации**. На этом **TLS‑рукопожатие** завершено.
-В дальнейшем клиент и сервер будут взаимодействовать по **зашифрованному TCP-соединению**, как предлагается в протоколе TLS. И на основе этого TCP-соедениния будет создано **HTTP-соединение**.
+После этого у клиента и сервера есть **зашифрованное TCP‑соединение** — это и предоставляет TLS. И они могут использовать это соединение, чтобы начать собственно **HTTP‑обмен**.
-Таким образом, **HTTPS** это тот же **HTTP**, но внутри **безопасного TLS-соединения** вместо чистого (незашифрованного) TCP-соединения.
+Собственно, **HTTPS** — это обычный **HTTP** внутри **защищённого TLS‑соединения**, вместо чистого (незашифрованного) TCP‑соединения.
-/// tip | Заметка
+/// tip | Совет
-Обратите внимание, что шифрование происходит на **уровне TCP**, а не на более высоком уровне HTTP.
+Обратите внимание, что шифрование обмена происходит на **уровне TCP**, а не на уровне HTTP.
///
-### HTTPS-запрос
+### HTTPS‑запрос { #https-request }
-Теперь, когда между клиентом и сервером (в нашем случае, браузером и прокси-сервером) создано **зашифрованное TCP-соединение**, они могут начать **обмен данными по протоколу HTTP**.
+Теперь, когда у клиента и сервера (конкретно у браузера и прокси‑сервера TLS-терминации) есть **зашифрованное TCP‑соединение**, они могут начать **HTTP‑обмен**.
-Так клиент отправляет **HTTPS-запрос**. То есть обычный HTTP-запрос, но через зашифрованное TLS-содинение.
+Клиент отправляет **HTTPS‑запрос**. Это обычный HTTP‑запрос через зашифрованное TLS‑соединение.

-### Расшифровка запроса
+### Расшифровка запроса { #decrypt-the-request }
-Прокси-сервер, используя согласованный с клиентом ключ, расшифрует полученный **зашифрованный запрос** и передаст **обычный (незашифрованный) HTTP-запрос** процессу, запускающему приложение (например, процессу Uvicorn запускающему приложение FastAPI).
+Прокси‑сервер TLS-терминации использует согласованное шифрование, чтобы **расшифровать запрос**, и передаёт **обычный (расшифрованный) HTTP‑запрос** процессу, запускающему приложение (например, процессу с Uvicorn, который запускает приложение FastAPI).

-### HTTP-ответ
+### HTTP‑ответ { #http-response }
-Приложение обработает запрос и вернёт **обычный (незашифрованный) HTTP-ответ** прокси-серверу.
+Приложение обработает запрос и отправит **обычный (незашифрованный) HTTP‑ответ** прокси‑серверу TLS-терминации.

-### HTTPS-ответ
+### HTTPS‑ответ { #https-response }
-Пркоси-сервер **зашифрует ответ** используя ранее согласованный с клиентом способ шифрования (которые содержатся в сертификате для домена `someapp.example.com`) и отправит его браузеру.
+Затем прокси‑сервер TLS-терминации **зашифрует ответ** с использованием ранее согласованного способа шифрования (который начали использовать для сертификата для `someapp.example.com`) и отправит его обратно в браузер.
-Наконец, браузер проверит ответ, в том числе, что тот зашифрован с нужным ключом, **расшифрует его** и обработает.
+Далее браузер проверит, что ответ корректен и зашифрован правильным криптографическим ключом и т.п., затем **расшифрует ответ** и обработает его.

-Клиент (браузер) знает, что ответ пришёл от правильного сервера, так как использует методы шифрования, согласованные ими раннее через **HTTPS-сертификат**.
+Клиент (браузер) узнает, что ответ пришёл от правильного сервера, потому что используется способ шифрования, о котором они договорились ранее с помощью **HTTPS‑сертификата**.
-### Множество приложений
+### Несколько приложений { #multiple-applications }
-На одном и том же сервере (или серверах) можно разместить **множество приложений**, например, другие программы с API или базы данных.
+На одном и том же сервере (или серверах) могут работать **несколько приложений**, например другие программы с API или база данных.
-Напомню, что только один процесс (например, прокси-сервер) может прослушивать определённый порт определённого IP-адреса.
-Но другие процессы и приложения тоже могут работать на этом же сервере (серверах), если они не пытаются использовать уже занятую **комбинацию IP-адреса и порта** (сокет).
+Только один процесс может обрабатывать конкретную комбинацию IP и порта (в нашем примере — прокси‑сервер TLS-терминации), но остальные приложения/процессы тоже могут работать на сервере(ах), пока они не пытаются использовать ту же **комбинацию публичного IP и порта**.

-Таким образом, сервер завершения TLS может обрабатывать HTTPS-запросы и использовать сертификаты для **множества доменов** или приложений и передавать запросы правильным адресатам (другим приложениям).
+Таким образом, прокси‑сервер TLS-терминации может обрабатывать HTTPS и сертификаты для **нескольких доменов** (для нескольких приложений), а затем передавать запросы нужному приложению в каждом случае.
-### Обновление сертификата
+### Продление сертификата { #certificate-renewal }
-В недалёком будущем любой сертификат станет **просроченным** (примерно через три месяца после получения).
+Со временем каждый сертификат **истечёт** (примерно через 3 месяца после получения).
-Когда это произойдёт, можно запустить другую программу, которая подключится к Let's Encrypt и обновит сертификат(ы). Существуют прокси-серверы, которые могут сделать это действие самостоятельно.
+Затем будет другая программа (иногда это отдельная программа, иногда — тот же прокси‑сервер TLS-терминации), которая свяжется с Let's Encrypt и продлит сертификат(ы).

-**TLS-сертификаты** не привязаны к IP-адресу, но **связаны с именем домена**.
+**TLS‑сертификаты** **связаны с именем домена**, а не с IP‑адресом.
-Так что при обновлении сертификатов программа должна **подтвердить** центру сертификации (Let's Encrypt), что обновление запросил **"владелец", который контролирует этот домен**.
+Поэтому, чтобы продлить сертификаты, программа продления должна **доказать** удостоверяющему центру (Let's Encrypt), что она действительно **«владеет» и контролирует этот домен**.
-Есть несколько путей осуществления этого. Самые популярные из них:
+Для этого, учитывая разные потребности приложений, есть несколько способов. Популярные из них:
-* **Изменение записей DNS**.
- * Для такого варианта Ваша программа обновления должна уметь работать с API DNS-провайдера, обслуживающего Ваши DNS-записи. Не у всех провайдеров есть такой API, так что этот способ не всегда применим.
-* **Запуск в качестве программы-сервера** (как минимум, на время обновления сертификатов) на публичном IP-адресе домена.
- * Как уже не раз упоминалось, только один процесс может прослушивать определённый порт определённого IP-адреса.
- * Это одна из причин использования прокси-сервера ещё и в качестве программы обновления сертификатов.
- * В случае, если обновлением сертификатов занимается другая программа, вам понадобится остановить прокси-сервер, запустить программу обновления сертификатов на сокете, предназначенном для прокси-сервера, настроить прокси-сервер на работу с новыми сертификатами и перезапустить его. Эта схема далека от идеальной, так как Ваши приложения будут недоступны на время отключения прокси-сервера.
+* **Изменить некоторые DNS‑записи**.
+ * Для этого программа продления должна поддерживать API DNS‑провайдера, поэтому, в зависимости от используемого провайдера DNS, этот вариант может быть доступен или нет.
+* **Запуститься как сервер** (как минимум на время получения сертификатов) на публичном IP‑адресе, связанном с доменом.
+ * Как сказано выше, только один процесс может слушать конкретный IP и порт.
+ * Это одна из причин, почему очень удобно, когда тот же прокси‑сервер TLS-терминации также занимается процессом продления сертификатов.
+ * В противном случае вам, возможно, придётся временно остановить прокси‑сервер TLS-терминации, запустить программу продления для получения сертификатов, затем настроить их в прокси‑сервере TLS-терминации и перезапустить его. Это не идеально, так как ваше приложение(я) будут недоступны, пока прокси‑сервер TLS-терминации остановлен.
-Весь этот процесс обновления, одновременный с обслуживанием запросов, является одной из основных причин, по которой желательно иметь **отдельную систему для работы с HTTPS** в виде прокси-сервера завершения TLS, а не просто использовать сертификаты TLS непосредственно с сервером приложений (например, Uvicorn).
+Весь этот процесс продления, совмещённый с обслуживанием приложения, — одна из главных причин иметь **отдельную систему для работы с HTTPS** в виде прокси‑сервера TLS-терминации, вместо использования TLS‑сертификатов напрямую в сервере приложения (например, Uvicorn).
-## Резюме
+## Пересылаемые HTTP-заголовки прокси { #proxy-forwarded-headers }
-Наличие **HTTPS** очень важно и довольно **критично** в большинстве случаев. Однако, Вам, как разработчику, не нужно тратить много сил на это, достаточно **понимать эти концепции** и принципы их работы.
+Когда вы используете прокси для обработки HTTPS, ваш **сервер приложения** (например, Uvicorn через FastAPI CLI) ничего не знает о процессе HTTPS, он общается обычным HTTP с **прокси‑сервером TLS-терминации**.
-Но узнав базовые основы **HTTPS** вы можете легко совмещать разные инструменты, которые помогут вам в дальнейшей разработке.
+Обычно этот **прокси** на лету добавляет некоторые HTTP‑заголовки перед тем, как переслать запрос на **сервер приложения**, чтобы тот знал, что запрос был **проксирован**.
-В следующих главах я покажу вам несколько примеров, как настраивать **HTTPS** для приложений **FastAPI**. 🔒
+/// note | Технические детали
+
+Заголовки прокси:
+
+*
X-Forwarded-For
+*
X-Forwarded-Proto
+*
X-Forwarded-Host
+
+///
+
+Тем не менее, так как **сервер приложения** не знает, что он находится за доверенным **прокси**, по умолчанию он не будет доверять этим заголовкам.
+
+Но вы можете настроить **сервер приложения**, чтобы он доверял *пересылаемым* заголовкам, отправленным **прокси**. Если вы используете FastAPI CLI, вы можете использовать *опцию CLI* `--forwarded-allow-ips`, чтобы указать, с каких IP‑адресов следует доверять этим *пересылаемым* заголовкам.
+
+Например, если **сервер приложения** получает запросы только от доверенного **прокси**, вы можете установить `--forwarded-allow-ips="*"`, чтобы доверять всем входящим IP, так как он всё равно будет получать запросы только с IP‑адреса, используемого **прокси**.
+
+Таким образом, приложение сможет знать свой публичный URL, использует ли оно HTTPS, какой домен и т.п.
+
+Это будет полезно, например, для корректной обработки редиректов.
+
+/// tip | Совет
+
+Подробнее об этом вы можете узнать в документации: [За прокси — Включить пересылаемые заголовки прокси](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank}
+
+///
+
+## Резюме { #recap }
+
+Наличие **HTTPS** очень важно и во многих случаях довольно **критично**. Большая часть усилий, которые вам, как разработчику, нужно приложить вокруг HTTPS, — это просто **понимание этих концепций** и того, как они работают.
+
+Зная базовую информацию о **HTTPS для разработчиков**, вы сможете легко комбинировать и настраивать разные инструменты, чтобы управлять всем этим простым способом.
+
+В некоторых из следующих глав я покажу вам несколько конкретных примеров настройки **HTTPS** для приложений **FastAPI**. 🔒
diff --git a/docs/ru/docs/deployment/index.md b/docs/ru/docs/deployment/index.md
index e88ddc3e2..c85fa0d52 100644
--- a/docs/ru/docs/deployment/index.md
+++ b/docs/ru/docs/deployment/index.md
@@ -1,16 +1,16 @@
-# Развёртывание
+# Развёртывание { #deployment }
Развернуть приложение **FastAPI** довольно просто.
-## Да что такое это ваше - "развёртывание"?!
+## Что означает развёртывание { #what-does-deployment-mean }
Термин **развёртывание** (приложения) означает выполнение необходимых шагов, чтобы сделать приложение **доступным для пользователей**.
-Обычно **веб-приложения** размещают на удалённом компьютере с серверной программой, которая обеспечивает хорошую производительность, стабильность и т. д., Чтобы ваши пользователи могли эффективно, беспрерывно и беспроблемно обращаться к приложению.
+Для **веб-API** это обычно означает размещение его на **удалённой машине** с **серверной программой**, обеспечивающей хорошую производительность, стабильность и т.д., чтобы ваши **пользователи** могли **получать доступ** к приложению эффективно и без перебоев или проблем.
-Это отличается от **разработки**, когда вы постоянно меняете код, делаете в нём намеренные ошибки и исправляете их, останавливаете и перезапускаете сервер разработки и т. д.
+Это отличается от этапов **разработки**, когда вы постоянно меняете код, ломаете его и исправляете, останавливаете и перезапускаете сервер разработки и т.д.
-## Стратегии развёртывания
+## Стратегии развёртывания { #deployment-strategies }
В зависимости от вашего конкретного случая, есть несколько способов сделать это.
diff --git a/docs/ru/docs/deployment/manually.md b/docs/ru/docs/deployment/manually.md
index 9b1d32be8..37fed5780 100644
--- a/docs/ru/docs/deployment/manually.md
+++ b/docs/ru/docs/deployment/manually.md
@@ -1,163 +1,157 @@
-# Запуск сервера вручную - Uvicorn
+# Запуск сервера вручную { #run-a-server-manually }
-Для запуска приложения **FastAPI** на удалённой серверной машине вам необходим программный сервер, поддерживающий протокол ASGI, такой как **Uvicorn**.
+## Используйте команду `fastapi run` { #use-the-fastapi-run-command }
-Существует три наиболее распространённые альтернативы:
+Коротко: используйте `fastapi run`, чтобы запустить ваше приложение FastAPI:
-*
Uvicorn: высокопроизводительный ASGI сервер.
-*
Hypercorn: ASGI сервер, помимо прочего поддерживающий HTTP/2 и Trio.
-*
Daphne: ASGI сервер, созданный для Django Channels.
-
-## Сервер как машина и сервер как программа
-
-В этих терминах есть некоторые различия и вам следует запомнить их. 💡
-
-Слово "**сервер**" чаще всего используется в двух контекстах:
+
-- удалённый или расположенный в "облаке" компьютер (физическая или виртуальная машина).
-- программа, запущенная на таком компьютере (например, Uvicorn).
+```console
+$
fastapi run
main.py
-Просто запомните, если вам встретился термин "сервер", то обычно он подразумевает что-то из этих двух смыслов.
+
FastAPI Starting production server 🚀
-Когда имеют в виду именно удалённый компьютер, часто говорят просто **сервер**, но ещё его называют **машина**, **ВМ** (виртуальная машина), **нода**. Все эти термины обозначают одно и то же - удалённый компьютер, обычно под управлением Linux, на котором вы запускаете программы.
+ Searching for package file structure from directories
+ with
__init__.py files
+ Importing from
/home/user/code/awesomeapp
-## Установка программного сервера
+
module 🐍 main.py
-Вы можете установить сервер, совместимый с протоколом ASGI, так:
+
code Importing the FastAPI app object from the module with
+ the following code:
-//// tab | Uvicorn
+
from main import app
-*
Uvicorn, очень быстрый ASGI сервер, основанный на библиотеках uvloop и httptools.
+
app Using import string:
main:app
-
+ server Server started at http://0.0.0.0:8000
+ server Documentation at http://0.0.0.0:8000/docs
-```console
-$ pip install "uvicorn[standard]"
+ Logs:
----> 100%
+ INFO Started server process [2306215]
+ INFO Waiting for application startup.
+ INFO Application startup complete.
+ INFO Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C
+ to quit)
```
-/// tip | Подсказка
-
-С опцией `standard`, Uvicorn будет устанавливаться и использоваться с некоторыми дополнительными рекомендованными зависимостями.
-
-В них входит `uvloop`, высокопроизводительная замена `asyncio`, которая значительно ускоряет работу асинхронных программ.
-
-///
-
-////
+В большинстве случаев этого достаточно. 😎
-//// tab | Hypercorn
+Этой командой, например, можно запускать приложение **FastAPI** в контейнере, на сервере и т.д.
-*
Hypercorn, ASGI сервер, поддерживающий протокол HTTP/2.
+## ASGI‑серверы { #asgi-servers }
-
+Давайте немного углубимся в детали.
-```console
-$ pip install hypercorn
+FastAPI использует стандарт для построения Python‑веб‑фреймворков и серверов под названием
ASGI. FastAPI — ASGI-веб‑фреймворк.
----> 100%
-```
+Главное, что вам нужно, чтобы запустить приложение **FastAPI** (или любое другое ASGI‑приложение) на удалённой серверной машине, — это программа ASGI‑сервера, такая как **Uvicorn**; именно он используется по умолчанию в команде `fastapi`.
-
+Есть несколько альтернатив, например:
-...или какой-либо другой ASGI сервер.
+*
Uvicorn: высокопроизводительный ASGI‑сервер.
+*
Hypercorn: ASGI‑сервер, среди прочего совместимый с HTTP/2 и Trio.
+*
Daphne: ASGI‑сервер, созданный для Django Channels.
+*
Granian: HTTP‑сервер на Rust для Python‑приложений.
+*
NGINX Unit: NGINX Unit — лёгкая и многофункциональная среда выполнения веб‑приложений.
-////
+## Сервер как машина и сервер как программа { #server-machine-and-server-program }
-## Запуск серверной программы
+Есть небольшой нюанс в терминологии, о котором стоит помнить. 💡
-Затем запустите ваше приложение так же, как было указано в руководстве ранее, но без опции `--reload`:
+Слово «сервер» обычно используют и для обозначения удалённого/облачного компьютера (физической или виртуальной машины), и для программы, работающей на этой машине (например, Uvicorn).
-//// tab | Uvicorn
+Имейте в виду, что слово «сервер» в целом может означать любое из этих двух.
-
+Когда речь идёт об удалённой машине, её зачастую называют **сервер**, а также **машина**, **VM** (виртуальная машина), **нода**. Всё это — варианты названия удалённой машины, обычно под управлением Linux, на которой вы запускаете программы.
-```console
-$ uvicorn main:app --host 0.0.0.0 --port 80
+## Установка серверной программы { #install-the-server-program }
-INFO: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
-```
+При установке FastAPI он поставляется с продакшн‑сервером Uvicorn, и вы можете запустить его командой `fastapi run`.
-
+Но вы также можете установить ASGI‑сервер вручную.
-////
+Создайте [виртуальное окружение](../virtual-environments.md){.internal-link target=_blank}, активируйте его и затем установите серверное приложение.
-//// tab | Hypercorn
+Например, чтобы установить Uvicorn:
```console
-$ hypercorn main:app --bind 0.0.0.0:80
+$ pip install "uvicorn[standard]"
-Running on 0.0.0.0:8080 over http (CTRL + C to quit)
+---> 100%
```
-////
+Аналогично устанавливаются и другие ASGI‑серверы.
-/// warning | Предупреждение
+/// tip | Совет
-Не забудьте удалить опцию `--reload`, если ранее пользовались ею.
+С добавлением `standard` Uvicorn установит и будет использовать ряд рекомендованных дополнительных зависимостей.
-Включение опции `--reload` требует дополнительных ресурсов, влияет на стабильность работы приложения и может повлечь прочие неприятности.
+В их числе `uvloop` — высокопроизводительная замена `asyncio`, дающая серьёзный прирост производительности при параллельной работе.
-Она сильно помогает во время **разработки**, но **не следует** использовать её при **реальной работе** приложения.
+Если вы устанавливаете FastAPI, например так: `pip install "fastapi[standard]"`, вы уже получаете и `uvicorn[standard]`.
///
-## Hypercorn с Trio
-
-Starlette и **FastAPI** основаны на
AnyIO, которая делает их совместимыми как с
asyncio - стандартной библиотекой Python, так и с
Trio.
-
+## Запуск серверной программы { #run-the-server-program }
-Тем не менее Uvicorn совместим только с asyncio и обычно используется совместно с
`uvloop`, высокопроизводительной заменой `asyncio`.
-
-Но если вы хотите использовать **Trio** напрямую, то можете воспользоваться **Hypercorn**, так как они совместимы. ✨
-
-### Установка Hypercorn с Trio
-
-Для начала, вам нужно установить Hypercorn с поддержкой Trio:
+Если вы установили ASGI‑сервер вручную, обычно нужно передать строку импорта в специальном формате, чтобы он смог импортировать ваше приложение FastAPI:
```console
-$ pip install "hypercorn[trio]"
----> 100%
+$ uvicorn main:app --host 0.0.0.0 --port 80
+
+INFO: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
```
-### Запуск с Trio
+/// note | Примечание
-Далее запустите Hypercorn с опцией `--worker-class` и аргументом `trio`:
+Команда `uvicorn main:app` означает:
-
+* `main`: файл `main.py` (Python‑«модуль»).
+* `app`: объект, созданный в `main.py` строкой `app = FastAPI()`.
-```console
-$ hypercorn main:app --worker-class trio
+Эквивалентно:
+
+```Python
+from main import app
```
-
+///
-Hypercorn, в свою очередь, запустит ваше приложение использующее Trio.
+У каждого альтернативного ASGI‑сервера будет похожая команда; подробнее см. в их документации.
-Таким образом, вы сможете использовать Trio в своём приложении. Но лучше использовать AnyIO, для сохранения совместимости и с Trio, и с asyncio. 🎉
+/// warning | Предупреждение
+
+Uvicorn и другие серверы поддерживают опцию `--reload`, полезную в период разработки.
+
+Опция `--reload` потребляет значительно больше ресурсов, менее стабильна и т.п.
+
+Она сильно помогает во время **разработки**, но в **продакшн** её использовать **не следует**.
+
+///
-## Концепции развёртывания
+## Концепции развёртывания { #deployment-concepts }
-В вышеприведённых примерах серверные программы (например Uvicorn) запускали только **один процесс**, принимающий входящие запросы с любого IP (на это указывал аргумент `0.0.0.0`) на определённый порт (в примерах мы указывали порт `80`).
+В этих примерах серверная программа (например, Uvicorn) запускает **один процесс**, слушающий все IP‑адреса (`0.0.0.0`) на заранее заданном порту (например, `80`).
-Это основная идея. Но возможно, вы озаботитесь добавлением дополнительных возможностей, таких как:
+Это базовая идея. Но, вероятно, вам понадобится позаботиться и о некоторых дополнительных вещах, например:
-* Использование более безопасного протокола HTTPS
-* Настройки запуска приложения
-* Перезагрузка приложения
-* Запуск нескольких экземпляров приложения
-* Управление памятью
-* Использование перечисленных функций перед запуском приложения.
+* Безопасность — HTTPS
+* Запуск при старте системы
+* Перезапуски
+* Репликация (количество запущенных процессов)
+* Память
+* Предварительные шаги перед запуском
-Я расскажу вам больше о каждой из этих концепций в следующих главах, с конкретными примерами стратегий работы с ними. 🚀
+В следующих главах я расскажу подробнее про каждую из этих концепций, о том, как о них думать, и приведу конкретные примеры со стратегиями, как с ними работать. 🚀
diff --git a/docs/ru/docs/deployment/versions.md b/docs/ru/docs/deployment/versions.md
index e8db30ce8..58d5aa110 100644
--- a/docs/ru/docs/deployment/versions.md
+++ b/docs/ru/docs/deployment/versions.md
@@ -1,42 +1,42 @@
-# О версиях FastAPI
+# О версиях FastAPI { #about-fastapi-versions }
-**FastAPI** уже используется в продакшене во многих приложениях и системах. Покрытие тестами поддерживается на уровне 100%. Однако его разработка все еще продолжается.
+**FastAPI** уже используется в продакшене во многих приложениях и системах. Покрытие тестами поддерживается на уровне 100%. Но его разработка всё ещё движется быстрыми темпами.
Часто добавляются новые функции, регулярно исправляются баги, код продолжает постоянно совершенствоваться.
-По указанным причинам текущие версии до сих пор `0.x.x`. Это говорит о том, что каждая версия может содержать обратно несовместимые изменения, следуя
соглашению о Семантическом Версионировании.
+По указанным причинам текущие версии до сих пор `0.x.x`. Это говорит о том, что каждая версия может содержать обратно несовместимые изменения, следуя
Семантическому версионированию.
-Уже сейчас вы можете создавать приложения в продакшене, используя **FastAPI** (и скорее всего так и делаете), главное убедиться в том, что вы используете версию, которая корректно работает с вашим кодом.
+Уже сейчас вы можете создавать приложения в продакшене, используя **FastAPI** (и скорее всего так и делаете), главное убедиться в том, что вы используете версию, которая корректно работает с вашим кодом.
-## Закрепите вашу версию `fastapi`
+## Закрепите вашу версию `fastapi` { #pin-your-fastapi-version }
Первым делом вам следует "закрепить" конкретную последнюю используемую версию **FastAPI**, которая корректно работает с вашим приложением.
-Например, в своём приложении вы используете версию `0.45.0`.
+Например, в своём приложении вы используете версию `0.112.0`.
Если вы используете файл `requirements.txt`, вы можете указать версию следующим способом:
```txt
-fastapi==0.45.0
+fastapi[standard]==0.112.0
```
-это означает, что вы будете использовать именно версию `0.45.0`.
+это означает, что вы будете использовать именно версию `0.112.0`.
Или вы можете закрепить версию следующим способом:
```txt
-fastapi>=0.45.0,<0.46.0
+fastapi[standard]>=0.112.0,<0.113.0
```
-это значит, что вы используете версии `0.45.0` или выше, но меньше чем `0.46.0`. Например, версия `0.45.2` все еще будет подходить.
+это значит, что вы используете версии `0.112.0` или выше, но меньше чем `0.113.0`. Например, версия `0.112.2` всё ещё будет подходить.
-Если вы используете любой другой инструмент для управления зависимостями, например Poetry, Pipenv или др., у них у всех имеется способ определения специфической версии для ваших пакетов.
+Если вы используете любой другой инструмент для управления установками/зависимостями, например `uv`, Poetry, Pipenv или др., у них у всех имеется способ определения специфической версии для ваших пакетов.
-## Доступные версии
+## Доступные версии { #available-versions }
-Вы можете посмотреть доступные версии (например, проверить последнюю на данный момент) в [примечаниях к выпуску](../release-notes.md){.internal-link target=_blank}.
+Вы можете посмотреть доступные версии (например, проверить последнюю на данный момент) в [Примечаниях к выпуску](../release-notes.md){.internal-link target=_blank}.
-## О версиях
+## О версиях { #about-versions }
Следуя соглашению о Семантическом Версионировании, любые версии ниже `1.0.0` потенциально могут добавить обратно несовместимые изменения.
@@ -44,7 +44,7 @@ FastAPI следует соглашению в том, что любые изм
/// tip | Подсказка
-"ПАТЧ" - это последнее число. Например, в `0.2.3`, ПАТЧ-версия - это `3`.
+"ПАТЧ" — это последнее число. Например, в `0.2.3`, ПАТЧ-версия — это `3`.
///
@@ -58,11 +58,11 @@ fastapi>=0.45.0,<0.46.0
/// tip | Подсказка
-"МИНОРНАЯ" версия - это число в середине. Например, в `0.2.3` МИНОРНАЯ версия - это `2`.
+"МИНОРНАЯ" версия — это число в середине. Например, в `0.2.3` МИНОРНАЯ версия — это `2`.
///
-## Обновление версий FastAPI
+## Обновление версий FastAPI { #upgrading-the-fastapi-versions }
Вам следует добавить тесты для вашего приложения.
@@ -70,9 +70,9 @@ fastapi>=0.45.0,<0.46.0
После создания тестов вы можете обновить свою версию **FastAPI** до более новой. После этого следует убедиться, что ваш код работает корректно, запустив тесты.
-Если все работает корректно, или после внесения необходимых изменений все ваши тесты проходят, только тогда вы можете закрепить вашу новую версию `fastapi`.
+Если всё работает корректно, или после внесения необходимых изменений все ваши тесты проходят, только тогда вы можете закрепить вашу новую версию `fastapi`.
-## О Starlette
+## О Starlette { #about-starlette }
Не следует закреплять версию `starlette`.
@@ -80,14 +80,14 @@ fastapi>=0.45.0,<0.46.0
Так что решение об используемой версии Starlette, вы можете оставить **FastAPI**.
-## О Pydantic
+## О Pydantic { #about-pydantic }
Pydantic включает свои собственные тесты для **FastAPI**, так что новые версии Pydantic (выше `1.0.0`) всегда совместимы с FastAPI.
-Вы можете закрепить любую версию Pydantic, которая вам подходит, выше `1.0.0` и ниже `2.0.0`.
+Вы можете закрепить любую версию Pydantic, которая вам подходит, выше `1.0.0`.
Например:
```txt
-pydantic>=1.2.0,<2.0.0
+pydantic>=2.7.0,<3.0.0
```
diff --git a/docs/ru/docs/environment-variables.md b/docs/ru/docs/environment-variables.md
index a6c7b0c77..6291b79d2 100644
--- a/docs/ru/docs/environment-variables.md
+++ b/docs/ru/docs/environment-variables.md
@@ -1,6 +1,6 @@
-# Переменные окружения
+# Переменные окружения { #environment-variables }
-/// tip
+/// tip | Совет
Если вы уже знаете, что такое «переменные окружения» и как их использовать, можете пропустить это.
@@ -10,7 +10,7 @@
Переменные окружения могут быть полезны для работы с **настройками** приложений, как часть **установки** Python и т.д.
-## Создание и использование переменных окружения
+## Создание и использование переменных окружения { #create-and-use-env-vars }
Можно **создавать** и использовать переменные окружения в **оболочке (терминале)**, не прибегая к помощи Python:
@@ -50,7 +50,7 @@ Hello Wade Wilson
////
-## Чтение переменных окружения в python
+## Чтение переменных окружения в python { #read-env-vars-in-python }
Так же существует возможность создания переменных окружения **вне** Python, в терминале (или любым другим способом), а затем **чтения их в Python**.
@@ -63,11 +63,12 @@ name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
-/// tip
+/// tip | Совет
-Второй аргумент
`os.getenv()` - это возвращаемое по умолчанию значение.
+Второй аргумент
`os.getenv()` - это возвращаемое по умолчанию значение.
Если значение не указано, то по умолчанию оно равно `None`. В данном случае мы указываем `«World»` в качестве значения по умолчанию.
+
///
Затем можно запустить эту программу на Python:
@@ -150,13 +151,13 @@ Hello World from Python
-/// tip
+/// tip | Совет
Подробнее об этом можно прочитать на сайте
The Twelve-Factor App: Config.
///
-## Типизация и Валидация
+## Типизация и Валидация { #types-and-validation }
Эти переменные окружения могут работать только с **текстовыми строками**, поскольку они являются внешними по отношению к Python и должны быть совместимы с другими программами и остальной системой (и даже с различными операционными системами, такими как Linux, Windows, macOS).
@@ -164,7 +165,7 @@ Hello World from Python
Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md){.internal-link target=_blank}.
-## Переменная окружения `PATH`
+## Переменная окружения `PATH` { #path-environment-variable }
Существует **специальная** переменная окружения **`PATH`**, которая используется операционными системами (Linux, macOS, Windows) для поиска программ для запуска.
@@ -208,7 +209,7 @@ C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System3
Если она ее находит, то **использует ее**. В противном случае она продолжает искать в **других каталогах**.
-### Установка Python и обновление `PATH`
+### Установка Python и обновление `PATH` { #installing-python-and-updating-the-path }
При установке Python вас могут спросить, нужно ли обновить переменную окружения `PATH`.
@@ -286,7 +287,7 @@ $ C:\opt\custompython\bin\python
Эта информация будет полезна при изучении [Виртуальных окружений](virtual-environments.md){.internal-link target=_blank}.
-## Вывод
+## Вывод { #conclusion }
Благодаря этому вы должны иметь базовое представление о том, что такое **переменные окружения** и как использовать их в Python.
diff --git a/docs/ru/docs/fastapi-cli.md b/docs/ru/docs/fastapi-cli.md
index c0be4a5df..156e3d200 100644
--- a/docs/ru/docs/fastapi-cli.md
+++ b/docs/ru/docs/fastapi-cli.md
@@ -1,4 +1,4 @@
-# FastAPI CLI
+# FastAPI CLI { #fastapi-cli }
**FastAPI CLI** это программа командной строки, которую вы можете использовать для запуска вашего FastAPI приложения, для управления FastAPI-проектом, а также для многих других вещей.
@@ -50,26 +50,26 @@ $
fastapi dev
Uvicorn, высокопроизводительный, готовый к работе в production сервер ASGI. 😎
+Внутри **FastAPI CLI** используется Uvicorn, высокопроизводительный, готовый к работе в продакшне ASGI-сервер. 😎
-## `fastapi dev`
+## `fastapi dev` { #fastapi-dev }
Вызов `fastapi dev` запускает режим разработки.
-По умолчанию включена автоматическая перезагрузка (**auto-reload**), благодаря этому при изменении кода происходит перезагрузка сервера приложения. Эта установка требует значительных ресурсов и делает систему менее стабильной. Используйте её только при разработке. Приложение слушает входящие подключения на IP `127.0.0.1`. Это IP адрес вашей машины, предназначенный для внутренних коммуникаций (`localhost`).
+По умолчанию включена авто-перезагрузка (**auto-reload**), благодаря этому при изменении кода происходит перезагрузка сервера приложения. Эта установка требует значительных ресурсов и делает систему менее стабильной. Используйте её только при разработке. Приложение слушает входящие подключения на IP `127.0.0.1`. Это IP адрес вашей машины, предназначенный для внутренних коммуникаций (`localhost`).
-## `fastapi run`
+## `fastapi run` { #fastapi-run }
-Вызов `fastapi run` по умолчанию запускает FastAPI в режиме production.
+Вызов `fastapi run` по умолчанию запускает FastAPI в режиме продакшн.
-По умолчанию функция перезагрузки **auto-reload** отключена. Приложение слушает входящие подключения на IP `0.0.0.0`, т.е. на всех доступных адресах компьютера. Таким образом, приложение будет находиться в публичном доступе для любого, кто может подсоединиться к вашей машине. Продуктовые приложения запускаются именно так, например, с помощью контейнеров.
+По умолчанию авто-перезагрузка (**auto-reload**) отключена. Приложение слушает входящие подключения на IP `0.0.0.0`, т.е. на всех доступных адресах компьютера. Таким образом, приложение будет находиться в публичном доступе для любого, кто может подсоединиться к вашей машине. Продуктовые приложения запускаются именно так, например, с помощью контейнеров.
В большинстве случаев вы будете (и должны) использовать прокси-сервер ("termination proxy"), который будет поддерживать HTTPS поверх вашего приложения. Всё будет зависеть от того, как вы развертываете приложение: за вас это либо сделает ваш провайдер, либо вам придется сделать настройки самостоятельно.
/// tip | Подсказка
-Вы можете больше узнать об этом в документации по развертыванию приложений [deployment documentation](deployment/index.md){.internal-link target=_blank}.
+Вы можете больше узнать об этом в [документации по развертыванию](deployment/index.md){.internal-link target=_blank}.
///
diff --git a/docs/ru/docs/features.md b/docs/ru/docs/features.md
index 77d6b936a..91ffe331b 100644
--- a/docs/ru/docs/features.md
+++ b/docs/ru/docs/features.md
@@ -1,23 +1,21 @@
-# Основные свойства
+# Возможности { #features }
-## Основные свойства FastAPI
+## Возможности FastAPI { #fastapi-features }
**FastAPI** предлагает вам следующее:
-### Использование открытых стандартов
+### Основано на открытых стандартах { #based-on-open-standards }
-* OpenAPI для создания API, включая объявления операций пути, параметров, тела запроса, безопасности и т.д.
-
-
-* Автоматическое документирование моделей данных в соответствии с JSON Schema (так как спецификация OpenAPI сама основана на JSON Schema).
-* Разработан, придерживаясь этих стандартов, после тщательного их изучения. Эти стандарты изначально включены во фреймфорк, а не являются дополнительной надстройкой.
+* OpenAPI для создания API, включая объявления операций пути, параметров, тел запросов, безопасности и т. д.
+* Автоматическая документация моделей данных с помощью JSON Schema (так как сама спецификация OpenAPI основана на JSON Schema).
+* Разработан вокруг этих стандартов, после тщательного их изучения. Это не дополнительная надстройка поверх.
* Это также позволяет использовать автоматическую **генерацию клиентского кода** на многих языках.
-### Автоматически генерируемая документация
+### Автоматическая документация { #automatic-docs }
-Интерактивная документация для API и исследования пользовательских веб-интерфейсов. Поскольку этот фреймворк основан на OpenAPI, существует несколько вариантов документирования, 2 из которых включены по умолчанию.
+Интерактивная документация для API и исследовательские веб-интерфейсы. Поскольку фреймворк основан на OpenAPI, существует несколько вариантов документирования, 2 из них включены по умолчанию.
-* Swagger UI, с интерактивным взаимодействием, вызывает и тестирует ваш API прямо из браузера.
+* Swagger UI, с интерактивным исследованием, вызовом и тестированием вашего API прямо из браузера.

@@ -25,22 +23,21 @@

-### Только современный Python
+### Только современный Python { #just-modern-python }
-Все эти возможности основаны на стандартных **аннотациях типов Python 3.8** (благодаря Pydantic). Не нужно изучать новый синтаксис. Только лишь стандартный современный Python.
+Все основано на стандартных **аннотациях типов Python** (благодаря Pydantic). Не нужно изучать новый синтаксис. Только стандартный современный Python.
-Если вам нужно освежить знания, как использовать аннотации типов в Python (даже если вы не используете FastAPI), выделите 2 минуты и просмотрите краткое руководство: [Введение в аннотации типов Python¶
-](python-types.md){.internal-link target=_blank}.
+Если вам нужно освежить знания о типах в Python (даже если вы не используете FastAPI), выделите 2 минуты и просмотрите краткое руководство: [Типы Python](python-types.md){.internal-link target=_blank}.
-Вы пишете на стандартном Python с аннотациями типов:
+Вы пишете стандартный Python с типами:
```Python
from datetime import date
from pydantic import BaseModel
-# Объявляем параметр user_id с типом `str`
-# и получаем поддержку редактора внутри функции
+# Объявляем параметр как `str`
+# и получаем поддержку редактора кода внутри функции
def main(user_id: str):
return user_id
@@ -70,17 +67,17 @@ my_second_user: User = User(**second_user_data)
`**second_user_data` означает:
-Передать ключи и значения словаря `second_user_data`, в качестве аргументов типа "ключ-значение", это эквивалентно: `User(id=4, name="Mary", joined="2018-11-30")` .
+Передать ключи и значения словаря `second_user_data` в качестве аргументов "ключ-значение", эквивалентно: `User(id=4, name="Mary", joined="2018-11-30")`
///
-### Поддержка редакторов (IDE)
+### Поддержка редакторов (IDE) { #editor-support }
Весь фреймворк был продуман так, чтобы быть простым и интуитивно понятным в использовании, все решения были проверены на множестве редакторов еще до начала разработки, чтобы обеспечить наилучшие условия при написании кода.
-В опросе Python-разработчиков было выяснено, что наиболее часто используемой функцией редакторов, является "автодополнение".
+В опросах Python‑разработчиков видно, что одной из самых часто используемых функций является «автозавершение».
-Вся структура **FastAPI** основана на удовлетворении этой возможности. Автодополнение работает везде.
+Вся структура **FastAPI** основана на удовлетворении этой возможности. Автозавершение работает везде.
Вам редко нужно будет возвращаться к документации.
@@ -94,23 +91,23 @@ my_second_user: User = User(**second_user_data)

-Вы будете получать автодополнение кода даже там, где вы считали это невозможным раньше.
-Как пример, ключ `price` внутри тела JSON (который может быть вложенным), приходящего в запросе.
+Вы будете получать автозавершение кода даже там, где вы считали это невозможным раньше. Как пример, ключ `price` внутри тела JSON (который может быть вложенным), приходящего в запросе.
+
+Больше никаких неправильных имён ключей, метания по документации или прокручивания кода вверх и вниз в попытках узнать — использовали вы ранее `username` или `user_name`.
-Больше никаких неправильных имён ключей, метания по документации или прокручивания кода вверх и вниз, в попытках узнать - использовали вы ранее `username` или `user_name`.
+### Краткость { #short }
-### Краткость
-FastAPI имеет продуманные значения **по умолчанию** для всего, с произвольными настройками везде. Все параметры могут быть тонко подстроены так, чтобы делать то, что вам нужно и определять необходимый вам API.
+FastAPI имеет продуманные значения **по умолчанию** для всего, с опциональными настройками везде. Все параметры могут быть тонко подстроены так, чтобы делать то, что вам нужно, и определять необходимый вам API.
-Но, по умолчанию, всё это **"и так работает"**.
+Но по умолчанию всё **«просто работает»**.
-### Проверка значений
+### Проверка значений { #validation }
-* Проверка значений для большинства (или всех?) **типов данных** Python, включая:
+* Проверка значений для большинства (или всех?) **типов данных** Python, включая:
* Объекты JSON (`dict`).
- * Массивы JSON (`list`) с установленными типами элементов.
+ * Массив JSON (`list`) с определёнными типами элементов.
* Строковые (`str`) поля с ограничением минимальной и максимальной длины.
- * Числа (`int`, `float`) с минимальными и максимальными значениями и т.п.
+ * Числа (`int`, `float`) с минимальными и максимальными значениями и т. п.
* Проверка для более экзотических типов, таких как:
* URL.
@@ -118,11 +115,11 @@ FastAPI имеет продуманные значения **по умолчан
* UUID.
* ...и другие.
-Все проверки обрабатываются хорошо зарекомендовавшим себя и надежным **Pydantic**.
+Все проверки обрабатываются хорошо зарекомендовавшим себя и надёжным **Pydantic**.
-### Безопасность и аутентификация
+### Безопасность и аутентификация { #security-and-authentication }
-Встроеные функции безопасности и аутентификации. Без каких-либо компромиссов с базами данных или моделями данных.
+Встроенные функции безопасности и аутентификации. Без каких‑либо компромиссов с базами данных или моделями данных.
Все схемы безопасности, определённые в OpenAPI, включая:
@@ -137,68 +134,68 @@ FastAPI имеет продуманные значения **по умолчан
Все инструменты и компоненты спроектированы для многократного использования и легко интегрируются с вашими системами, хранилищами данных, реляционными и NoSQL базами данных и т. д.
-### Внедрение зависимостей
+### Внедрение зависимостей { #dependency-injection }
FastAPI включает в себя чрезвычайно простую в использовании, но чрезвычайно мощную систему Внедрения зависимостей.
-* Даже зависимости могут иметь зависимости, создавая иерархию или **"графы" зависимостей**.
+* Даже зависимости могут иметь зависимости, создавая иерархию или **«граф» зависимостей**.
* Всё **автоматически обрабатывается** фреймворком.
* Все зависимости могут запрашивать данные из запросов и **дополнять операции пути** ограничениями и автоматической документацией.
-* **Автоматическая проверка** даже для параметров *операций пути*, определенных в зависимостях.
-* Поддержка сложных систем аутентификации пользователей, **соединений с базами данных** и т.д.
-* **Никаких компромиссов** с базами данных, интерфейсами и т.д. Но легкая интеграция со всеми ними.
+* **Автоматическая проверка** даже для параметров *операций пути*, определённых в зависимостях.
+* Поддержка сложных систем аутентификации пользователей, **соединений с базами данных** и т. д.
+* **Никаких компромиссов** с базами данных, интерфейсами и т. д. Но при этом — лёгкая интеграция со всеми ними.
-### Нет ограничений на "Плагины"
+### Нет ограничений на "Плагины" { #unlimited-plug-ins }
-Или, другими словами, нет сложностей с ними, импортируйте и используйте нужный вам код.
+Или, другими словами, нет необходимости в них — просто импортируйте и используйте нужный вам код.
-Любая интеграция разработана настолько простой в использовании (с зависимостями), что вы можете создать "плагин" для своего приложения в пару строк кода, используя ту же структуру и синтаксис, что и для ваших *операций пути*.
+Любая интеграция разработана настолько простой в использовании (с зависимостями), что вы можете создать «плагин» для своего приложения в пару строк кода, используя ту же структуру и синтаксис, что и для ваших *операций пути*.
-### Проверен
+### Проверен { #tested }
-* 100% покрытие тестами.
-* 100% аннотирование типов в кодовой базе.
-* Используется в реально работающих приложениях.
+* 100% покрытие тестами.
+* 100% аннотирование типов в кодовой базе.
+* Используется в продакшн‑приложениях.
-## Основные свойства Starlette
+## Возможности Starlette { #starlette-features }
-**FastAPI** основан на Starlette и полностью совместим с ним. Так что, любой дополнительный код Starlette, который у вас есть, будет также работать.
+**FastAPI** основан на Starlette и полностью совместим с ним. Так что любой дополнительный код Starlette, который у вас есть, также будет работать.
-На самом деле, `FastAPI` - это класс, унаследованный от `Starlette`. Таким образом, если вы уже знаете или используете Starlette, большая часть функционала будет работать так же.
+На самом деле, `FastAPI` — это подкласс `Starlette`. Таким образом, если вы уже знаете или используете Starlette, большая часть функционала будет работать так же.
-С **FastAPI** вы получаете все возможности **Starlette** (так как FastAPI это всего лишь Starlette на стероидах):
+С **FastAPI** вы получаете все возможности **Starlette** (так как FastAPI — это всего лишь Starlette на стероидах):
-* Серьёзно впечатляющая производительность. Это один из самых быстрых фреймворков на Python, наравне с приложениями использующими **NodeJS** или **Go**.
+* Серьёзно впечатляющая производительность. Это один из самых быстрых фреймворков на Python, наравне с **NodeJS** и **Go**.
* Поддержка **WebSocket**.
-* Фоновые задачи для процессов.
+* Фоновые задачи в том же процессе.
* События запуска и выключения.
-* Тестовый клиент построен на библиотеке HTTPX.
+* Тестовый клиент построен на HTTPX.
* **CORS**, GZip, статические файлы, потоковые ответы.
* Поддержка **сессий и cookie**.
* 100% покрытие тестами.
* 100% аннотирование типов в кодовой базе.
-## Особенности и возможности Pydantic
+## Возможности Pydantic { #pydantic-features }
-**FastAPI** основан на Pydantic и полностью совместим с ним. Так что, любой дополнительный код Pydantic, который у вас есть, будет также работать.
+**FastAPI** полностью совместим с (и основан на) Pydantic. Поэтому любой дополнительный код Pydantic, который у вас есть, также будет работать.
-Включая внешние библиотеки, также основанные на Pydantic, такие как: ORM'ы, ODM'ы для баз данных.
+Включая внешние библиотеки, также основанные на Pydantic, такие как ORM’ы, ODM’ы для баз данных.
Это также означает, что во многих случаях вы можете передавать тот же объект, который получили из запроса, **непосредственно в базу данных**, так как всё проверяется автоматически.
И наоборот, во многих случаях вы можете просто передать объект, полученный из базы данных, **непосредственно клиенту**.
-С **FastAPI** вы получаете все возможности **Pydantic** (так как, FastAPI основан на Pydantic, для обработки данных):
-
-* **Никакой нервотрёпки** :
- * Не нужно изучать новых схем в микроязыках.
- * Если вы знаете аннотации типов в Python, вы знаете, как использовать Pydantic.
-* Прекрасно сочетается с вашими **IDE/linter/мозгом**:
- * Потому что структуры данных pydantic - это всего лишь экземпляры классов, определённых вами. Автодополнение, проверка кода, mypy и ваша интуиция - всё будет работать с вашими проверенными данными.
-* Проверка **сложных структур**:
- * Использование иерархических моделей Pydantic; `List`, `Dict` и т.п. из модуля `typing` (входит в стандартную библиотеку Python).
- * Валидаторы позволяют четко и легко определять, проверять и документировать сложные схемы данных в виде JSON Schema.
- * У вас могут быть глубоко **вложенные объекты JSON** и все они будут проверены и аннотированы.
+С **FastAPI** вы получаете все возможности **Pydantic** (так как FastAPI основан на Pydantic для обработки данных):
+
+* **Никакой нервотрёпки**:
+ * Не нужно изучать новые схемы в микроязыках.
+ * Если вы знаете типы в Python, вы знаете, как использовать Pydantic.
+* Прекрасно сочетается с вашим **IDE/linter/мозгом**:
+ * Потому что структуры данных pydantic — это всего лишь экземпляры классов, определённых вами; автозавершение, проверка кода, mypy и ваша интуиция — всё будет работать с вашими валидированными данными.
+* Валидация **сложных структур**:
+ * Использование иерархических моделей Pydantic; `List`, `Dict` и т. п. из модуля `typing` (входит в стандартную библиотеку Python).
+ * Валидаторы позволяют чётко и легко определять, проверять и документировать сложные схемы данных в виде JSON Schema.
+ * У вас могут быть глубоко **вложенные объекты JSON**, и все они будут проверены и аннотированы.
* **Расширяемость**:
- * Pydantic позволяет определять пользовательские типы данных или расширять проверку методами модели, с помощью проверочных декораторов.
+ * Pydantic позволяет определять пользовательские типы данных или расширять проверку методами модели с помощью декораторов валидаторов.
* 100% покрытие тестами.
diff --git a/docs/ru/docs/help-fastapi.md b/docs/ru/docs/help-fastapi.md
index 2f73c3c10..6bfabb96c 100644
--- a/docs/ru/docs/help-fastapi.md
+++ b/docs/ru/docs/help-fastapi.md
@@ -1,261 +1,255 @@
-# Помочь FastAPI - Получить помощь
+# Помочь FastAPI - Получить помощь { #help-fastapi-get-help }
Нравится ли Вам **FastAPI**?
-Хотели бы Вы помочь FastAPI, его пользователям и автору?
+Хотели бы Вы помочь FastAPI, другим пользователям и автору?
-Может быть у Вас возникли трудности с **FastAPI** и Вам нужна помощь?
+Или Вы хотите получить помощь по **FastAPI**?
-Есть несколько очень простых способов оказания помощи (иногда достаточно всего лишь одного или двух кликов).
+Есть несколько очень простых способов помочь (иногда достаточно всего лишь одного-двух кликов).
И также есть несколько способов получить помощь.
-## Подписаться на новостную рассылку
+## Подписаться на новостную рассылку { #subscribe-to-the-newsletter }
Вы можете подписаться на редкую [новостную рассылку **FastAPI и его друзья**](newsletter.md){.internal-link target=_blank} и быть в курсе о:
* Новостях о FastAPI и его друзьях 🚀
* Руководствах 📝
* Возможностях ✨
-* Исправлениях 🚨
+* Ломающих изменениях 🚨
* Подсказках и хитростях ✅
-## Подписаться на FastAPI в X (Twitter)
+## Подписаться на FastAPI в X (Twitter) { #follow-fastapi-on-x-twitter }
Подписаться на @fastapi в **X (Twitter)** для получения наисвежайших новостей о **FastAPI**. 🐦
-## Добавить **FastAPI** звезду на GitHub
+## Добавить **FastAPI** звезду на GitHub { #star-fastapi-in-github }
-Вы можете добавить FastAPI "звезду" на GitHub (кликнуть на кнопку звезды в верхнем правом углу экрана): https://github.com/fastapi/fastapi. ⭐️
+Вы можете добавить FastAPI "звезду" на GitHub (кликнув на кнопку звезды в правом верхнем углу): https://github.com/fastapi/fastapi. ⭐️
-Чем больше звёзд, тем легче другим пользователям найти нас и увидеть, что проект уже стал полезным для многих.
+Чем больше звёзд, тем легче другим пользователям найти проект и увидеть, что он уже оказался полезным для многих.
-## Отслеживать свежие выпуски в репозитории на GitHub
+## Отслеживать свежие выпуски в репозитории на GitHub { #watch-the-github-repository-for-releases }
-Вы можете "отслеживать" FastAPI на GitHub (кликните по кнопке "watch" наверху справа): https://github.com/fastapi/fastapi. 👀
+Вы можете "отслеживать" FastAPI на GitHub (кликнув по кнопке "watch" наверху справа): https://github.com/fastapi/fastapi. 👀
-Там же Вы можете указать в настройках - "Releases only".
+Там же Вы можете выбрать "Releases only".
С такой настройкой Вы будете получать уведомления на вашу электронную почту каждый раз, когда появится новый релиз (новая версия) **FastAPI** с исправлениями ошибок и новыми возможностями.
-## Связаться с автором
+## Связаться с автором { #connect-with-the-author }
-Можно связаться со мной (Себястьян Рамирез / `tiangolo`), автором FastAPI.
+Можно связаться со мной (Sebastián Ramírez / `tiangolo`), автором.
Вы можете:
* Подписаться на меня на **GitHub**.
* Посмотреть другие мои проекты с открытым кодом, которые могут быть полезны Вам.
- * Подписавшись на меня Вы сможете получать уведомления, что я создал новый проект с открытым кодом,.
+ * Подписаться, чтобы видеть, когда я создаю новый проект с открытым кодом.
* Подписаться на меня в **X (Twitter)** или в Mastodon.
- * Поделиться со мной, как Вы используете FastAPI (я обожаю читать про это).
- * Получать уведомления, когда я делаю объявления и представляю новые инструменты.
+ * Поделиться со мной, как Вы используете FastAPI (я обожаю это читать).
+ * Узнавать, когда я делаю объявления или выпускаю новые инструменты.
* Вы также можете подписаться на @fastapi в X (Twitter) (это отдельный аккаунт).
-* Подписаться на меня в **Linkedin**.
- * Получать уведомления, когда я делаю объявления и представляю новые инструменты (правда чаще всего я использую X (Twitter) 🤷♂).
-* Читать, что я пишу (или подписаться на меня) в **Dev.to** или в **Medium**.
- * Читать другие идеи, статьи и читать об инструментах созданных мной.
- * Подпишитесь на меня, чтобы прочитать, когда я опубликую что-нибудь новое.
+* Подписаться на меня в **LinkedIn**.
+ * Узнавать, когда я делаю объявления или выпускаю новые инструменты (хотя чаще я использую X (Twitter) 🤷♂).
+* Читать, что я пишу (или подписаться на меня) на **Dev.to** или **Medium**.
+ * Читать другие идеи, статьи и о созданных мной инструментах.
+ * Подписаться, чтобы читать, когда я публикую что-то новое.
-## Оставить сообщение в X (Twitter) о **FastAPI**
+## Оставить сообщение в X (Twitter) о **FastAPI** { #tweet-about-fastapi }
-Оставьте сообщение в X (Twitter) о **FastAPI** и позвольте мне и другим узнать - почему он Вам нравится. 🎉
+Оставьте сообщение в X (Twitter) о **FastAPI** и позвольте мне и другим узнать, почему он Вам нравится. 🎉
-Я люблю узнавать о том, как **FastAPI** используется, что Вам понравилось в нём, в каких проектах/компаниях Вы используете его и т.п.
+Я люблю узнавать о том, как **FastAPI** используется, что Вам понравилось в нём, в каких проектах/компаниях Вы его используете и т.д.
-## Оставить голос за FastAPI
+## Оставить голос за FastAPI { #vote-for-fastapi }
* Голосуйте за **FastAPI** в Slant.
-* Голосуйте за **FastAPI** в AlternativeTo.
-* Расскажите, как Вы используете **FastAPI** на StackShare.
+* Голосуйте за **FastAPI** в AlternativeTo.
+* Расскажите, что Вы используете **FastAPI** на StackShare.
-## Помочь другим с их проблемами на GitHub
+## Помочь другим с вопросами на GitHub { #help-others-with-questions-in-github }
-Вы можете посмотреть, какие проблемы испытывают другие люди и попытаться помочь им. Чаще всего это вопросы, на которые, весьма вероятно, Вы уже знаете ответ. 🤓
+Вы можете попробовать помочь другим с их вопросами в:
-Если Вы будете много помогать людям с решением их проблем, Вы можете стать официальным [Экспертом FastAPI](fastapi-people.md#_3){.internal-link target=_blank}. 🎉
+* GitHub Discussions
+* GitHub Issues
-Только помните, самое важное при этом - доброта. Столкнувшись с проблемой, люди расстраиваются и часто задают вопросы не лучшим образом, но постарайтесь быть максимально доброжелательным. 🤗
+Во многих случаях Вы уже можете знать ответы на эти вопросы. 🤓
-Идея сообщества **FastAPI** в том, чтобы быть добродушным и гостеприимными. Не допускайте издевательств или неуважительного поведения по отношению к другим. Мы должны заботиться друг о друге.
+Если Вы много помогаете людям с их вопросами, Вы станете официальным [Экспертом FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}. 🎉
+
+Только помните, самое важное — постарайтесь быть добрыми. Люди приходят со своими разочарованиями и часто задают вопросы не лучшим образом, но постарайтесь, насколько можете, быть доброжелательными. 🤗
+
+Идея сообщества **FastAPI** — быть доброжелательным и гостеприимным. В то же время не допускайте травлю или неуважительное поведение по отношению к другим. Мы должны заботиться друг о друге.
---
-Как помочь другим с их проблемами:
+Как помочь другим с вопросами (в обсуждениях или Issues):
-### Понять вопрос
+### Понять вопрос { #understand-the-question }
-* Удостоверьтесь, что поняли **цель** и обстоятельства случая вопрошающего.
+* Убедитесь, что поняли **цель** и кейс использования задающего вопрос.
-* Затем проверьте, что вопрос (в подавляющем большинстве - это вопросы) Вам **ясен**.
+* Затем проверьте, что вопрос (в подавляющем большинстве это вопросы) сформулирован **ясно**.
-* Во многих случаях вопрос касается решения, которое пользователь придумал сам, но может быть и решение **получше**. Если Вы поймёте проблему и обстоятельства случая, то сможете предложить **альтернативное решение**.
+* Во многих случаях спрашивают о воображаемом решении пользователя, но может быть решение **получше**. Если Вы лучше поймёте проблему и кейс, сможете предложить **альтернативное решение**.
-* Ежели вопрос Вам непонятен, запросите больше **деталей**.
+* Если вопрос непонятен, запросите больше **деталей**.
-### Воспроизвести проблему
+### Воспроизвести проблему { #reproduce-the-problem }
-В большинстве случаев есть что-то связанное с **исходным кодом** вопрошающего.
+В большинстве случаев и вопросов есть что-то связанное с **исходным кодом** автора.
-И во многих случаях будет предоставлен только фрагмент этого кода, которого недостаточно для **воспроизведения проблемы**.
+Во многих случаях предоставляют только фрагмент кода, но этого недостаточно, чтобы **воспроизвести проблему**.
-* Попросите предоставить минимальный воспроизводимый пример, который можно **скопировать** и запустить локально дабы увидеть такую же ошибку, или поведение, или лучше понять обстоятельства случая.
+* Попросите предоставить минимальный воспроизводимый пример, который Вы сможете **скопировать-вставить** и запустить локально, чтобы увидеть ту же ошибку или поведение, или лучше понять их кейс.
-* Если на Вас нахлынуло великодушие, то можете попытаться **создать похожий пример** самостоятельно, основываясь только на описании проблемы. Но имейте в виду, что это может занять много времени и, возможно, стоит сначала позадавать вопросы для прояснения проблемы.
+* Если чувствуете себя особенно великодушными, можете попытаться **создать такой пример** сами, основываясь только на описании проблемы. Просто помните, что это может занять много времени, и, возможно, сначала лучше попросить уточнить проблему.
-### Предложить решение
+### Предложить решение { #suggest-solutions }
-* После того как Вы поняли вопрос, Вы можете дать **ответ**.
+* После того как Вы поняли вопрос, Вы можете дать возможный **ответ**.
-* Следует понять **основную проблему и обстоятельства случая**, потому что может быть решение лучше, чем то, которое пытались реализовать.
+* Во многих случаях лучше понять **исходную проблему или кейс**, потому что может существовать способ решить её лучше, чем то, что пытаются сделать.
-### Попросить закрыть проблему
+### Попросить закрыть { #ask-to-close }
-Если Вам ответили, высоки шансы, что Вам удалось решить проблему, поздравляю, **Вы - герой**! 🦸
+Если Вам ответили, велика вероятность, что Вы решили их проблему, поздравляю, **Вы — герой**! 🦸
-* В таком случае, если вопрос решён, попросите **закрыть проблему**.
+* Теперь, если проблема решена, можно попросить их:
+ * В GitHub Discussions: пометить комментарий как **answer** (ответ).
+ * В GitHub Issues: **закрыть** Issue.
-## Отслеживать репозиторий на GitHub
+## Отслеживать репозиторий на GitHub { #watch-the-github-repository }
-Вы можете "отслеживать" FastAPI на GitHub (кликните по кнопке "watch" наверху справа): https://github.com/fastapi/fastapi. 👀
+Вы можете "отслеживать" FastAPI на GitHub (кликнув по кнопке "watch" наверху справа): https://github.com/fastapi/fastapi. 👀
-Если Вы выберете "Watching" вместо "Releases only", то будете получать уведомления когда кто-либо попросит о помощи с решением его проблемы.
+Если Вы выберете "Watching" вместо "Releases only", то будете получать уведомления, когда кто-либо создаёт новый вопрос или Issue. Вы также можете указать, что хотите получать уведомления только о новых Issues, или обсуждениях, или пулл-реквестах и т.д.
-Тогда Вы можете попробовать решить эту проблему.
+Тогда Вы можете попробовать помочь им с решением этих вопросов.
-## Запросить помощь с решением проблемы
+## Задать вопросы { #ask-questions }
-Вы можете создать новый запрос с просьбой о помощи в репозитории на GitHub, например:
+Вы можете создать новый вопрос в репозитории GitHub, например:
-* Задать **вопрос** или попросить помощи в решении **проблемы**.
-* Предложить новое **улучшение**.
+* Задать **вопрос** или спросить о **проблеме**.
+* Предложить новую **возможность**.
-**Заметка**: Если Вы создаёте подобные запросы, то я попрошу Вас также оказывать аналогичную помощь другим. 😉
+**Заметка**: если Вы это сделаете, то я попрошу Вас также помогать другим. 😉
-## Проверять пул-реквесты
+## Проверять пулл-реквесты { #review-pull-requests }
-Вы можете помочь мне проверять пул-реквесты других участников.
+Вы можете помочь мне проверять пулл-реквесты других участников.
-И повторюсь, постарайтесь быть доброжелательным. 🤗
+И, снова, постарайтесь быть доброжелательными. 🤗
---
-О том, что нужно иметь в виду при проверке пул-реквестов:
+О том, что нужно иметь в виду и как проверять пулл-реквест:
-### Понять проблему
+### Понять проблему { #understand-the-problem }
-* Во-первых, убедитесь, что **поняли проблему**, которую пул-реквест пытается решить. Для этого может потребоваться продолжительное обсуждение.
+* Во-первых, убедитесь, что **поняли проблему**, которую пулл-реквест пытается решить. Возможно, это обсуждалось более подробно в GitHub Discussion или Issue.
-* Также есть вероятность, что пул-реквест не актуален, так как проблему можно решить **другим путём**. В таком случае Вы можете указать на этот факт.
+* Также есть вероятность, что пулл-реквест не нужен, так как проблему можно решить **другим путём**. Тогда Вы можете предложить или спросить об этом.
-### Не переживайте о стиле
+### Не переживайте о стиле { #dont-worry-about-style }
-* Не стоит слишком беспокоиться о таких вещах, как стиль сообщений в коммитах или количество коммитов. При слиянии пул-реквеста с основной веткой, я буду сжимать и настраивать всё вручную.
+* Не стоит слишком беспокоиться о таких вещах, как стиль сообщений в коммитах — при слиянии я выполню squash и настрою коммит вручную.
-* Также не беспокойтесь о правилах стиля, для проверки сего есть автоматизированные инструменты.
+* Также не беспокойтесь о правилах стиля, это уже проверяют автоматизированные инструменты.
-И если всё же потребуется какой-то другой стиль, я попрошу Вас об этом напрямую или добавлю сам коммиты с необходимыми изменениями.
+Если будет нужна какая-то другая стилистика или единообразие, я попрошу об этом напрямую или добавлю поверх свои коммиты с нужными изменениями.
-### Проверить код
+### Проверить код { #check-the-code }
-* Проверьте и прочитайте код, посмотрите, какой он имеет смысл, **запустите его локально** и посмотрите, действительно ли он решает поставленную задачу.
+* Проверьте и прочитайте код, посмотрите, логичен ли он, **запустите его локально** и проверьте, действительно ли он решает проблему.
-* Затем, используя **комментарий**, сообщите, что Вы сделали проверку, тогда я буду знать, что Вы действительно проверили код.
+* Затем оставьте **комментарий**, что Вы это сделали, так я пойму, что Вы действительно проверили код.
/// info | Информация
-К сожалению, я не могу так просто доверять пул-реквестам, у которых уже есть несколько одобрений.
+К сожалению, я не могу просто доверять PR-ам только потому, что у них есть несколько одобрений.
-Бывали случаи, что пул-реквесты имели 3, 5 или больше одобрений, вероятно из-за привлекательного описания, но когда я проверял эти пул-реквесты, они оказывались сломаны, содержали ошибки или вовсе не решали проблему, которую, как они утверждали, должны были решить. 😅
+Несколько раз было так, что у PR-ов было 3, 5 или больше одобрений, вероятно из-за привлекательного описания, но когда я их проверял, они оказывались сломанными, содержали баги или вовсе не решали заявленную проблему. 😅
-Потому это действительно важно - проверять и запускать код, и комментарием уведомлять меня, что Вы проделали эти действия. 🤓
+Поэтому очень важно действительно прочитать и запустить код и сообщить мне об этом в комментарии. 🤓
///
-* Если Вы считаете, что пул-реквест можно упростить, то можете попросить об этом, но не нужно быть слишком придирчивым, может быть много субъективных точек зрения (и у меня тоже будет своя 🙈), поэтому будет лучше, если Вы сосредоточитесь на фундаментальных вещах.
+* Если PR можно упростить, Вы можете попросить об этом, но не нужно быть слишком придирчивым — может быть много субъективных мнений (и у меня тоже 🙈), поэтому лучше сосредоточиться на фундаментальных вещах.
-### Тестировать
+### Тестировать { #tests }
-* Помогите мне проверить, что у пул-реквеста есть **тесты**.
+* Помогите мне проверить, что у PR есть **тесты**.
-* Проверьте, что тесты **падали** до пул-реквеста. 🚨
+* Проверьте, что тесты **падают** до PR. 🚨
-* Затем проверьте, что тесты **не валятся** после пул-реквеста. ✅
+* Затем проверьте, что тесты **проходят** после PR. ✅
-* Многие пул-реквесты не имеют тестов, Вы можете **напомнить** о необходимости добавления тестов или даже **предложить** какие-либо свои тесты. Это одна из тех вещей, которые отнимают много времени и Вы можете помочь с этим.
+* Многие PR не имеют тестов — Вы можете **напомнить** добавить тесты или даже **предложить** некоторые тесты сами. Это одна из самых трудозатратных частей, и здесь Вы можете очень помочь.
-* Затем добавьте комментарий, что Вы испробовали в ходе проверки. Таким образом я буду знать, как Вы произвели проверку. 🤓
+* Затем добавьте комментарий, что Вы попробовали, чтобы я знал, что Вы это проверили. 🤓
-## Создать пул-реквест
+## Создать пулл-реквест { #create-a-pull-request }
-Вы можете [сделать вклад](contributing.md){.internal-link target=_blank} в код фреймворка используя пул-реквесты, например:
+Вы можете [сделать вклад](contributing.md){.internal-link target=_blank} в исходный код пулл-реквестами, например:
-* Исправить опечатку, которую Вы нашли в документации.
-* Поделиться статьёй, видео или подкастом о FastAPI, которые Вы создали или нашли изменив этот файл.
- * Убедитесь, что Вы добавили свою ссылку в начало соответствующего раздела.
-* Помочь с [переводом документации](contributing.md#_8){.internal-link target=_blank} на Ваш язык.
- * Вы также можете проверять переводы сделанные другими.
+* Исправить опечатку, найденную в документации.
+* Поделиться статьёй, видео или подкастом о FastAPI, которые Вы создали или нашли, изменив этот файл.
+ * Убедитесь, что добавили свою ссылку в начало соответствующего раздела.
+* Помочь с [переводом документации](contributing.md#translations){.internal-link target=_blank} на Ваш язык.
+ * Вы также можете проверять переводы, сделанные другими.
* Предложить новые разделы документации.
-* Исправить существующуе проблемы/баги.
+* Исправить существующую проблему/баг.
* Убедитесь, что добавили тесты.
* Добавить новую возможность.
* Убедитесь, что добавили тесты.
- * Убедитесь, что добавили документацию, если она необходима.
+ * Убедитесь, что добавили документацию, если это уместно.
-## Помочь поддерживать FastAPI
+## Помочь поддерживать FastAPI { #help-maintain-fastapi }
Помогите мне поддерживать **FastAPI**! 🤓
-Предстоит ещё много работы и, по большей части, **ВЫ** можете её сделать.
+Предстоит ещё много работы, и, по большей части, **ВЫ** можете её сделать.
Основные задачи, которые Вы можете выполнить прямо сейчас:
-* [Помочь другим с их проблемами на GitHub](#github_1){.internal-link target=_blank} (смотрите вышестоящую секцию).
-* [Проверить пул-реквесты](#-){.internal-link target=_blank} (смотрите вышестоящую секцию).
+* [Помочь другим с вопросами на GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (смотрите секцию выше).
+* [Проверять пулл-реквесты](#review-pull-requests){.internal-link target=_blank} (смотрите секцию выше).
-Эти две задачи **отнимают больше всего времени**. Это основная работа по поддержке FastAPI.
+Именно эти две задачи **забирают больше всего времени**. Это основная работа по поддержке FastAPI.
-Если Вы можете помочь мне с этим, **Вы помогаете поддерживать FastAPI** и следить за тем, чтобы он продолжал **развиваться быстрее и лучше**. 🚀
+Если Вы можете помочь мне с этим, **Вы помогаете поддерживать FastAPI** и делаете так, чтобы он продолжал **развиваться быстрее и лучше**. 🚀
-## Подключиться к чату
+## Подключиться к чату { #join-the-chat }
-Подключайтесь к 👥 чату в Discord 👥 и общайтесь с другими участниками сообщества FastAPI.
+Подключайтесь к 👥 серверу чата в Discord 👥 и общайтесь с другими участниками сообщества FastAPI.
/// tip | Подсказка
-Вопросы по проблемам с фреймворком лучше задавать в GitHub issues, так больше шансов, что Вы получите помощь от [Экспертов FastAPI](fastapi-people.md#_3){.internal-link target=_blank}.
+По вопросам — задавайте их в GitHub Discussions, так гораздо выше шанс, что Вы получите помощь от [Экспертов FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}.
-Используйте этот чат только для бесед на отвлечённые темы.
+Используйте чат только для прочих общих бесед.
///
-### Не использовать чаты для вопросов
-
-Имейте в виду, что чаты позволяют больше "свободного общения", потому там легко задавать вопросы, которые слишком общие и на которые труднее ответить, так что Вы можете не получить нужные Вам ответы.
-
-В разделе "проблемы" на GitHub, есть шаблон, который поможет Вам написать вопрос правильно, чтобы Вам было легче получить хороший ответ или даже решить проблему самостоятельно, прежде чем Вы зададите вопрос. В GitHub я могу быть уверен, что всегда отвечаю на всё, даже если это займет какое-то время. И я не могу сделать то же самое в чатах. 😅
-
-Кроме того, общение в чатах не так легкодоступно для поиска, как в GitHub, потому вопросы и ответы могут потеряться среди другого общения. И только проблемы решаемые на GitHub учитываются в получении лычки [Эксперт FastAPI](fastapi-people.md#_3){.internal-link target=_blank}, так что весьма вероятно, что Вы получите больше внимания на GitHub.
-
-С другой стороны, в чатах тысячи пользователей, а значит есть большие шансы в любое время найти там кого-то, с кем можно поговорить. 😄
-
-## Спонсировать автора
-
-Вы также можете оказать мне финансовую поддержку посредством спонсорства через GitHub.
+### Не используйте чат для вопросов { #dont-use-the-chat-for-questions }
-Там можно просто купить мне кофе ☕️ в знак благодарности. 😄
+Имейте в виду, что в чатах, благодаря "свободному общению", легко задать вопросы, которые слишком общие и на которые сложнее ответить, поэтому Вы можете не получить ответы.
-А ещё Вы можете стать Серебряным или Золотым спонсором для FastAPI. 🏅🎉
+На GitHub шаблон поможет Вам правильно сформулировать вопрос, чтобы Вам было легче получить хороший ответ или даже решить проблему самостоятельно ещё до того, как спросите. И на GitHub я могу следить за тем, чтобы всегда отвечать на всё, даже если это занимает время. А с чатами я не могу сделать этого лично. 😅
-## Спонсировать инструменты, на которых зиждется мощь FastAPI
+Кроме того, переписка в чатах хуже ищется, чем на GitHub, поэтому вопросы и ответы могут теряться среди остальных сообщений. И только те, что на GitHub, учитываются для получения лычки [Эксперт FastAPI](fastapi-people.md#fastapi-experts){.internal-link target=_blank}, так что вероятнее всего Вы получите больше внимания именно на GitHub.
-Как Вы могли заметить в документации, FastAPI опирается на плечи титанов: Starlette и Pydantic.
+С другой стороны, в чатах тысячи пользователей, так что почти всегда есть шанс найти там кого-то для разговора. 😄
-Им тоже можно оказать спонсорскую поддержку:
+## Спонсировать автора { #sponsor-the-author }
-* Samuel Colvin (Pydantic)
-* Encode (Starlette, Uvicorn)
+Если Ваш **продукт/компания** зависят от **FastAPI** или связаны с ним и Вы хотите донести до пользователей информацию о себе, Вы можете спонсировать автора (меня) через GitHub Sponsors. В зависимости от уровня поддержки Вы можете получить дополнительные бонусы, например, бейдж в документации. 🎁
---
-Благодарствую! 🚀
+Спасибо! 🚀
diff --git a/docs/ru/docs/history-design-future.md b/docs/ru/docs/history-design-future.md
index 96604e3a4..d679af3e3 100644
--- a/docs/ru/docs/history-design-future.md
+++ b/docs/ru/docs/history-design-future.md
@@ -1,4 +1,4 @@
-# История создания и дальнейшее развитие
+# История, проектирование и будущее { #history-design-and-future }
Однажды, один из пользователей **FastAPI** задал вопрос:
@@ -6,7 +6,7 @@
Что ж, вот небольшая часть истории проекта.
-## Альтернативы
+## Альтернативы { #alternatives }
В течение нескольких лет я, возглавляя различные команды разработчиков, создавал довольно сложные API для машинного обучения, распределённых систем, асинхронных задач, баз данных NoSQL и т.д.
@@ -24,45 +24,47 @@
Я всячески избегал создания нового фреймворка в течение нескольких лет. Сначала я пытался собрать все нужные возможности, которые ныне есть в **FastAPI**, используя множество различных фреймворков, плагинов и инструментов.
-Но в какой-то момент не осталось другого выбора, кроме как создать что-то, что предоставляло бы все эти возможности сразу. Взять самые лучшие идеи из предыдущих инструментов и, используя введённые в Python подсказки типов (которых не было до версии 3.6), объединить их.
+Но в какой-то момент не осталось другого выбора, кроме как создать что-то, что предоставляло бы все эти возможности сразу. Взять самые лучшие идеи из предыдущих инструментов и, используя введённые в Python аннотации типов (которых не было до версии 3.6), объединить их.
-## Исследования
+## Исследования { #investigation }
Благодаря опыту использования существующих альтернатив, мы с коллегами изучили их основные идеи и скомбинировали собранные знания наилучшим образом.
-Например, стало ясно, что необходимо брать за основу стандартные подсказки типов Python, а самым лучшим подходом является использование уже существующих стандартов.
+Например, стало ясно, что необходимо брать за основу стандартные аннотации типов Python.
+
+Также наилучшим подходом является использование уже существующих стандартов.
Итак, прежде чем приступить к написанию **FastAPI**, я потратил несколько месяцев на изучение OpenAPI, JSON Schema, OAuth2, и т.п. для понимания их взаимосвязей, совпадений и различий.
-## Дизайн
+## Проектирование { #design }
Затем я потратил некоторое время на придумывание "API" разработчика, который я хотел иметь как пользователь (как разработчик, использующий FastAPI).
-Я проверил несколько идей на самых популярных редакторах кода среди Python-разработчиков: PyCharm, VS Code, Jedi.
+Я проверил несколько идей на самых популярных редакторах кода: PyCharm, VS Code, редакторы на базе Jedi.
-Данные по редакторам я взял из опроса Python-разработчиков, который охватываает около 80% пользователей.
+Данные по редакторам я взял из опроса Python-разработчиков, который охватывает около 80% пользователей.
Это означает, что **FastAPI** был специально проверен на редакторах, используемых 80% Python-разработчиками. И поскольку большинство других редакторов, как правило, работают аналогичным образом, все его преимущества должны работать практически для всех редакторов.
-Таким образом, я смог найти наилучшие способы сократить дублирование кода, обеспечить повсеместное автодополнение, проверку типов и ошибок и т.д.
+Таким образом, я смог найти наилучшие способы сократить дублирование кода, обеспечить повсеместное автозавершение, проверку типов и ошибок и т.д.
И все это, чтобы все пользователи могли получать наилучший опыт разработки.
-## Зависимости
+## Зависимости { #requirements }
Протестировав несколько вариантов, я решил, что в качестве основы буду использовать **Pydantic** и его преимущества.
-По моим предложениям был изменён код этого фреймворка, чтобы сделать его полностью совместимым с JSON Schema, поддержать различные способы определения ограничений и улучшить помощь редакторов (проверки типов, автозаполнение).
+По моим предложениям был изменён код этого фреймворка, чтобы сделать его полностью совместимым с JSON Schema, поддержать различные способы определения ограничений и улучшить поддержку в редакторах кода (проверки типов, автозавершение) на основе тестов в нескольких редакторах.
В то же время, я принимал участие в разработке **Starlette**, ещё один из основных компонентов FastAPI.
-## Разработка
+## Разработка { #development }
К тому времени, когда я начал создавать **FastAPI**, большинство необходимых деталей уже существовало, дизайн был определён, зависимости и прочие инструменты были готовы, а знания о стандартах и спецификациях были четкими и свежими.
-## Будущее
+## Будущее { #future }
Сейчас уже ясно, что **FastAPI** со своими идеями стал полезен многим людям.
diff --git a/docs/ru/docs/index.md b/docs/ru/docs/index.md
index 692c03ecb..1fcc9ea9d 100644
--- a/docs/ru/docs/index.md
+++ b/docs/ru/docs/index.md
@@ -1,4 +1,4 @@
-# FastAPI
+# FastAPI { #fastapi }