diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 68a180e380..a0e83e5c86 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -22,10 +22,10 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-v03
+ key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v03
- name: Install docs extras
if: steps.cache.outputs.cache-hit != 'true'
- run: pip install .[doc]
+ run: pip install -r requirements-docs.txt
- name: Install Material for MkDocs Insiders
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
@@ -42,7 +42,7 @@ jobs:
with:
publish-dir: './site'
production-branch: master
- github-token: ${{ secrets.GITHUB_TOKEN }}
+ github-token: ${{ secrets.FASTAPI_BUILD_DOCS_NETLIFY }}
enable-commit-comment: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml
index e2fb4f7a43..617105b6e8 100644
--- a/.github/workflows/issue-manager.yml
+++ b/.github/workflows/issue-manager.yml
@@ -20,7 +20,7 @@ jobs:
steps:
- uses: tiangolo/issue-manager@0.4.0
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ token: ${{ secrets.FASTAPI_ISSUE_MANAGER }}
config: >
{
"answered": {
diff --git a/.github/workflows/label-approved.yml b/.github/workflows/label-approved.yml
index b2646dd16d..4a73b02aa3 100644
--- a/.github/workflows/label-approved.yml
+++ b/.github/workflows/label-approved.yml
@@ -10,4 +10,4 @@ jobs:
steps:
- uses: docker://tiangolo/label-approved:0.0.2
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ token: ${{ secrets.FASTAPI_LABEL_APPROVED }}
diff --git a/.github/workflows/latest-changes.yml b/.github/workflows/latest-changes.yml
index 4aa8475b62..f11a638487 100644
--- a/.github/workflows/latest-changes.yml
+++ b/.github/workflows/latest-changes.yml
@@ -30,11 +30,9 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
with:
limit-access-to-actor: true
- token: ${{ secrets.ACTIONS_TOKEN }}
- standard_token: ${{ secrets.GITHUB_TOKEN }}
- uses: docker://tiangolo/latest-changes:0.0.3
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
latest_changes_file: docs/en/docs/release-notes.md
latest_changes_header: '## Latest Changes\n\n'
debug_logs: true
diff --git a/.github/workflows/notify-translations.yml b/.github/workflows/notify-translations.yml
index fdd24414ce..0926486e9b 100644
--- a/.github/workflows/notify-translations.yml
+++ b/.github/workflows/notify-translations.yml
@@ -19,4 +19,4 @@ jobs:
limit-access-to-actor: true
- uses: ./.github/actions/notify-translations
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ token: ${{ secrets.FASTAPI_NOTIFY_TRANSLATIONS }}
diff --git a/.github/workflows/people.yml b/.github/workflows/people.yml
index cca1329e71..b167c268fa 100644
--- a/.github/workflows/people.yml
+++ b/.github/workflows/people.yml
@@ -24,9 +24,7 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
with:
limit-access-to-actor: true
- token: ${{ secrets.ACTIONS_TOKEN }}
- standard_token: ${{ secrets.GITHUB_TOKEN }}
- uses: ./.github/actions/people
with:
token: ${{ secrets.ACTIONS_TOKEN }}
- standard_token: ${{ secrets.GITHUB_TOKEN }}
+ standard_token: ${{ secrets.FASTAPI_PEOPLE }}
diff --git a/.github/workflows/preview-docs.yml b/.github/workflows/preview-docs.yml
index 91b0cba025..298f75b026 100644
--- a/.github/workflows/preview-docs.yml
+++ b/.github/workflows/preview-docs.yml
@@ -18,7 +18,7 @@ jobs:
- name: Download Artifact Docs
uses: dawidd6/action-download-artifact@v2.27.0
with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
+ github_token: ${{ secrets.FASTAPI_PREVIEW_DOCS_DOWNLOAD_ARTIFACTS }}
workflow: build-docs.yml
run_id: ${{ github.event.workflow_run.id }}
name: docs-zip
@@ -34,7 +34,7 @@ jobs:
with:
publish-dir: './site'
production-deploy: false
- github-token: ${{ secrets.GITHUB_TOKEN }}
+ github-token: ${{ secrets.FASTAPI_PREVIEW_DOCS_NETLIFY }}
enable-commit-comment: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
@@ -42,5 +42,5 @@ jobs:
- name: Comment Deploy
uses: ./.github/actions/comment-docs-preview-in-pr
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ token: ${{ secrets.FASTAPI_PREVIEW_DOCS_COMMENT_DEPLOY }}
deploy_url: "${{ steps.netlify.outputs.deploy-url }}"
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 1ad11f8d2c..bdadcc6d3d 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -39,9 +39,3 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- # - name: Notify
- # env:
- # GITTER_TOKEN: ${{ secrets.GITTER_TOKEN }}
- # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- # TAG: ${{ github.event.release.name }}
- # run: bash scripts/notify.sh
diff --git a/.github/workflows/smokeshow.yml b/.github/workflows/smokeshow.yml
index f135fb3e4f..c6d894d9f6 100644
--- a/.github/workflows/smokeshow.yml
+++ b/.github/workflows/smokeshow.yml
@@ -22,6 +22,7 @@ jobs:
- uses: dawidd6/action-download-artifact@v2.27.0
with:
+ github_token: ${{ secrets.FASTAPI_SMOKESHOW_DOWNLOAD_ARTIFACTS }}
workflow: test.yml
commit: ${{ github.event.workflow_run.head_sha }}
@@ -30,6 +31,6 @@ jobs:
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100
SMOKESHOW_GITHUB_CONTEXT: coverage
- SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SMOKESHOW_GITHUB_TOKEN: ${{ secrets.FASTAPI_SMOKESHOW_UPLOAD }}
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 65b29be204..84f101424e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -5,16 +5,39 @@ on:
branches:
- master
pull_request:
- types: [opened, synchronize]
+ types:
+ - opened
+ - synchronize
jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: "3.11"
+ # Issue ref: https://github.com/actions/setup-python/issues/436
+ # cache: "pip"
+ # cache-dependency-path: pyproject.toml
+ - uses: actions/cache@v3
+ id: cache
+ with:
+ path: ${{ env.pythonLocation }}
+ key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
+ - name: Install Dependencies
+ if: steps.cache.outputs.cache-hit != 'true'
+ run: pip install -r requirements-tests.txt
+ - name: Lint
+ run: bash scripts/lint.sh
+
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
fail-fast: false
-
steps:
- uses: actions/checkout@v3
- name: Set up Python
@@ -23,17 +46,15 @@ jobs:
python-version: ${{ matrix.python-version }}
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
- cache-dependency-path: pyproject.toml
+ # cache-dependency-path: pyproject.toml
- uses: actions/cache@v3
id: cache
with:
path: ${{ env.pythonLocation }}
- key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v03
+ key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
- run: pip install -e .[all,dev,doc,test]
- - name: Lint
- run: bash scripts/lint.sh
+ run: pip install -r requirements-tests.txt
- run: mkdir coverage
- name: Test
run: bash scripts/test.sh
@@ -45,33 +66,28 @@ jobs:
with:
name: coverage
path: coverage
+
coverage-combine:
needs: [test]
runs-on: ubuntu-latest
-
steps:
- uses: actions/checkout@v3
-
- uses: actions/setup-python@v4
with:
python-version: '3.8'
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
- cache-dependency-path: pyproject.toml
-
+ # cache-dependency-path: pyproject.toml
- name: Get coverage files
uses: actions/download-artifact@v3
with:
name: coverage
path: coverage
-
- run: pip install coverage[toml]
-
- run: ls -la coverage
- run: coverage combine coverage
- run: coverage report
- run: coverage html --show-contexts --title "Coverage for ${{ github.sha }}"
-
- name: Store coverage HTML
uses: actions/upload-artifact@v3
with:
@@ -80,14 +96,10 @@ jobs:
# https://github.com/marketplace/actions/alls-green#why
check: # This job does nothing and is only used for the branch protection
-
if: always()
-
needs:
- coverage-combine
-
runs-on: ubuntu-latest
-
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 25e797d246..2a8a031363 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -21,24 +21,13 @@ repos:
- --py3-plus
- --keep-runtime-typing
- repo: https://github.com/charliermarsh/ruff-pre-commit
- rev: v0.0.254
+ rev: v0.0.272
hooks:
- id: ruff
args:
- --fix
-- repo: https://github.com/pycqa/isort
- rev: 5.12.0
- hooks:
- - id: isort
- name: isort (python)
- - id: isort
- name: isort (cython)
- types: [cython]
- - id: isort
- name: isort (pyi)
- types: [pyi]
- repo: https://github.com/psf/black
- rev: 23.1.0
+ rev: 23.3.0
hooks:
- id: black
ci:
diff --git a/README.md b/README.md
index 8baee7825e..ee25f18037 100644
--- a/README.md
+++ b/README.md
@@ -47,8 +47,8 @@ The key features are:
+
-
diff --git a/docs/em/docs/contributing.md b/docs/em/docs/contributing.md
index 7749d27a17..748928f88f 100644
--- a/docs/em/docs/contributing.md
+++ b/docs/em/docs/contributing.md
@@ -108,7 +108,7 @@ $ python -m pip install --upgrade pip
+
+
+
Llega tu turno, haces tu pedido de 2 hamburguesas impresionantes para esa persona 😍 y para ti.
-Pagas 💸.
+
El cajero 💁 le dice algo al chico de la cocina 👨🍳 para que sepa que tiene que preparar tus hamburguesas 🍔 (a pesar de que actualmente está preparando las de los clientes anteriores).
+
+
+Pagas 💸.
El cajero 💁 te da el número de tu turno.
+
+
Mientras esperas, vas con esa persona 😍 y eliges una mesa, se sientan y hablan durante un rato largo (ya que las hamburguesas son muy impresionantes y necesitan un rato para prepararse ✨🍔✨).
Mientras te sientas en la mesa con esa persona 😍, esperando las hamburguesas 🍔, puedes disfrutar ese tiempo admirando lo increíble, inteligente, y bien que se ve ✨😍✨.
+
+
Mientras esperas y hablas con esa persona 😍, de vez en cuando, verificas el número del mostrador para ver si ya es tu turno.
Al final, en algún momento, llega tu turno. Vas al mostrador, coges tus hamburguesas 🍔 y vuelves a la mesa.
+
+
Tú y esa persona 😍 se comen las hamburguesas 🍔 y la pasan genial ✨.
+
+
+!!! info
+ Las ilustraciones fueron creados por Ketrina Thompson. 🎨
+
---
Imagina que eres el sistema / programa 🤖 en esa historia.
@@ -150,26 +166,41 @@ Haces la cola mientras varios cajeros (digamos 8) que a la vez son cocineros
Todos los que están antes de ti están esperando 🕙 que sus hamburguesas 🍔 estén listas antes de dejar el mostrador porque cada uno de los 8 cajeros prepara la hamburguesa de inmediato antes de recibir el siguiente pedido.
+
+
Entonces finalmente es tu turno, haces tu pedido de 2 hamburguesas 🍔 impresionantes para esa persona 😍 y para ti.
Pagas 💸.
+
+
El cajero va a la cocina 👨🍳.
Esperas, de pie frente al mostrador 🕙, para que nadie más recoja tus hamburguesas 🍔, ya que no hay números para los turnos.
+
+
Como tu y esa persona 😍 están ocupados en impedir que alguien se ponga delante y recoja tus hamburguesas apenas llegan 🕙, tampoco puedes prestarle atención a esa persona 😞.
Este es un trabajo "síncrono", estás "sincronizado" con el cajero / cocinero 👨🍳. Tienes que esperar y estar allí en el momento exacto en que el cajero / cocinero 👨🍳 termina las hamburguesas 🍔 y te las da, o de lo contrario, alguien más podría cogerlas.
+
+
Luego, el cajero / cocinero 👨🍳 finalmente regresa con tus hamburguesas 🍔, después de mucho tiempo esperando 🕙 frente al mostrador.
+
+
Cojes tus hamburguesas 🍔 y vas a la mesa con esa persona 😍.
Sólo las comes y listo 🍔 ⏹.
+
+
No has hablado ni coqueteado mucho, ya que has pasado la mayor parte del tiempo esperando 🕙 frente al mostrador 😞.
+!!! info
+ Las ilustraciones fueron creados por Ketrina Thompson. 🎨
+
---
En este escenario de las hamburguesas paralelas, tú eres un sistema / programa 🤖 con dos procesadores (tú y la persona que te gusta 😍), ambos esperando 🕙 y dedicando su atención ⏯ a estar "esperando en el mostrador" 🕙 durante mucho tiempo.
@@ -240,7 +271,7 @@ Pero en este caso, si pudieras traer a los 8 ex cajeros / cocineros / ahora limp
En este escenario, cada uno de los limpiadores (incluido tú) sería un procesador, haciendo su parte del trabajo.
-Y como la mayor parte del tiempo de ejecución lo coge el trabajo real (en lugar de esperar), y el trabajo en un sistema lo realiza una CPU , a estos problemas se les llama "CPU bond".
+Y como la mayor parte del tiempo de ejecución lo coge el trabajo real (en lugar de esperar), y el trabajo en un sistema lo realiza una CPU , a estos problemas se les llama "CPU bound".
---
@@ -257,7 +288,7 @@ Por ejemplo:
Con **FastAPI** puedes aprovechar la concurrencia que es muy común para el desarrollo web (atractivo principal de NodeJS).
-Pero también puedes aprovechar los beneficios del paralelismo y el multiprocesamiento (tener múltiples procesos ejecutándose en paralelo) para cargas de trabajo **CPU bond** como las de los sistemas de Machine Learning.
+Pero también puedes aprovechar los beneficios del paralelismo y el multiprocesamiento (tener múltiples procesos ejecutándose en paralelo) para cargas de trabajo **CPU bound** como las de los sistemas de Machine Learning.
Eso, más el simple hecho de que Python es el lenguaje principal para **Data Science**, Machine Learning y especialmente Deep Learning, hacen de FastAPI una muy buena combinación para las API y aplicaciones web de Data Science / Machine Learning (entre muchas otras).
diff --git a/docs/id/docs/tutorial/index.md b/docs/id/docs/tutorial/index.md
index 8fec3c087e..b8ed96ae1f 100644
--- a/docs/id/docs/tutorial/index.md
+++ b/docs/id/docs/tutorial/index.md
@@ -10,9 +10,9 @@ Sehingga kamu dapat kembali lagi dan mencari apa yang kamu butuhkan dengan tepat
## Jalankan kode
-Semua blok-blok kode dapat dicopy dan digunakan langsung (Mereka semua sebenarnya adalah file python yang sudah teruji).
+Semua blok-blok kode dapat disalin dan digunakan langsung (Mereka semua sebenarnya adalah file python yang sudah teruji).
-Untuk menjalankan setiap contoh, copy kode ke file `main.py`, dan jalankan `uvicorn` dengan:
+Untuk menjalankan setiap contoh, salin kode ke file `main.py`, dan jalankan `uvicorn` dengan:
+
+---
+
+Теперь, когда нам известна разница между **процессом** и **программой**, давайте продолжим обсуждение развёртывания.
+
+## Настройки запуска приложения
+
+В большинстве случаев когда Вы создаёте веб-приложение, то желаете, чтоб оно **работало постоянно** и непрерывно, предоставляя клиентам доступ в любое время. Хотя иногда у Вас могут быть причины, чтоб оно запускалось только при определённых условиях.
+
+### Удалённый сервер
+
+Когда Вы настраиваете удалённый сервер (облачный сервер, виртуальную машину и т.п.), самое простое, что можно сделать, запустить Uvicorn (или его аналог) вручную, как Вы делаете при локальной разработке.
+
+Это рабочий способ и он полезен **во время разработки**.
+
+Но если Вы потеряете соединение с сервером, то не сможете отслеживать - работает ли всё ещё **запущенный Вами процесс**.
+
+И если сервер перезагрузится (например, после обновления или каких-то действий облачного провайдера), Вы скорее всего **этого не заметите**, чтобы снова запустить процесс вручную. Вследствие этого Ваш API останется мёртвым. 😱
+
+### Автоматический запуск программ
+
+Вероятно Вы пожелаете, чтоб Ваша серверная программа (такая как Uvicorn) стартовала автоматически при включении сервера, без **человеческого вмешательства** и всегда могла управлять Вашим API (так как Uvicorn запускает приложение FastAPI).
+
+### Отдельная программа
+
+Для этого у обычно используют отдельную программу, которая следит за тем, чтобы Ваши приложения запускались при включении сервера. Такой подход гарантирует, что другие компоненты или приложения также будут запущены, например, база данных
+
+### Примеры инструментов, управляющих запуском программ
+
+Вот несколько примеров, которые могут справиться с такой задачей:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker в режиме Swarm
+* Systemd
+* Supervisor
+* Использование услуг облачного провайдера
+* Прочие...
+
+Я покажу Вам некоторые примеры их использования в следующих главах.
+
+## Перезапуск
+
+Вы, вероятно, также пожелаете, чтоб Ваше приложение **перезапускалось**, если в нём произошёл сбой.
+
+### Мы ошибаемся
+
+Все люди совершают **ошибки**. Программное обеспечение почти *всегда* содержит **баги** спрятавшиеся в разных местах. 🐛
+
+И мы, будучи разработчиками, продолжаем улучшать код, когда обнаруживаем в нём баги или добавляем новый функционал (возможно, добавляя при этом баги 😅).
+
+### Небольшие ошибки обрабатываются автоматически
+
+Когда Вы создаёте свои API на основе FastAPI и допускаете в коде ошибку, то FastAPI обычно остановит её распространение внутри одного запроса, при обработке которого она возникла. 🛡
+
+Клиент получит ошибку **500 Internal Server Error** в ответ на свой запрос, но приложение не сломается и будет продолжать работать с последующими запросами.
+
+### Большие ошибки - Падение приложений
+
+Тем не менее, может случиться так, что ошибка вызовет **сбой всего приложения** или даже сбой в Uvicorn, а то и в самом Python. 💥
+
+Но мы всё ещё хотим, чтобы приложение **продолжало работать** несмотря на эту единственную ошибку, обрабатывая, как минимум, запросы к *операциям пути* не имеющим ошибок.
+
+### Перезапуск после падения
+
+Для случаев, когда ошибки приводят к сбою в запущенном **процессе**, Вам понадобится добавить компонент, который **перезапустит** процесс хотя бы пару раз...
+
+!!! tip "Заметка"
+ ... Если приложение падает сразу же после запуска, вероятно бесполезно его бесконечно перезапускать. Но полагаю, Вы заметите такое поведение во время разработки или, по крайней мере, сразу после развёртывания.
+
+ Так что давайте сосредоточимся на конкретных случаях, когда приложение может полностью выйти из строя, но всё ещё есть смысл его запустить заново.
+
+Возможно Вы захотите, чтоб был некий **внешний компонент**, ответственный за перезапуск Вашего приложения даже если уже не работает Uvicorn или Python. То есть ничего из того, что написано в Вашем коде внутри приложения, не может быть выполнено в принципе.
+
+### Примеры инструментов для автоматического перезапуска
+
+В большинстве случаев инструменты **запускающие программы при старте сервера** умеют **перезапускать** эти программы.
+
+В качестве примера можно взять те же:
+
+* Docker
+* Kubernetes
+* Docker Compose
+* Docker в режиме Swarm
+* Systemd
+* Supervisor
+* Использование услуг облачного провайдера
+* Прочие...
+
+## Запуск нескольких экземпляров приложения (Репликация) - Процессы и память
+
+Приложение FastAPI, управляемое серверной программой (такой как Uvicorn), запускается как **один процесс** и может обслуживать множество клиентов одновременно.
+
+Но часто Вам может понадобиться несколько одновременно работающих одинаковых процессов.
+
+### Множество процессов - Воркеры (Workers)
+
+Если количество Ваших клиентов больше, чем может обслужить один процесс (допустим, что виртуальная машина не слишком мощная), но при этом Вам доступно **несколько ядер процессора**, то Вы можете запустить **несколько процессов** одного и того же приложения параллельно и распределить запросы между этими процессами.
+
+**Несколько запущенных процессов** одной и той же API-программы часто называют **воркерами**.
+
+### Процессы и порты́
+
+Помните ли Вы, как на странице [Об HTTPS](./https.md){.internal-link target=_blank} мы обсуждали, что на сервере только один процесс может слушать одну комбинацию IP-адреса и порта?
+
+С тех пор ничего не изменилось.
+
+Соответственно, чтобы иметь возможность работать с **несколькими процессами** одновременно, должен быть **один процесс, прослушивающий порт** и затем каким-либо образом передающий данные каждому рабочему процессу.
+
+### У каждого процесса своя память
+
+Работающая программа загружает в память данные, необходимые для её работы, например, переменные содержащие модели машинного обучения или большие файлы. Каждая переменная **потребляет некоторое количество оперативной памяти (RAM)** сервера.
+
+Обычно процессы **не делятся памятью друг с другом**. Сие означает, что каждый работающий процесс имеет свои данные, переменные и свой кусок памяти. И если для выполнения Вашего кода процессу нужно много памяти, то **каждый такой же процесс** запущенный дополнительно, потребует такого же количества памяти.
+
+### Память сервера
+
+Допустим, что Ваш код загружает модель машинного обучения **размером 1 ГБ**. Когда Вы запустите своё API как один процесс, он займёт в оперативной памяти не менее 1 ГБ. А если Вы запустите **4 таких же процесса** (4 воркера), то каждый из них займёт 1 ГБ оперативной памяти. В результате Вашему API потребуется **4 ГБ оперативной памяти (RAM)**.
+
+И если Ваш удалённый сервер или виртуальная машина располагает только 3 ГБ памяти, то попытка загрузить в неё 4 ГБ данных вызовет проблемы. 🚨
+
+### Множество процессов - Пример
+
+В этом примере **менеджер процессов** запустит и будет управлять двумя **воркерами**.
+
+Менеджер процессов будет слушать определённый **сокет** (IP:порт) и передавать данные работающим процессам.
+
+Каждый из этих процессов будет запускать Ваше приложение для обработки полученного **запроса** и возвращения вычисленного **ответа** и они будут использовать оперативную память.
+
+
+
+Вы не могли бы получить такую поддержку редактора, если бы работали напрямую с `dict`, а не с моделями Pydantic.
+
+Но вы также не должны беспокоиться об этом, входящие словари автоматически конвертируются, а ваш вывод также автоматически преобразуется в формат JSON.
+
+## Тела запросов с произвольными словарями (`dict` )
+
+Вы также можете объявить тело запроса как `dict` с ключами определенного типа и значениями другого типа данных.
+
+Без необходимости знать заранее, какие значения являются допустимыми для имён полей/атрибутов (как это было бы в случае с моделями Pydantic).
+
+Это было бы полезно, если вы хотите получить ключи, которые вы еще не знаете.
+
+---
+
+Другой полезный случай - когда вы хотите чтобы ключи были другого типа данных, например, `int`.
+
+Именно это мы сейчас и увидим здесь.
+
+В этом случае вы принимаете `dict`, пока у него есть ключи типа `int` со значениями типа `float`:
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/body_nested_models/tutorial009_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/body_nested_models/tutorial009.py!}
+ ```
+
+!!! tip "Совет"
+ Имейте в виду, что JSON поддерживает только ключи типа `str`.
+
+ Но Pydantic обеспечивает автоматическое преобразование данных.
+
+ Это значит, что даже если пользователи вашего API могут отправлять только строки в качестве ключей, при условии, что эти строки содержат целые числа, Pydantic автоматический преобразует и валидирует эти данные.
+
+ А `dict`, с именем `weights`, который вы получите в качестве ответа Pydantic, действительно будет иметь ключи типа `int` и значения типа `float`.
+
+## Резюме
+
+С помощью **FastAPI** вы получаете максимальную гибкость, предоставляемую моделями Pydantic, сохраняя при этом простоту, краткость и элегантность вашего кода.
+
+И дополнительно вы получаете:
+
+* Поддержку редактора (автодополнение доступно везде!)
+* Преобразование данных (также известно как парсинг / сериализация)
+* Валидацию данных
+* Документацию схемы данных
+* Автоматическую генерацию документации
diff --git a/docs/ru/docs/tutorial/body.md b/docs/ru/docs/tutorial/body.md
new file mode 100644
index 0000000000..c03d40c3fb
--- /dev/null
+++ b/docs/ru/docs/tutorial/body.md
@@ -0,0 +1,165 @@
+# Тело запроса
+
+Когда вам необходимо отправить данные из клиента (допустим, браузера) в ваш API, вы отправляете их как **тело запроса**.
+
+Тело **запроса** --- это данные, отправляемые клиентом в ваш API. Тело **ответа** --- это данные, которые ваш API отправляет клиенту.
+
+Ваш API почти всегда отправляет тело **ответа**. Но клиентам не обязательно всегда отправлять тело **запроса**.
+
+Чтобы объявить тело **запроса**, необходимо использовать модели Pydantic, со всей их мощью и преимуществами.
+
+!!! info "Информация"
+ Чтобы отправить данные, необходимо использовать один из методов: `POST` (обычно), `PUT`, `DELETE` или `PATCH`.
+
+ Отправка тела с запросом `GET` имеет неопределенное поведение в спецификациях, тем не менее, оно поддерживается FastAPI только для очень сложных/экстремальных случаев использования.
+
+ Поскольку это не рекомендуется, интерактивная документация со Swagger UI не будет отображать информацию для тела при использовании метода GET, а промежуточные прокси-серверы могут не поддерживать такой вариант запроса.
+
+## Импортирование `BaseModel` из Pydantic
+
+Первое, что вам необходимо сделать, это импортировать `BaseModel` из пакета `pydantic`:
+
+```Python hl_lines="4"
+{!../../../docs_src/body/tutorial001.py!}
+```
+
+## Создание вашей собственной модели
+
+После этого вы описываете вашу модель данных как класс, наследующий от `BaseModel`.
+
+Используйте аннотации типов Python для всех атрибутов:
+
+```Python hl_lines="7-11"
+{!../../../docs_src/body/tutorial001.py!}
+```
+
+Также как и при описании параметров запроса, когда атрибут модели имеет значение по умолчанию, он является необязательным. Иначе он обязателен. Используйте `None`, чтобы сделать его необязательным без использования конкретных значений по умолчанию.
+
+Например, модель выше описывает вот такой JSON "объект" (или словарь Python):
+
+```JSON
+{
+ "name": "Foo",
+ "description": "An optional description",
+ "price": 45.2,
+ "tax": 3.5
+}
+```
+
+...поскольку `description` и `tax` являются необязательными (с `None` в качестве значения по умолчанию), вот такой JSON "объект" также подходит:
+
+```JSON
+{
+ "name": "Foo",
+ "price": 45.2
+}
+```
+
+## Объявление как параметра функции
+
+Чтобы добавить параметр к вашему *обработчику*, объявите его также, как вы объявляли параметры пути или параметры запроса:
+
+```Python hl_lines="18"
+{!../../../docs_src/body/tutorial001.py!}
+```
+
+...и укажите созданную модель в качестве типа параметра, `Item`.
+
+## Результаты
+
+Всего лишь с помощью аннотации типов Python, **FastAPI**:
+
+* Читает тело запроса как JSON.
+* Приводит к соответствующим типам (если есть необходимость).
+* Проверяет корректность данных.
+ * Если данные некорректны, будет возращена читаемая и понятная ошибка, показывающая что именно и в каком месте некорректно в данных.
+* Складывает полученные данные в параметр `item`.
+ * Поскольку внутри функции вы объявили его с типом `Item`, то теперь у вас есть поддержка со стороны редактора (автодополнение и т.п.) для всех атрибутов и их типов.
+* Генерирует декларативное описание модели в виде JSON Schema, так что вы можете его использовать где угодно, если это имеет значение для вашего проекта.
+* Эти схемы являются частью сгенерированной схемы OpenAPI и используются для автоматического документирования UI.
+
+## Автоматическое документирование
+
+Схема JSON ваших моделей будет частью сгенерированной схемы OpenAPI и будет отображена в интерактивной документации API:
+
+
+
+Также она будет указана в документации по API внутри каждой *операции пути*, в которой используются:
+
+
+
+## Поддержка редактора
+
+В вашем редакторе внутри вашей функции у вас будут подсказки по типам и автодополнение (это не будет работать, если вы получаете словарь вместо модели Pydantic):
+
+
+
+Также вы будете получать ошибки в случае несоответствия типов:
+
+
+
+Это не случайно, весь фреймворк построен вокруг такого дизайна.
+
+И это все тщательно протестировано еще на этапе разработки дизайна, до реализации, чтобы это работало со всеми редакторами.
+
+Для поддержки этого даже были внесены некоторые изменения в сам Pydantic.
+
+На всех предыдущих скриншотах используется Visual Studio Code.
+
+Но у вас будет такая же поддержка и с PyCharm, и вообще с любым редактором Python:
+
+
+
+!!! tip "Подсказка"
+ Если вы используете PyCharm в качестве редактора, то вам стоит попробовать плагин Pydantic PyCharm Plugin.
+
+ Он улучшает поддержку редактором моделей Pydantic в части:
+
+ * автодополнения,
+ * проверки типов,
+ * рефакторинга,
+ * поиска,
+ * инспектирования.
+
+## Использование модели
+
+Внутри функции вам доступны все атрибуты объекта модели напрямую:
+
+```Python hl_lines="21"
+{!../../../docs_src/body/tutorial002.py!}
+```
+
+## Тело запроса + параметры пути
+
+Вы можете одновременно объявлять параметры пути и тело запроса.
+
+**FastAPI** распознает, какие параметры функции соответствуют параметрам пути и должны быть **получены из пути**, а какие параметры функции, объявленные как модели Pydantic, должны быть **получены из тела запроса**.
+
+```Python hl_lines="17-18"
+{!../../../docs_src/body/tutorial003.py!}
+```
+
+## Тело запроса + параметры пути + параметры запроса
+
+Вы также можете одновременно объявить параметры для **пути**, **запроса** и **тела запроса**.
+
+**FastAPI** распознает каждый из них и возьмет данные из правильного источника.
+
+```Python hl_lines="18"
+{!../../../docs_src/body/tutorial004.py!}
+```
+
+Параметры функции распознаются следующим образом:
+
+* Если параметр также указан в **пути**, то он будет использоваться как параметр пути.
+* Если аннотация типа параметра содержит **примитивный тип** (`int`, `float`, `str`, `bool` и т.п.), он будет интерпретирован как параметр **запроса**.
+* Если аннотация типа параметра представляет собой **модель Pydantic**, он будет интерпретирован как параметр **тела запроса**.
+
+!!! note "Заметка"
+ FastAPI понимает, что значение параметра `q` не является обязательным, потому что имеет значение по умолчанию `= None`.
+
+ Аннотация `Optional` в `Optional[str]` не используется FastAPI, но помогает вашему редактору лучше понимать ваш код и обнаруживать ошибки.
+
+## Без Pydantic
+
+Если вы не хотите использовать модели Pydantic, вы все еще можете использовать параметры **тела запроса**. Читайте в документации раздел [Тело - Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
diff --git a/docs/ru/docs/tutorial/debugging.md b/docs/ru/docs/tutorial/debugging.md
new file mode 100644
index 0000000000..755d98cf20
--- /dev/null
+++ b/docs/ru/docs/tutorial/debugging.md
@@ -0,0 +1,112 @@
+# Отладка
+
+Вы можете подключить отладчик в своем редакторе, например, в Visual Studio Code или PyCharm.
+
+## Вызов `uvicorn`
+
+В вашем FastAPI приложении, импортируйте и вызовите `uvicorn` напрямую:
+
+```Python hl_lines="1 15"
+{!../../../docs_src/debugging/tutorial001.py!}
+```
+
+### Описание `__name__ == "__main__"`
+
+Главная цель использования `__name__ == "__main__"` в том, чтобы код выполнялся при запуске файла с помощью:
+
+
+
+---
+
+Если используете Pycharm, вы можете выполнить следующие шаги:
+
+* Открыть "Run" меню.
+* Выбрать опцию "Debug...".
+* Затем в появившемся контекстном меню.
+* Выбрать файл для отладки (в данном случае, `main.py`).
+
+Это запустит сервер с вашим **FastAPI** кодом, остановится на точках останова, и т.д.
+
+Вот как это может выглядеть:
+
+
diff --git a/docs/ru/docs/tutorial/first-steps.md b/docs/ru/docs/tutorial/first-steps.md
new file mode 100644
index 0000000000..b46f235bc7
--- /dev/null
+++ b/docs/ru/docs/tutorial/first-steps.md
@@ -0,0 +1,333 @@
+# Первые шаги
+
+Самый простой FastAPI файл может выглядеть так:
+
+```Python
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+Скопируйте в файл `main.py`.
+
+Запустите сервер в режиме реального времени:
+
+get операцию
+
+!!! info "`@decorator` Дополнительная информация"
+ Синтаксис `@something` в Python называется "декоратор".
+
+ Вы помещаете его над функцией. Как красивую декоративную шляпу (думаю, что оттуда и происходит этот термин).
+
+ "Декоратор" принимает функцию ниже и выполняет с ней какое-то действие.
+
+ В нашем случае, этот декоратор сообщает **FastAPI**, что функция ниже соответствует **пути** `/` и **операции** `get`.
+
+ Это и есть "**декоратор операции пути**".
+
+Можно также использовать операции:
+
+* `@app.post()`
+* `@app.put()`
+* `@app.delete()`
+
+И более экзотические:
+
+* `@app.options()`
+* `@app.head()`
+* `@app.patch()`
+* `@app.trace()`
+
+!!! tip "Подсказка"
+ Вы можете использовать каждую операцию (HTTP-метод) по своему усмотрению.
+
+ **FastAPI** не навязывает определенного значения для каждого метода.
+
+ Информация здесь представлена как рекомендация, а не требование.
+
+ Например, при использовании GraphQL обычно все действия выполняются только с помощью POST операций.
+
+### Шаг 4: определите **функцию операции пути**
+
+Вот "**функция операции пути**":
+
+* **путь**: `/`.
+* **операция**: `get`.
+* **функция**: функция ниже "декоратора" (ниже `@app.get("/")`).
+
+```Python hl_lines="7"
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+Это обычная Python функция.
+
+**FastAPI** будет вызывать её каждый раз при получении `GET` запроса к URL "`/`".
+
+В данном случае это асинхронная функция.
+
+---
+
+Вы также можете определить ее как обычную функцию вместо `async def`:
+
+```Python hl_lines="7"
+{!../../../docs_src/first_steps/tutorial003.py!}
+```
+
+!!! note "Технические детали"
+ Если не знаете в чём разница, посмотрите [Конкурентность: *"Нет времени?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
+
+### Шаг 5: верните результат
+
+```Python hl_lines="8"
+{!../../../docs_src/first_steps/tutorial001.py!}
+```
+
+Вы можете вернуть `dict`, `list`, отдельные значения `str`, `int` и т.д.
+
+Также можно вернуть модели Pydantic (рассмотрим это позже).
+
+Многие объекты и модели будут автоматически преобразованы в JSON (включая ORM). Пробуйте использовать другие объекты, которые предпочтительней для Вас, вероятно, они уже поддерживаются.
+
+## Резюме
+
+* Импортируем `FastAPI`.
+* Создаём экземпляр `app`.
+* Пишем **декоратор операции пути** (такой как `@app.get("/")`).
+* Пишем **функцию операции пути** (`def root(): ...`).
+* Запускаем сервер в режиме разработки (`uvicorn main:app --reload`).
diff --git a/docs/ru/docs/tutorial/index.md b/docs/ru/docs/tutorial/index.md
new file mode 100644
index 0000000000..4277a6c4f1
--- /dev/null
+++ b/docs/ru/docs/tutorial/index.md
@@ -0,0 +1,80 @@
+# Учебник - Руководство пользователя - Введение
+
+В этом руководстве шаг за шагом показано, как использовать **FastApi** с большинством его функций.
+
+Каждый раздел постепенно основывается на предыдущих, но он структурирован по отдельным темам, так что вы можете перейти непосредственно к конкретной теме для решения ваших конкретных потребностей в API.
+
+Он также создан для использования в качестве будущего справочника.
+
+Так что вы можете вернуться и посмотреть именно то, что вам нужно.
+
+## Запустите код
+
+Все блоки кода можно копировать и использовать напрямую (на самом деле это проверенные файлы Python).
+
+Чтобы запустить любой из примеров, скопируйте код в файл `main.py` и запустите `uvicorn` с параметрами:
+
+kwargs, даже если у них нет значений по умолчанию.
+
+```Python hl_lines="7"
+{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
+```
+
+### Лучше с `Annotated`
+
+Имейте в виду, что если вы используете `Annotated`, то, поскольку вы не используете значений по умолчанию для параметров функции, то у вас не возникнет подобной проблемы и вам не придётся использовать `*`.
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
+ ```
+
+## Валидация числовых данных: больше или равно
+
+С помощью `Query` и `Path` (и других классов, которые мы разберём позже) вы можете добавлять ограничения для числовых данных.
+
+В этом примере при указании `ge=1`, параметр `item_id` должен быть больше или равен `1` ("`g`reater than or `e`qual").
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ Рекомендуется использовать версию с `Annotated` если возможно.
+
+ ```Python hl_lines="8"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial004.py!}
+ ```
+
+## Валидация числовых данных: больше и меньше или равно
+
+То же самое применимо к:
+
+* `gt`: больше (`g`reater `t`han)
+* `le`: меньше или равно (`l`ess than or `e`qual)
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ Рекомендуется использовать версию с `Annotated` если возможно.
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial005.py!}
+ ```
+
+## Валидация числовых данных: числа с плавающей точкой, больше и меньше
+
+Валидация также применима к значениям типа `float`.
+
+В этом случае становится важной возможность добавить ограничение gt, вместо ge, поскольку в таком случае вы можете, например, создать ограничение, чтобы значение было больше `0`, даже если оно меньше `1`.
+
+Таким образом, `0.5` будет корректным значением. А `0.0` или `0` — нет.
+
+То же самое справедливо и для lt.
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="13"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="12"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
+ ```
+
+=== "Python 3.6+ без Annotated"
+
+ !!! tip "Подсказка"
+ Рекомендуется использовать версию с `Annotated` если возможно.
+
+ ```Python hl_lines="11"
+ {!> ../../../docs_src/path_params_numeric_validations/tutorial006.py!}
+ ```
+
+## Резюме
+
+С помощью `Query`, `Path` (и других классов, которые мы пока не затронули) вы можете добавлять метаданные и строковую валидацию тем же способом, как и в главе [Query-параметры и валидация строк](query-params-str-validations.md){.internal-link target=_blank}.
+
+А также вы можете добавить валидацию числовых данных:
+
+* `gt`: больше (`g`reater `t`han)
+* `ge`: больше или равно (`g`reater than or `e`qual)
+* `lt`: меньше (`l`ess `t`han)
+* `le`: меньше или равно (`l`ess than or `e`qual)
+
+!!! info "Информация"
+ `Query`, `Path` и другие классы, которые мы разберём позже, являются наследниками общего класса `Param`.
+
+ Все они используют те же параметры для дополнительной валидации и метаданных, которые вы видели ранее.
+
+!!! note "Технические детали"
+ `Query`, `Path` и другие "классы", которые вы импортируете из `fastapi`, на самом деле являются функциями, которые при вызове возвращают экземпляры одноимённых классов.
+
+ Объект `Query`, который вы импортируете, является функцией. И при вызове она возвращает экземпляр одноимённого класса `Query`.
+
+ Использование функций (вместо использования классов напрямую) нужно для того, чтобы ваш редактор не подсвечивал ошибки, связанные с их типами.
+
+ Таким образом вы можете использовать привычный вам редактор и инструменты разработки, не добавляя дополнительных конфигураций для игнорирования подобных ошибок.
diff --git a/docs/ru/docs/tutorial/path-params.md b/docs/ru/docs/tutorial/path-params.md
new file mode 100644
index 0000000000..55b498ef0a
--- /dev/null
+++ b/docs/ru/docs/tutorial/path-params.md
@@ -0,0 +1,251 @@
+# Path-параметры
+
+Вы можете определить "параметры" или "переменные" пути, используя синтаксис форматированных строк Python:
+
+```Python hl_lines="6-7"
+{!../../../docs_src/path_params/tutorial001.py!}
+```
+
+Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
+
+Если запустите этот пример и перейдёте по адресу: http://127.0.0.1:8000/items/foo, то увидите ответ:
+
+```JSON
+{"item_id":"foo"}
+```
+
+## Параметры пути с типами
+
+Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python.
+
+```Python hl_lines="7"
+{!../../../docs_src/path_params/tutorial002.py!}
+```
+
+Здесь, `item_id` объявлен типом `int`.
+
+!!! check "Заметка"
+ Это обеспечит поддержку редактора внутри функции (проверка ошибок, автодополнение и т.п.).
+
+## Преобразование данных
+
+Если запустите этот пример и перейдёте по адресу: http://127.0.0.1:8000/items/3, то увидите ответ:
+
+```JSON
+{"item_id":3}
+```
+
+!!! check "Заметка"
+ Обратите внимание на значение `3`, которое получила (и вернула) функция. Это целочисленный Python `int`, а не строка `"3"`.
+
+ Используя определения типов, **FastAPI** выполняет автоматический "парсинг" запросов.
+
+## Проверка данных
+
+Если откроете браузер по адресу http://127.0.0.1:8000/items/foo, то увидите интересную HTTP-ошибку:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ]
+}
+```
+
+из-за того, что параметр пути `item_id` имеет значение `"foo"`, которое не является типом `int`.
+
+Та же ошибка возникнет, если вместо `int` передать `float` , например: http://127.0.0.1:8000/items/4.2
+
+!!! check "Заметка"
+ **FastAPI** обеспечивает проверку типов, используя всё те же определения типов.
+
+ Обратите внимание, что в тексте ошибки явно указано место не прошедшее проверку.
+
+ Это очень полезно при разработке и отладке кода, который взаимодействует с API.
+
+## Документация
+
+И теперь, когда откроете браузер по адресу: http://127.0.0.1:8000/docs, то увидите вот такую автоматически сгенерированную документацию API:
+
+
+
+!!! check "Заметка"
+ Ещё раз, просто используя определения типов, **FastAPI** обеспечивает автоматическую интерактивную документацию (с интеграцией Swagger UI).
+
+ Обратите внимание, что параметр пути объявлен целочисленным.
+
+## Преимущества стандартизации, альтернативная документация
+
+Поскольку сгенерированная схема соответствует стандарту OpenAPI, её можно использовать со множеством совместимых инструментов.
+
+Именно поэтому, FastAPI сам предоставляет альтернативную документацию API (используя ReDoc), которую можно получить по адресу: http://127.0.0.1:8000/redoc.
+
+
+
+По той же причине, есть множество совместимых инструментов, включая инструменты генерации кода для многих языков.
+
+## Pydantic
+
+Вся проверка данных выполняется под капотом с помощью Pydantic. Поэтому вы можете быть уверены в качестве обработки данных.
+
+Вы можете использовать в аннотациях как простые типы данных, вроде `str`, `float`, `bool`, так и более сложные типы.
+
+Некоторые из них рассматриваются в следующих главах данного руководства.
+
+## Порядок имеет значение
+
+При создании *операций пути* можно столкнуться с ситуацией, когда путь является фиксированным.
+
+Например, `/users/me`. Предположим, что это путь для получения данных о текущем пользователе.
+
+У вас также может быть путь `/users/{user_id}`, чтобы получить данные о конкретном пользователе по его ID.
+
+Поскольку *операции пути* выполняются в порядке их объявления, необходимо, чтобы путь для `/users/me` был объявлен раньше, чем путь для `/users/{user_id}`:
+
+
+```Python hl_lines="6 11"
+{!../../../docs_src/path_params/tutorial003.py!}
+```
+
+Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`.
+
+Аналогично, вы не можете переопределить операцию с путем:
+
+```Python hl_lines="6 11"
+{!../../../docs_src/path_params/tutorial003b.py!}
+```
+
+Первый будет выполняться всегда, так как путь совпадает первым.
+
+## Предопределенные значения
+
+Что если нам нужно заранее определить допустимые *параметры пути*, которые *операция пути* может принимать? В таком случае можно использовать стандартное перечисление `Enum` Python.
+
+### Создание класса `Enum`
+
+Импортируйте `Enum` и создайте подкласс, который наследуется от `str` и `Enum`.
+
+Мы наследуемся от `str`, чтобы документация API могла понять, что значения должны быть типа `string` и отображалась правильно.
+
+Затем создайте атрибуты класса с фиксированными допустимыми значениями:
+
+```Python hl_lines="1 6-9"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+!!! info "Дополнительная информация"
+ Перечисления (enum) доступны в Python начиная с версии 3.4.
+
+!!! tip "Подсказка"
+ Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия моделей машинного обучения.
+
+### Определение *параметра пути*
+
+Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
+
+```Python hl_lines="16"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+### Проверьте документацию
+
+Поскольку доступные значения *параметра пути* определены заранее, интерактивная документация может наглядно их отображать:
+
+
+
+### Работа с *перечислениями* в Python
+
+Значение *параметра пути* будет *элементом перечисления*.
+
+#### Сравнение *элементов перечисления*
+
+Вы можете сравнить это значение с *элементом перечисления* класса `ModelName`:
+
+```Python hl_lines="17"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+#### Получение *значения перечисления*
+
+Можно получить фактическое значение (в данном случае - `str`) с помощью `model_name.value` или в общем случае `your_enum_member.value`:
+
+```Python hl_lines="20"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+!!! tip "Подсказка"
+ Значение `"lenet"` также можно получить с помощью `ModelName.lenet.value`.
+
+#### Возврат *элементов перечисления*
+
+Из *операции пути* можно вернуть *элементы перечисления*, даже вложенные в тело JSON (например в `dict`).
+
+Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту:
+
+```Python hl_lines="18 21 23"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+Вы отправите клиенту такой JSON-ответ:
+
+```JSON
+{
+ "model_name": "alexnet",
+ "message": "Deep Learning FTW!"
+}
+```
+
+## Path-параметры, содержащие пути
+
+Предположим, что есть *операция пути* с путем `/files/{file_path}`.
+
+Но вам нужно, чтобы `file_path` сам содержал *путь*, например, `home/johndoe/myfile.txt`.
+
+Тогда URL для этого файла будет такой: `/files/home/johndoe/myfile.txt`.
+
+### Поддержка OpenAPI
+
+OpenAPI не поддерживает способов объявления *параметра пути*, содержащего внутри *путь*, так как это может привести к сценариям, которые сложно определять и тестировать.
+
+Тем не менее это можно сделать в **FastAPI**, используя один из внутренних инструментов Starlette.
+
+Документация по-прежнему будет работать, хотя и не добавит никакой информации о том, что параметр должен содержать путь.
+
+### Конвертер пути
+
+Благодаря одной из опций Starlette, можете объявить *параметр пути*, содержащий *путь*, используя URL вроде:
+
+```
+/files/{file_path:path}
+```
+
+В этом случае `file_path` - это имя параметра, а часть `:path`, указывает, что параметр должен соответствовать любому *пути*.
+
+Можете использовать так:
+
+```Python hl_lines="6"
+{!../../../docs_src/path_params/tutorial004.py!}
+```
+
+!!! tip "Подсказка"
+ Возможно, вам понадобится, чтобы параметр содержал `/home/johndoe/myfile.txt` с ведущим слэшем (`/`).
+
+ В этом случае URL будет таким: `/files//home/johndoe/myfile.txt`, с двойным слэшем (`//`) между `files` и `home`.
+
+## Резюме
+Используя **FastAPI** вместе со стандартными объявлениями типов Python (короткими и интуитивно понятными), вы получаете:
+
+* Поддержку редактора (проверку ошибок, автозаполнение и т.п.)
+* "Парсинг" данных
+* Валидацию данных
+* Автоматическую документацию API с указанием типов параметров.
+
+И объявлять типы достаточно один раз.
+
+Это, вероятно, является главным заметным преимуществом **FastAPI** по сравнению с альтернативными фреймворками (кроме сырой производительности).
diff --git a/docs/ru/docs/tutorial/query-params.md b/docs/ru/docs/tutorial/query-params.md
new file mode 100644
index 0000000000..68333ec566
--- /dev/null
+++ b/docs/ru/docs/tutorial/query-params.md
@@ -0,0 +1,225 @@
+# Query-параметры
+
+Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры.
+
+```Python hl_lines="9"
+{!../../../docs_src/query_params/tutorial001.py!}
+```
+
+Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака `?` в URL-адресе, разделенные символами `&`.
+
+Например, в этом URL-адресе:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+...параметры запроса такие:
+
+* `skip`: со значением `0`
+* `limit`: со значением `10`
+
+Будучи частью URL-адреса, они "по умолчанию" являются строками.
+
+Но когда вы объявляете их с использованием аннотаций (в примере выше, как `int`), они конвертируются в указанный тип данных и проходят проверку на соответствие ему.
+
+Все те же правила, которые применяются к path-параметрам, также применяются и query-параметрам:
+
+* Поддержка от редактора кода (очевидно)
+* "Парсинг" данных
+* Проверка на соответствие данных (Валидация)
+* Автоматическая документация
+
+## Значения по умолчанию
+
+Поскольку query-параметры не являются фиксированной частью пути, они могут быть не обязательными и иметь значения по умолчанию.
+
+В примере выше значения по умолчанию равны `skip=0` и `limit=10`.
+
+Таким образом, результат перехода по URL-адресу:
+
+```
+http://127.0.0.1:8000/items/
+```
+
+будет таким же, как если перейти используя параметры по умолчанию:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+Но если вы введёте, например:
+
+```
+http://127.0.0.1:8000/items/?skip=20
+```
+
+Значения параметров в вашей функции будут:
+
+* `skip=20`: потому что вы установили это в URL-адресе
+* `limit=10`: т.к это было значение по умолчанию
+
+## Необязательные параметры
+
+Аналогично, вы можете объявлять необязательные query-параметры, установив их значение по умолчанию, равное `None`:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/query_params/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/query_params/tutorial002.py!}
+ ```
+
+В этом случае, параметр `q` будет не обязательным и будет иметь значение `None` по умолчанию.
+
+!!! Важно
+ Также обратите внимание, что **FastAPI** достаточно умён чтобы заметить, что параметр `item_id` является path-параметром, а `q` нет, поэтому, это параметр запроса.
+
+## Преобразование типа параметра запроса
+
+Вы также можете объявлять параметры с типом `bool`, которые будут преобразованы соответственно:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="7"
+ {!> ../../../docs_src/query_params/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="9"
+ {!> ../../../docs_src/query_params/tutorial003.py!}
+ ```
+
+В этом случае, если вы сделаете запрос:
+
+```
+http://127.0.0.1:8000/items/foo?short=1
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=True
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=true
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=on
+```
+
+или
+
+```
+http://127.0.0.1:8000/items/foo?short=yes
+```
+
+или в любом другом варианте написания (в верхнем регистре, с заглавной буквой, и т.п), внутри вашей функции параметр `short` будет иметь значение `True` типа данных `bool` . В противном случае - `False`.
+
+
+## Смешивание query-параметров и path-параметров
+
+Вы можете объявлять несколько query-параметров и path-параметров одновременно,**FastAPI** сам разберётся, что чем является.
+
+И вы не обязаны объявлять их в каком-либо определенном порядке.
+
+Они будут обнаружены по именам:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="6 8"
+ {!> ../../../docs_src/query_params/tutorial004_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="8 10"
+ {!> ../../../docs_src/query_params/tutorial004.py!}
+ ```
+
+## Обязательные query-параметры
+
+Когда вы объявляете значение по умолчанию для параметра, который не является path-параметром (в этом разделе, мы пока что познакомились только с path-параметрами), то это значение не является обязательным.
+
+Если вы не хотите задавать конкретное значение, но хотите сделать параметр необязательным, вы можете установить значение по умолчанию равным `None`.
+
+Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию:
+
+```Python hl_lines="6-7"
+{!../../../docs_src/query_params/tutorial005.py!}
+```
+
+Здесь параметр запроса `needy` является обязательным параметром с типом данных `str`.
+
+Если вы откроете в браузере URL-адрес, например:
+
+```
+http://127.0.0.1:8000/items/foo-item
+```
+
+...без добавления обязательного параметра `needy`, вы увидите подобного рода ошибку:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "query",
+ "needy"
+ ],
+ "msg": "field required",
+ "type": "value_error.missing"
+ }
+ ]
+}
+```
+
+Поскольку `needy` является обязательным параметром, вам необходимо указать его в URL-адресе:
+
+```
+http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
+```
+
+...это будет работать:
+
+```JSON
+{
+ "item_id": "foo-item",
+ "needy": "sooooneedy"
+}
+```
+
+Конечно, вы можете определить некоторые параметры как обязательные, некоторые - со значением по умполчанию, а некоторые - полностью необязательные:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="8"
+ {!> ../../../docs_src/query_params/tutorial006_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="10"
+ {!> ../../../docs_src/query_params/tutorial006.py!}
+ ```
+
+В этом примере, у нас есть 3 параметра запроса:
+
+* `needy`, обязательный `str`.
+* `skip`, типа `int` и со значением по умолчанию `0`.
+* `limit`, необязательный `int`.
+
+!!! подсказка
+ Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#predefined-values){.internal-link target=_blank}.
diff --git a/docs/ru/docs/tutorial/schema-extra-example.md b/docs/ru/docs/tutorial/schema-extra-example.md
new file mode 100644
index 0000000000..a0363b9ba7
--- /dev/null
+++ b/docs/ru/docs/tutorial/schema-extra-example.md
@@ -0,0 +1,189 @@
+# Объявление примера запроса данных
+
+Вы можете объявлять примеры данных, которые ваше приложение может получать.
+
+Вот несколько способов, как это можно сделать.
+
+## Pydantic `schema_extra`
+
+Вы можете объявить ключ `example` для модели Pydantic, используя класс `Config` и переменную `schema_extra`, как описано в Pydantic документации: Настройка схемы:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="13-21"
+ {!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="15-23"
+ {!> ../../../docs_src/schema_extra_example/tutorial001.py!}
+ ```
+
+Эта дополнительная информация будет включена в **JSON Schema** выходных данных для этой модели, и она будет использоваться в документации к API.
+
+!!! tip Подсказка
+ Вы можете использовать тот же метод для расширения JSON-схемы и добавления своей собственной дополнительной информации.
+
+ Например, вы можете использовать это для добавления дополнительной информации для пользовательского интерфейса в вашем веб-приложении и т.д.
+
+## Дополнительные аргументы поля `Field`
+
+При использовании `Field()` с моделями Pydantic, вы также можете объявлять дополнительную информацию для **JSON Schema**, передавая любые другие произвольные аргументы в функцию.
+
+Вы можете использовать это, чтобы добавить аргумент `example` для каждого поля:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="2 8-11"
+ {!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="4 10-13"
+ {!> ../../../docs_src/schema_extra_example/tutorial002.py!}
+ ```
+
+!!! warning Внимание
+ Имейте в виду, что эти дополнительные переданные аргументы не добавляют никакой валидации, только дополнительную информацию для документации.
+
+## Использование `example` и `examples` в OpenAPI
+
+При использовании любой из этих функций:
+
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
+
+вы также можете добавить аргумент, содержащий `example` или группу `examples` с дополнительной информацией, которая будет добавлена в **OpenAPI**.
+
+### Параметр `Body` с аргументом `example`
+
+Здесь мы передаём аргумент `example`, как пример данных ожидаемых в параметре `Body()`:
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="22-27"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="22-27"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="23-28"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip Заметка
+ Рекомендуется использовать версию с `Annotated`, если это возможно.
+
+ ```Python hl_lines="18-23"
+ {!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip Заметка
+ Рекомендуется использовать версию с `Annotated`, если это возможно.
+
+ ```Python hl_lines="20-25"
+ {!> ../../../docs_src/schema_extra_example/tutorial003.py!}
+ ```
+
+### Аргумент "example" в UI документации
+
+С любым из вышеуказанных методов это будет выглядеть так в `/docs`:
+
+
+
+### `Body` с аргументом `examples`
+
+В качестве альтернативы одному аргументу `example`, вы можете передавать `examples` используя тип данных `dict` с **несколькими примерами**, каждый из которых содержит дополнительную информацию, которая также будет добавлена в **OpenAPI**.
+
+Ключи `dict` указывают на каждый пример, а значения для каждого из них - на еще один тип `dict` с дополнительной информацией.
+
+Каждый конкретный пример типа `dict` в аргументе `examples` может содержать:
+
+* `summary`: Краткое описание для примера.
+* `description`: Полное описание, которое может содержать текст в формате Markdown.
+* `value`: Это конкретный пример, который отображается, например, в виде типа `dict`.
+* `externalValue`: альтернатива параметру `value`, URL-адрес, указывающий на пример. Хотя это может не поддерживаться таким же количеством инструментов разработки и тестирования API, как параметр `value`.
+
+=== "Python 3.10+"
+
+ ```Python hl_lines="23-49"
+ {!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!}
+ ```
+
+=== "Python 3.9+"
+
+ ```Python hl_lines="23-49"
+ {!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
+ ```
+
+=== "Python 3.6+"
+
+ ```Python hl_lines="24-50"
+ {!> ../../../docs_src/schema_extra_example/tutorial004_an.py!}
+ ```
+
+=== "Python 3.10+ non-Annotated"
+
+ !!! tip Заметка
+ Рекомендуется использовать версию с `Annotated`, если это возможно.
+
+ ```Python hl_lines="19-45"
+ {!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip Заметка
+ Рекомендуется использовать версию с `Annotated`, если это возможно.
+
+ ```Python hl_lines="21-47"
+ {!> ../../../docs_src/schema_extra_example/tutorial004.py!}
+ ```
+
+### Аргумент "examples" в UI документации
+
+С аргументом `examples`, добавленным в `Body()`, страница документации `/docs` будет выглядеть так:
+
+
+
+## Технические Детали
+
+!!! warning Внимание
+ Эти технические детали относятся к стандартам **JSON Schema** и **OpenAPI**.
+
+ Если предложенные выше идеи уже работают для вас, возможно этого будет достаточно и эти детали вам не потребуются, можете спокойно их пропустить.
+
+Когда вы добавляете пример внутрь модели Pydantic, используя `schema_extra` или `Field(example="something")`, этот пример добавляется в **JSON Schema** для данной модели Pydantic.
+
+И эта **JSON Schema** модели Pydantic включается в **OpenAPI** вашего API, а затем используется в UI документации.
+
+Поля `example` как такового не существует в стандартах **JSON Schema**. В последних версиях JSON-схемы определено поле `examples`, но OpenAPI 3.0.3 основан на более старой версии JSON-схемы, которая не имела поля `examples`.
+
+Таким образом, OpenAPI 3.0.3 определяет своё собственное поле `example` для модифицированной версии **JSON Schema**, которую он использует чтобы достичь той же цели (однако это именно поле `example`, а не `examples`), и именно это используется API в UI документации (с интеграцией Swagger UI).
+
+Итак, хотя поле `example` не является частью JSON-схемы, оно является частью настраиваемой версии JSON-схемы в OpenAPI, и именно это поле будет использоваться в UI документации.
+
+Однако, когда вы используете поле `example` или `examples` с любой другой функцией (`Query()`, `Body()`, и т.д.), эти примеры не добавляются в JSON-схему, которая описывает эти данные (даже в собственную версию JSON-схемы OpenAPI), они добавляются непосредственно в объявление *операции пути* в OpenAPI (вне частей OpenAPI, которые используют JSON-схему).
+
+Для функций `Path()`, `Query()`, `Header()`, и `Cookie()`, аргументы `example` или `examples` добавляются в определение OpenAPI, к объекту `Parameter Object` (в спецификации).
+
+И для функций `Body()`, `File()` и `Form()` аргументы `example` или `examples` аналогично добавляются в определение OpenAPI, к объекту `Request Body Object`, в поле `content` в объекте `Media Type Object` (в спецификации).
+
+С другой стороны, существует более новая версия OpenAPI: **3.1.0**, недавно выпущенная. Она основана на последней версии JSON-схемы и большинство модификаций из OpenAPI JSON-схемы удалены в обмен на новые возможности из последней версии JSON-схемы, так что все эти мелкие отличия устранены. Тем не менее, Swagger UI в настоящее время не поддерживает OpenAPI 3.1.0, поэтому пока лучше продолжать использовать вышеупомянутые методы.
diff --git a/docs/ru/docs/tutorial/static-files.md b/docs/ru/docs/tutorial/static-files.md
new file mode 100644
index 0000000000..ec09eb5a3a
--- /dev/null
+++ b/docs/ru/docs/tutorial/static-files.md
@@ -0,0 +1,40 @@
+# Статические Файлы
+
+Вы можете предоставлять статические файлы автоматически из директории, используя `StaticFiles`.
+
+## Использование `StaticFiles`
+
+* Импортируйте `StaticFiles`.
+* "Примонтируйте" экземпляр `StaticFiles()` с указанием определенной директории.
+
+```Python hl_lines="2 6"
+{!../../../docs_src/static_files/tutorial001.py!}
+```
+
+!!! заметка "Технические детали"
+ Вы также можете использовать `from starlette.staticfiles import StaticFiles`.
+
+ **FastAPI** предоставляет `starlette.staticfiles` под псевдонимом `fastapi.staticfiles`, просто для вашего удобства, как разработчика. Но на самом деле это берётся напрямую из библиотеки Starlette.
+
+### Что такое "Монтирование"
+
+"Монтирование" означает добавление полноценного "независимого" приложения в определенную директорию, которое затем обрабатывает все подпути.
+
+Это отличается от использования `APIRouter`, так как примонтированное приложение является полностью независимым.
+OpenAPI и документация из вашего главного приложения не будет содержать ничего из примонтированного приложения, и т.д.
+
+Вы можете прочитать больше об этом в **Расширенном руководстве пользователя**.
+
+## Детали
+
+Первый параметр `"/static"` относится к подпути, по которому это "подприложение" будет "примонтировано". Таким образом, любой путь начинающийся со `"/static"` будет обработан этим приложением.
+
+Параметр `directory="static"` относится к имени директории, которая содержит ваши статические файлы.
+
+`name="static"` даёт имя маршруту, которое может быть использовано внутри **FastAPI**.
+
+Все эти параметры могут отличаться от "`static`", настройте их в соответствии с вашими нуждами и конкретными деталями вашего собственного приложения.
+
+## Больше информации
+
+Для получения дополнительной информации о деталях и настройках ознакомьтесь с Документацией Starlette о статических файлах.
diff --git a/docs/ru/mkdocs.yml b/docs/ru/mkdocs.yml
index 93fae36ced..ecd3aead12 100644
--- a/docs/ru/mkdocs.yml
+++ b/docs/ru/mkdocs.yml
@@ -67,17 +67,28 @@ nav:
- fastapi-people.md
- python-types.md
- Учебник - руководство пользователя:
+ - tutorial/index.md
+ - tutorial/first-steps.md
+ - tutorial/path-params.md
- tutorial/query-params-str-validations.md
+ - tutorial/path-params-numeric-validations.md
- tutorial/body-fields.md
- tutorial/background-tasks.md
- tutorial/extra-data-types.md
- tutorial/cookie-params.md
- tutorial/testing.md
- tutorial/response-status-code.md
+ - tutorial/query-params.md
+ - tutorial/body-multiple-params.md
+ - tutorial/static-files.md
+ - tutorial/debugging.md
+ - tutorial/schema-extra-example.md
+ - tutorial/body-nested-models.md
- async.md
- Развёртывание:
- deployment/index.md
- deployment/versions.md
+ - deployment/concepts.md
- deployment/https.md
- deployment/manually.md
- project-generation.md
diff --git a/docs/zh/docs/advanced/response-change-status-code.md b/docs/zh/docs/advanced/response-change-status-code.md
new file mode 100644
index 0000000000..a289cf2017
--- /dev/null
+++ b/docs/zh/docs/advanced/response-change-status-code.md
@@ -0,0 +1,31 @@
+# 响应 - 更改状态码
+
+你可能之前已经了解到,你可以设置默认的[响应状态码](../tutorial/response-status-code.md){.internal-link target=_blank}。
+
+但在某些情况下,你需要返回一个不同于默认值的状态码。
+
+## 使用场景
+
+例如,假设你想默认返回一个HTTP状态码为“OK”`200`。
+
+但如果数据不存在,你想创建它,并返回一个HTTP状态码为“CREATED”`201`。
+
+但你仍然希望能够使用`response_model`过滤和转换你返回的数据。
+
+对于这些情况,你可以使用一个`Response`参数。
+
+## 使用 `Response` 参数
+
+你可以在你的*路径操作函数*中声明一个`Response`类型的参数(就像你可以为cookies和头部做的那样)。
+
+然后你可以在这个*临时*响应对象中设置`status_code`。
+
+```Python hl_lines="1 9 12"
+{!../../../docs_src/response_change_status_code/tutorial001.py!}
+```
+
+然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。
+
+**FastAPI**将使用这个临时响应来提取状态码(也包括cookies和头部),并将它们放入包含你返回的值的最终响应中,该响应由任何`response_model`过滤。
+
+你也可以在依赖项中声明`Response`参数,并在其中设置状态码。但请注意,最后设置的状态码将会生效。
diff --git a/docs/zh/docs/advanced/response-headers.md b/docs/zh/docs/advanced/response-headers.md
new file mode 100644
index 0000000000..85dab15ac0
--- /dev/null
+++ b/docs/zh/docs/advanced/response-headers.md
@@ -0,0 +1,39 @@
+# 响应头
+
+## 使用 `Response` 参数
+
+你可以在你的*路径操作函数*中声明一个`Response`类型的参数(就像你可以为cookies做的那样)。
+
+然后你可以在这个*临时*响应对象中设置头部。
+```Python hl_lines="1 7-8"
+{!../../../docs_src/response_headers/tutorial002.py!}
+```
+
+然后你可以像平常一样返回任何你需要的对象(例如一个`dict`或者一个数据库模型)。如果你声明了一个`response_model`,它仍然会被用来过滤和转换你返回的对象。
+
+**FastAPI**将使用这个临时响应来提取头部(也包括cookies和状态码),并将它们放入包含你返回的值的最终响应中,该响应由任何`response_model`过滤。
+
+你也可以在依赖项中声明`Response`参数,并在其中设置头部(和cookies)。
+
+## 直接返回 `Response`
+
+你也可以在直接返回`Response`时添加头部。
+
+按照[直接返回响应](response-directly.md){.internal-link target=_blank}中所述创建响应,并将头部作为附加参数传递:
+```Python hl_lines="10-12"
+{!../../../docs_src/response_headers/tutorial001.py!}
+```
+
+
+!!! 注意 "技术细节"
+ 你也可以使用`from starlette.responses import Response`或`from starlette.responses import JSONResponse`。
+
+ **FastAPI**提供了与`fastapi.responses`相同的`starlette.responses`,只是为了方便开发者。但是,大多数可用的响应都直接来自Starlette。
+
+ 由于`Response`经常用于设置头部和cookies,因此**FastAPI**还在`fastapi.Response`中提供了它。
+
+## 自定义头部
+
+请注意,可以使用'X-'前缀添加自定义专有头部。
+
+但是,如果你有自定义头部,你希望浏览器中的客户端能够看到它们,你需要将它们添加到你的CORS配置中(在[CORS(跨源资源共享)](../tutorial/cors.md){.internal-link target=_blank}中阅读更多),使用在Starlette的CORS文档中记录的`expose_headers`参数。
diff --git a/docs/zh/docs/contributing.md b/docs/zh/docs/contributing.md
index 36c3631c44..4ebd673150 100644
--- a/docs/zh/docs/contributing.md
+++ b/docs/zh/docs/contributing.md
@@ -97,7 +97,7 @@ $ python -m venv env