]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Update translations for ru (update-outdated) (#14909)
authorMotov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Thu, 12 Feb 2026 19:57:34 +0000 (20:57 +0100)
committerGitHub <noreply@github.com>
Thu, 12 Feb 2026 19:57:34 +0000 (20:57 +0100)
* Update all

* Reflect latest changes in `docs/en/docs/tutorial/security/oauth2-jwt.md`

90 files changed:
docs/ru/docs/advanced/additional-responses.md
docs/ru/docs/advanced/advanced-dependencies.md
docs/ru/docs/advanced/advanced-python-types.md [new file with mode: 0644]
docs/ru/docs/advanced/async-tests.md
docs/ru/docs/advanced/behind-a-proxy.md
docs/ru/docs/advanced/custom-response.md
docs/ru/docs/advanced/dataclasses.md
docs/ru/docs/advanced/events.md
docs/ru/docs/advanced/generate-clients.md
docs/ru/docs/advanced/middleware.md
docs/ru/docs/advanced/openapi-webhooks.md
docs/ru/docs/advanced/path-operation-advanced-configuration.md
docs/ru/docs/advanced/response-change-status-code.md
docs/ru/docs/advanced/response-cookies.md
docs/ru/docs/advanced/response-directly.md
docs/ru/docs/advanced/response-headers.md
docs/ru/docs/advanced/security/http-basic-auth.md
docs/ru/docs/advanced/settings.md
docs/ru/docs/advanced/sub-applications.md
docs/ru/docs/advanced/templates.md
docs/ru/docs/advanced/testing-events.md
docs/ru/docs/advanced/testing-websockets.md
docs/ru/docs/advanced/using-request-directly.md
docs/ru/docs/advanced/websockets.md
docs/ru/docs/advanced/wsgi.md
docs/ru/docs/alternatives.md
docs/ru/docs/async.md
docs/ru/docs/benchmarks.md
docs/ru/docs/deployment/concepts.md
docs/ru/docs/deployment/docker.md
docs/ru/docs/deployment/https.md
docs/ru/docs/deployment/index.md
docs/ru/docs/deployment/versions.md
docs/ru/docs/environment-variables.md
docs/ru/docs/fastapi-cli.md
docs/ru/docs/features.md
docs/ru/docs/history-design-future.md
docs/ru/docs/how-to/authentication-error-status-code.md
docs/ru/docs/how-to/conditional-openapi.md
docs/ru/docs/how-to/configure-swagger-ui.md
docs/ru/docs/how-to/custom-docs-ui-assets.md
docs/ru/docs/how-to/extending-openapi.md
docs/ru/docs/how-to/graphql.md
docs/ru/docs/how-to/index.md
docs/ru/docs/index.md
docs/ru/docs/project-generation.md
docs/ru/docs/python-types.md
docs/ru/docs/tutorial/background-tasks.md
docs/ru/docs/tutorial/bigger-applications.md
docs/ru/docs/tutorial/body-multiple-params.md
docs/ru/docs/tutorial/body-nested-models.md
docs/ru/docs/tutorial/body.md
docs/ru/docs/tutorial/cookie-param-models.md
docs/ru/docs/tutorial/cookie-params.md
docs/ru/docs/tutorial/cors.md
docs/ru/docs/tutorial/debugging.md
docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md
docs/ru/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
docs/ru/docs/tutorial/dependencies/global-dependencies.md
docs/ru/docs/tutorial/dependencies/index.md
docs/ru/docs/tutorial/dependencies/sub-dependencies.md
docs/ru/docs/tutorial/encoder.md
docs/ru/docs/tutorial/extra-models.md
docs/ru/docs/tutorial/first-steps.md
docs/ru/docs/tutorial/handling-errors.md
docs/ru/docs/tutorial/metadata.md
docs/ru/docs/tutorial/middleware.md
docs/ru/docs/tutorial/path-operation-configuration.md
docs/ru/docs/tutorial/path-params-numeric-validations.md
docs/ru/docs/tutorial/path-params.md
docs/ru/docs/tutorial/query-param-models.md
docs/ru/docs/tutorial/query-params-str-validations.md
docs/ru/docs/tutorial/query-params.md
docs/ru/docs/tutorial/request-files.md
docs/ru/docs/tutorial/request-form-models.md
docs/ru/docs/tutorial/request-forms-and-files.md
docs/ru/docs/tutorial/request-forms.md
docs/ru/docs/tutorial/response-model.md
docs/ru/docs/tutorial/response-status-code.md
docs/ru/docs/tutorial/schema-extra-example.md
docs/ru/docs/tutorial/security/first-steps.md
docs/ru/docs/tutorial/security/get-current-user.md
docs/ru/docs/tutorial/security/index.md
docs/ru/docs/tutorial/security/oauth2-jwt.md
docs/ru/docs/tutorial/security/simple-oauth2.md
docs/ru/docs/tutorial/sql-databases.md
docs/ru/docs/tutorial/static-files.md
docs/ru/docs/tutorial/testing.md
docs/ru/docs/virtual-environments.md

index fca4f072da44965961f9e17b3d7de9dc8d354241..ca36ba20e336c238a0a74e92dee119d9f392271b 100644 (file)
@@ -26,7 +26,7 @@
 
 Например, чтобы объявить ещё один ответ со статус-кодом `404` и Pydantic-моделью `Message`, можно написать:
 
-{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
 
 /// note | Примечание
 
 
 А также ответ со статус-кодом `200`, который использует ваш `response_model`, но включает пользовательский `example`:
 
-{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
 
 Всё это будет объединено и включено в ваш OpenAPI и отображено в документации API:
 
index fb2643cd5c55d0649a6a149999a36ed83257695c..686a0cf91e21f337875f89caed1f69daf86d04df 100644 (file)
@@ -18,7 +18,7 @@
 
 Для этого объявляем метод `__call__`:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
 
 В этом случае именно `__call__` **FastAPI** использует для проверки дополнительных параметров и подзависимостей, и именно он будет вызван, чтобы позже передать значение параметру в вашей *функции-обработчике пути*.
 
@@ -26,7 +26,7 @@
 
 Теперь мы можем использовать `__init__`, чтобы объявить параметры экземпляра, с помощью которых будем «параметризовать» зависимость:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
 
 В этом случае **FastAPI** вовсе не трогает `__init__` и не зависит от него — мы используем его напрямую в нашем коде.
 
@@ -34,7 +34,7 @@
 
 Мы можем создать экземпляр этого класса так:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
 
 Так мы «параметризуем» нашу зависимость: теперь внутри неё хранится "bar" в атрибуте `checker.fixed_content`.
 
@@ -50,7 +50,7 @@ checker(q="somequery")
 
 …и передаст возвращённое значение как значение зависимости в параметр `fixed_content_included` нашей *функции-обработчика пути*:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
 
 /// tip | Совет
 
diff --git a/docs/ru/docs/advanced/advanced-python-types.md b/docs/ru/docs/advanced/advanced-python-types.md
new file mode 100644 (file)
index 0000000..62dcf8c
--- /dev/null
@@ -0,0 +1,61 @@
+# Продвинутые типы Python { #advanced-python-types }
+
+Ниже несколько дополнительных идей, которые могут быть полезны при работе с типами Python.
+
+## Использование `Union` или `Optional` { #using-union-or-optional }
+
+Если по какой-то причине ваш код не может использовать `|`, например, если это не аннотация типов, а что-то вроде `response_model=`, вместо вертикальной черты (`|`) можно использовать `Union` из `typing`.
+
+Например, вы можете объявить, что значение может быть `str` или `None`:
+
+```python
+from typing import Union
+
+
+def say_hi(name: Union[str, None]):
+        print(f"Hi {name}!")
+```
+
+В `typing` также есть сокращение, чтобы объявить, что значение может быть `None`, — `Optional`.
+
+Вот совет с моей очень субъективной точки зрения:
+
+- 🚨 Избегайте использования `Optional[SomeType]`
+- Вместо этого ✨ используйте **`Union[SomeType, None]`** ✨.
+
+Оба варианта эквивалентны и под капотом это одно и то же, но я бы рекомендовал `Union` вместо `Optional`, потому что слово «optional» может наводить на мысль, что значение необязательное, тогда как на самом деле это означает «значение может быть `None`», даже если оно не является необязательным и по-прежнему требуется.
+
+По-моему, `Union[SomeType, None]` более явно передаёт смысл.
+
+Речь только о словах и названиях. Но эти слова могут влиять на то, как вы и ваша команда думаете о коде.
+
+В качестве примера возьмём такую функцию:
+
+```python
+from typing import Optional
+
+
+def say_hi(name: Optional[str]):
+    print(f"Hey {name}!")
+```
+
+Параметр `name` объявлен как `Optional[str]`, но он не является необязательным: вы не можете вызвать функцию без этого параметра:
+
+```Python
+say_hi()  # О нет, это вызывает ошибку! 😱
+```
+
+Параметр `name` по-прежнему обязателен (не «optional»), так как у него нет значения по умолчанию. При этом `name` принимает `None` в качестве значения:
+
+```Python
+say_hi(name=None)  # Это работает, None допустим 🎉
+```
+
+Хорошая новость: в большинстве случаев вы сможете просто использовать `|` для объявления объединений типов:
+
+```python
+def say_hi(name: str | None):
+    print(f"Hey {name}!")
+```
+
+Так что обычно вам не о чем переживать из‑за названий вроде `Optional` и `Union`. 😎
index e689704066adb873062a030b0b5c635a4f83832c..52939c25596febd87678e434744837993428ae20 100644 (file)
 
 Файл `main.py`:
 
-{* ../../docs_src/async_tests/app_a_py39/main.py *}
+{* ../../docs_src/async_tests/app_a_py310/main.py *}
 
 Файл `test_main.py` содержит тесты для `main.py`, теперь он может выглядеть так:
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
 
 ## Запуск тестов { #run-it }
 
@@ -56,7 +56,7 @@ $ pytest
 
 Маркер `@pytest.mark.anyio` говорит pytest, что тестовая функция должна быть вызвана асинхронно:
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
 
 /// tip | Подсказка
 
@@ -66,7 +66,7 @@ $ pytest
 
 Затем мы можем создать `AsyncClient` со ссылкой на приложение и посылать асинхронные запросы, используя `await`.
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
 
 Это эквивалентно следующему:
 
@@ -94,6 +94,6 @@ response = client.get('/')
 
 /// tip | Подсказка
 
-Если вы столкнулись с `RuntimeError: Task attached to a different loop` при вызове асинхронных функций в ваших тестах (например, при использовании <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB's MotorClient</a>), то не забывайте инициализировать объекты, которым нужен цикл событий (event loop), только внутри асинхронных функций, например, в `'@app.on_event("startup")` callback.
+Если вы столкнулись с `RuntimeError: Task attached to a different loop` при вызове асинхронных функций в ваших тестах (например, при использовании <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB's MotorClient</a>), то не забывайте инициализировать объекты, которым нужен цикл событий (event loop), только внутри асинхронных функций, например, в `@app.on_event("startup")` callback.
 
 ///
index f78da01a095249224a929a52131d185de6cd9f61..ec75ed369889e94718d8064764cf503c28ff72b4 100644 (file)
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
 
 Например, вы объявили операцию пути `/items/`:
 
-{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
 
 Если клиент обратится к `/items`, по умолчанию произойдёт редирект на `/items/`.
 
@@ -115,7 +115,7 @@ sequenceDiagram
 
 Хотя весь ваш код написан с расчётом, что путь один — `/app`.
 
-{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
 
 Прокси будет «обрезать» префикс пути на лету перед передачей запроса на сервер приложения (скорее всего Uvicorn, запущенный через FastAPI CLI), поддерживая у вашего приложения иллюзию, что его обслуживают по `/app`, чтобы вам не пришлось менять весь код и добавлять префикс `/api/v1`.
 
@@ -193,7 +193,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Здесь мы добавляем его в сообщение лишь для демонстрации.
 
-{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
 
 Затем, если вы запустите Uvicorn так:
 
@@ -220,7 +220,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Если нет возможности передать опцию командной строки `--root-path` (или аналог), вы можете указать параметр `root_path` при создании приложения FastAPI:
 
-{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
 
 Передача `root_path` в `FastAPI` эквивалентна опции командной строки `--root-path` для Uvicorn или Hypercorn.
 
@@ -241,17 +241,17 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Uvicorn ожидает, что прокси обратится к нему по `http://127.0.0.1:8000/app`, а уже задача прокси — добавить сверху префикс `/api/v1`.
 
-## Ð\9e Ð¿Ñ\80окÑ\81и Ñ\81 Ñ\83Ñ\80езаннÑ\8bм Ð¿Ñ\80еÑ\84икÑ\81ом пути { #about-proxies-with-a-stripped-path-prefix }
+## Ð\9e Ð¿Ñ\80окÑ\81и Ñ\81 Ñ\84Ñ\83нкÑ\86ией Ñ\83далениÑ\8f Ð¿Ñ\80еÑ\84икÑ\81а пути { #about-proxies-with-a-stripped-path-prefix }
 
\9fомниÑ\82е, Ñ\87Ñ\82о Ð¿Ñ\80окÑ\81и Ñ\81 Ñ\83Ñ\80езаннÑ\8bм Ð¿Ñ\80еÑ\84икÑ\81ом пути — лишь один из вариантов настройки.
\9fомниÑ\82е, Ñ\87Ñ\82о Ð¿Ñ\80окÑ\81и Ñ\81 Ñ\84Ñ\83нкÑ\86ией Ñ\83далениÑ\8f Ð¿Ñ\80еÑ\84икÑ\81а пути — лишь один из вариантов настройки.
 
\92о Ð¼Ð½Ð¾Ð³Ð¸Ñ\85 Ñ\81лÑ\83Ñ\87аÑ\8fÑ\85 Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e Ð¿Ñ\80окÑ\81и Ð±Ñ\83деÑ\82 Ð±ÐµÐ· Ñ\83Ñ\80езанного префикса пути.
\92о Ð¼Ð½Ð¾Ð³Ð¸Ñ\85 Ñ\81лÑ\83Ñ\87аÑ\8fÑ\85 Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e Ð¿Ñ\80окÑ\81и Ð±Ñ\83деÑ\82 Ð±ÐµÐ· Ñ\84Ñ\83нкÑ\86ии Ñ\83далениÑ\8f префикса пути.
 
\92 Ñ\82аком Ñ\81лÑ\83Ñ\87ае (без Ñ\83Ñ\80езанного Ð¿Ñ\80еÑ\84икÑ\81а) прокси слушает, например, по адресу `https://myawesomeapp.com`, и если браузер идёт на `https://myawesomeapp.com/api/v1/app`, а ваш сервер (например, Uvicorn) слушает на `http://127.0.0.1:8000`, то прокси (без урезанного префикса) обратится к Uvicorn по тому же пути: `http://127.0.0.1:8000/api/v1/app`.
\92 Ñ\82аком Ñ\81лÑ\83Ñ\87ае (без Ñ\84Ñ\83нкÑ\86ии Ñ\83далениÑ\8f Ð¿Ñ\80еÑ\84икÑ\81а Ð¿Ñ\83Ñ\82и) прокси слушает, например, по адресу `https://myawesomeapp.com`, и если браузер идёт на `https://myawesomeapp.com/api/v1/app`, а ваш сервер (например, Uvicorn) слушает на `http://127.0.0.1:8000`, то прокси (без урезанного префикса) обратится к Uvicorn по тому же пути: `http://127.0.0.1:8000/api/v1/app`.
 
 ## Локальное тестирование с Traefik { #testing-locally-with-traefik }
 
\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð»ÐµÐ³ÐºÐ¾ Ð¿Ð¾Ñ\8dкÑ\81пеÑ\80именÑ\82иÑ\80оваÑ\82Ñ\8c Ð»Ð¾ÐºÐ°Ð»Ñ\8cно Ñ\81 Ñ\83Ñ\80езаннÑ\8bм Ð¿Ñ\80еÑ\84икÑ\81ом пути, используя <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>.
\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð»ÐµÐ³ÐºÐ¾ Ð¿Ð¾Ñ\8dкÑ\81пеÑ\80именÑ\82иÑ\80оваÑ\82Ñ\8c Ð»Ð¾ÐºÐ°Ð»Ñ\8cно Ñ\81 Ñ\84Ñ\83нкÑ\86ией Ñ\83далениÑ\8f Ð¿Ñ\80еÑ\84икÑ\81а пути, используя <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>.
 
 <a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">Скачайте Traefik</a> — это один бинарный файл; распакуйте архив и запустите его прямо из терминала.
 
@@ -400,7 +400,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Например:
 
-{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
 
 Будет сгенерирована схема OpenAPI примерно такая:
 
@@ -455,7 +455,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Если вы не хотите, чтобы FastAPI добавлял автоматический сервер, используя `root_path`, укажите параметр `root_path_in_servers=False`:
 
-{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
 
 и тогда этот сервер не будет добавлен в схему OpenAPI.
 
index 49550b49ffa048208e23d84191282e41ac9ef715..b9f91373da21fba5180e642bbef6345954b3cb06 100644 (file)
@@ -30,7 +30,7 @@
 
 Но если вы уверены, что содержимое, которое вы возвращаете, **сериализуемо в JSON**, вы можете передать его напрямую в класс ответа и избежать дополнительных накладных расходов, которые FastAPI понёс бы, пропуская возвращаемое содержимое через `jsonable_encoder` перед передачей в класс ответа.
 
-{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
 
 /// info | Информация
 
@@ -55,7 +55,7 @@
 - Импортируйте `HTMLResponse`.
 - Передайте `HTMLResponse` в параметр `response_class` вашего декоратора операции пути.
 
-{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
 
 /// info | Информация
 
 
 Тот же пример сверху, возвращающий `HTMLResponse`, может выглядеть так:
 
-{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
 
 /// warning | Предупреждение
 
-`Response`, Ð²Ð¾Ð·Ð²Ñ\80аÑ\89Ñ\91ннÑ\8bй Ð½Ð°Ð¿Ñ\80Ñ\8fмÑ\83Ñ\8e Ð²Ð°Ñ\88ей Ñ\84Ñ\83нкÑ\86ией-обÑ\80абоÑ\82Ñ\87иком Ð¿Ñ\83Ñ\82и, Ð½Ðµ Ð±Ñ\83деÑ\82 Ð·Ð°Ð´Ð¾ÐºÑ\83менÑ\82иÑ\80ован Ð² OpenAPI (напÑ\80имеÑ\80, `Content-Type` Ð½Ð½Ðµ Ð±Ñ\83деÑ\82 Ð·Ð°Ð´Ð¾ÐºÑ\83менÑ\82иÑ\80ова) и не будет виден в автоматически сгенерированной интерактивной документации.
+`Response`, Ð²Ð¾Ð·Ð²Ñ\80аÑ\89Ñ\91ннÑ\8bй Ð½Ð°Ð¿Ñ\80Ñ\8fмÑ\83Ñ\8e Ð²Ð°Ñ\88ей Ñ\84Ñ\83нкÑ\86ией-обÑ\80абоÑ\82Ñ\87иком Ð¿Ñ\83Ñ\82и, Ð½Ðµ Ð±Ñ\83деÑ\82 Ð·Ð°Ð´Ð¾ÐºÑ\83менÑ\82иÑ\80ован Ð² OpenAPI (напÑ\80имеÑ\80, `Content-Type` Ð½Ðµ Ð±Ñ\83деÑ\82 Ð·Ð°Ð´Ð¾ÐºÑ\83менÑ\82иÑ\80ован) и не будет виден в автоматически сгенерированной интерактивной документации.
 
 ///
 
 /// info | Информация
 
-РазÑ\83мееÑ\82Ñ\81Ñ\8f, Ñ\84акÑ\82иÑ\87еÑ\81кие заголовок `Content-Type`, статус-код и т.д. возьмутся из объекта `Response`, который вы вернули.
+РазÑ\83мееÑ\82Ñ\81Ñ\8f, Ñ\84акÑ\82иÑ\87еÑ\81кий заголовок `Content-Type`, статус-код и т.д. возьмутся из объекта `Response`, который вы вернули.
 
 ///
 
@@ -97,7 +97,7 @@
 
 Например, это может быть что-то вроде:
 
-{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
 
 В этом примере функция `generate_html_response()` уже генерирует и возвращает `Response` вместо возврата HTML в `str`.
 
 
 FastAPI (фактически Starlette) автоматически добавит заголовок Content-Length. Также будет добавлен заголовок Content-Type, основанный на `media_type` и с добавлением charset для текстовых типов.
 
-{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
 
 ### `HTMLResponse` { #htmlresponse }
 
@@ -146,7 +146,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 Принимает текст или байты и возвращает ответ в виде простого текста.
 
-{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
 
 ### `JSONResponse` { #jsonresponse }
 
@@ -180,7 +180,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
 
 /// tip | Совет
 
@@ -194,13 +194,13 @@ FastAPI (фактически Starlette) автоматически добави
 
 Вы можете вернуть `RedirectResponse` напрямую:
 
-{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
 
 ---
 
 Или можно использовать его в параметре `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
 
 Если вы сделаете так, то сможете возвращать URL напрямую из своей функции-обработчика пути.
 
@@ -210,13 +210,13 @@ FastAPI (фактически Starlette) автоматически добави
 
 Также вы можете использовать параметр `status_code` в сочетании с параметром `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
 
 ### `StreamingResponse` { #streamingresponse }
 
 Принимает асинхронный генератор или обычный генератор/итератор и отправляет тело ответа потоково.
 
-{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
 
 #### Использование `StreamingResponse` с файлоподобными объектами { #using-streamingresponse-with-file-like-objects }
 
@@ -226,7 +226,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 Это включает многие библиотеки для работы с облачным хранилищем, обработки видео и т.д.
 
-{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
 
 1. Это функция-генератор. Она является «функцией-генератором», потому что содержит оператор(ы) `yield` внутри.
 2. Используя блок `with`, мы гарантируем, что файлоподобный объект будет закрыт после завершения работы функции-генератора. То есть после того, как она закончит отправку ответа.
@@ -255,11 +255,11 @@ FastAPI (фактически Starlette) автоматически добави
 
 Файловые ответы будут содержать соответствующие заголовки `Content-Length`, `Last-Modified` и `ETag`.
 
-{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
 
 Вы также можете использовать параметр `response_class`:
 
-{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
 
 В этом случае вы можете возвращать путь к файлу напрямую из своей функции-обработчика пути.
 
@@ -273,7 +273,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 Вы могли бы создать `CustomORJSONResponse`. Главное, что вам нужно сделать — реализовать метод `Response.render(content)`, который возвращает содержимое как `bytes`:
 
-{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
 
 Теперь вместо того, чтобы возвращать:
 
@@ -299,7 +299,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 В примере ниже **FastAPI** будет использовать `ORJSONResponse` по умолчанию во всех операциях пути вместо `JSONResponse`.
 
-{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
 
 /// tip | Совет
 
index b3ced37c1e48d029615de58bb0c51e7ee75bede7..87a5763c105f1412b871f90eb914d31082f4f71f 100644 (file)
@@ -64,7 +64,7 @@ FastAPI построен поверх **Pydantic**, и я показывал в
 
 6. Здесь мы возвращаем словарь, содержащий `items`, который является списком dataclass.
 
-    FastAPI по-прежнему способен <abbr title="преобразование данных в формат, который можно передавать">сериализовать</abbr> данные в JSON.
+    FastAPI по-прежнему способен <dfn title="преобразование данных в формат, который можно передавать">сериализовать</dfn> данные в JSON.
 
 7. Здесь `response_model` использует аннотацию типа — список dataclass `Author`.
 
index db73d9094ec119de2a5509aff60ebdc568e84a02..bcb5b000a4106a991413f426f963e9934420b503 100644 (file)
@@ -30,7 +30,7 @@
 
 Мы создаём асинхронную функцию `lifespan()` с `yield` примерно так:
 
-{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
 
 Здесь мы симулируем дорогую операцию startup по загрузке модели, помещая (фиктивную) функцию модели в словарь с моделями Машинного обучения до `yield`. Этот код будет выполнен до того, как приложение начнет принимать запросы, во время startup.
 
@@ -48,7 +48,7 @@
 
 Первое, на что стоит обратить внимание, — мы определяем асинхронную функцию с `yield`. Это очень похоже на Зависимости с `yield`.
 
-{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
 
 Первая часть функции, до `yield`, будет выполнена до запуска приложения.
 
@@ -60,7 +60,7 @@
 
 Это превращает функцию в «асинхронный менеджер контекста».
 
-{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
 
 Менеджер контекста в Python — это то, что можно использовать в операторе `with`. Например, `open()` можно использовать как менеджер контекста:
 
@@ -82,7 +82,7 @@ async with lifespan(app):
 
 Параметр `lifespan` приложения `FastAPI` принимает асинхронный менеджер контекста, поэтому мы можем передать ему наш новый асинхронный менеджер контекста `lifespan`.
 
-{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
 
 ## Альтернативные события (устаревшие) { #alternative-events-deprecated }
 
@@ -104,7 +104,7 @@ async with lifespan(app):
 
 Чтобы добавить функцию, которую нужно запустить до старта приложения, объявите её как обработчик события `"startup"`:
 
-{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
 
 В этом случае функция-обработчик события `startup` инициализирует «базу данных» items (это просто `dict`) некоторыми значениями.
 
@@ -116,7 +116,7 @@ async with lifespan(app):
 
 Чтобы добавить функцию, которую нужно запустить при завершении работы приложения, объявите её как обработчик события `"shutdown"`:
 
-{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
 
 Здесь функция-обработчик события `shutdown` запишет строку текста `"Application shutdown"` в файл `log.txt`.
 
index 00bdd31fe8e720456736d10b3022ad6fba129951..4eb098a88fab4922293980446351b1d9e23445ff 100644 (file)
@@ -2,7 +2,7 @@
 
 Поскольку **FastAPI** основан на спецификации **OpenAPI**, его API можно описать в стандартном формате, понятном множеству инструментов.
 
-Это упрощает генерацию актуальной **документации**, клиентских библиотек (<abbr title="Software Development Kits  Наборы средств разработки">**SDKs**</abbr>) на разных языках, а также **тестирования** или **воркфлоу автоматизации**, которые остаются синхронизированными с вашим кодом.
+Это упрощает генерацию актуальной **документации**, клиентских библиотек (<abbr title="Software Development Kits - Наборы средств разработки">**SDKs**</abbr>) на разных языках, а также **тестирования** или **воркфлоу автоматизации**, которые остаются синхронизированными с вашим кодом.
 
 В этом руководстве вы узнаете, как сгенерировать **TypeScript SDK** для вашего бэкенда на FastAPI.
 
@@ -40,7 +40,7 @@ FastAPI автоматически генерирует спецификации
 
 Начнём с простого приложения FastAPI:
 
-{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
+{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
 
 Обратите внимание, что *операции пути (обработчики пути)* определяют модели, которые они используют для полезной нагрузки запроса и полезной нагрузки ответа, с помощью моделей `Item` и `ResponseMessage`.
 
@@ -98,7 +98,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
 
 Например, у вас может быть раздел для **items** и другой раздел для **users**, и они могут быть разделены тегами:
 
-{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
+{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
 
 ### Генерация TypeScript‑клиента с тегами { #generate-a-typescript-client-with-tags }
 
@@ -145,7 +145,7 @@ FastAPI использует **уникальный ID** для каждой *о
 
 Затем вы можете передать эту пользовательскую функцию в **FastAPI** через параметр `generate_unique_id_function`:
 
-{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
+{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
 
 ### Генерация TypeScript‑клиента с пользовательскими ID операций { #generate-a-typescript-client-with-custom-operation-ids }
 
@@ -157,7 +157,7 @@ FastAPI использует **уникальный ID** для каждой *о
 
 ### Предобработка спецификации OpenAPI для генератора клиента { #preprocess-the-openapi-specification-for-the-client-generator }
 
¡генерированном коде всё ещё есть **дублирующаяся информация**.
\92 Ñ\81генерированном коде всё ещё есть **дублирующаяся информация**.
 
 Мы уже знаем, что этот метод относится к **items**, потому что это слово есть в `ItemsService` (взято из тега), но при этом имя тега всё ещё добавлено префиксом к имени метода. 😕
 
@@ -167,7 +167,7 @@ FastAPI использует **уникальный ID** для каждой *о
 
 Мы можем скачать OpenAPI JSON в файл `openapi.json`, а затем **убрать этот префикс‑тег** таким скриптом:
 
-{* ../../docs_src/generate_clients/tutorial004_py39.py *}
+{* ../../docs_src/generate_clients/tutorial004_py310.py *}
 
 //// tab | Node.js
 
index 5ebe010782d0fc955c1fbd6d1e7a23b881088701..034feae7ebab6f6a4e6d9c8ce56018f9e5d7b955 100644 (file)
@@ -57,13 +57,13 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
 
 Любой входящий запрос по `http` или `ws` будет перенаправлен на безопасную схему.
 
-{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
 
 ## `TrustedHostMiddleware` { #trustedhostmiddleware }
 
 Гарантирует, что во всех входящих запросах корректно установлен `Host`‑заголовок, чтобы защититься от атак на HTTP‑заголовок Host.
 
-{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
 
 Поддерживаются следующие аргументы:
 
@@ -78,7 +78,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
 
 Это middleware обрабатывает как обычные, так и потоковые ответы.
 
-{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
 
 Поддерживаются следующие аргументы:
 
index 3a2b9fff7464fcba7951b94732c4bcf24fc400e0..b477075c113b74bd423fbfeb9ef2821735abdd26 100644 (file)
@@ -16,9 +16,9 @@
 
 Вся логика регистрации URL-адресов для вебхуков и код, который реально отправляет эти запросы, целиком на вашей стороне. Вы пишете это так, как вам нужно, в своем собственном коде.
 
-## Документирование вебхуков с помощью FastAPI и OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
+## Документирование вебхуков с помощью **FastAPI** и OpenAPI { #documenting-webhooks-with-fastapi-and-openapi }
 
-С FastAPI, используя OpenAPI, вы можете определить имена этих вебхуков, типы HTTP-операций, которые ваше приложение может отправлять (например, `POST`, `PUT` и т.д.), а также тела запросов, которые ваше приложение будет отправлять.
+С **FastAPI**, используя OpenAPI, вы можете определить имена этих вебхуков, типы HTTP-операций, которые ваше приложение может отправлять (например, `POST`, `PUT` и т.д.), а также тела запросов, которые ваше приложение будет отправлять.
 
 Это значительно упростит вашим пользователям реализацию их API для приема ваших вебхук-запросов; возможно, они даже смогут автоматически сгенерировать часть кода своего API.
 
@@ -32,7 +32,7 @@
 
 При создании приложения на **FastAPI** есть атрибут `webhooks`, с помощью которого можно объявлять вебхуки так же, как вы объявляете операции пути (обработчики пути), например с `@app.webhooks.post()`.
 
-{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
 
 Определенные вами вебхуки попадут в схему **OpenAPI** и в автоматический **интерфейс документации**.
 
index 86d3a5b630da0998d5814f81faaf7a01fd03998b..b8c879bf6f31bdeca5a66072fef17b86581713c4 100644 (file)
@@ -12,7 +12,7 @@
 
 Нужно убедиться, что он уникален для каждой операции.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
 
 ### Использование имени *функции-обработчика пути* как operationId { #using-the-path-operation-function-name-as-the-operationid }
 
@@ -20,7 +20,7 @@
 
 Делать это следует после добавления всех *операций пути*.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
 
 /// tip | Совет
 
@@ -40,7 +40,7 @@
 
 Чтобы исключить *операцию пути* из генерируемой схемы OpenAPI (а значит, и из автоматических систем документации), используйте параметр `include_in_schema` и установите его в `False`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
 
 ## Расширенное описание из docstring { #advanced-description-from-docstring }
 
@@ -92,7 +92,7 @@
 
 `openapi_extra` может пригодиться, например, чтобы объявить [Расширения OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
 
 Если вы откроете автоматическую документацию API, ваше расширение появится внизу страницы конкретной *операции пути*.
 
 
 Это можно сделать с помощью `openapi_extra`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
 
-В этом примере мы не объявляли никакую Pydantic-модель. Фактически тело запроса даже не <abbr title="преобразовано из простого формата, например байтов, в объекты Python">распарсено</abbr> как JSON, оно читается напрямую как `bytes`, а функция `magic_data_reader()` будет отвечать за его парсинг каким-то способом.
+В этом примере мы не объявляли никакую Pydantic-модель. Фактически тело запроса даже не <dfn title="преобразован из простого формата, например байтов, в объекты Python">распарсено</dfn> как JSON, оно читается напрямую как `bytes`, а функция `magic_data_reader()` будет отвечать за его парсинг каким-то способом.
 
 Тем не менее, мы можем объявить ожидаемую схему для тела запроса.
 
 
 Например, в этом приложении мы не используем встроенную функциональность FastAPI для извлечения JSON Schema из моделей Pydantic, равно как и автоматическую валидацию JSON. Мы объявляем тип содержимого HTTP-запроса как YAML, а не JSON:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
 
 Тем не менее, хотя мы не используем встроенную функциональность по умолчанию, мы всё равно используем Pydantic-модель, чтобы вручную сгенерировать JSON Schema для данных, которые мы хотим получить в YAML.
 
 
 А затем в нашем коде мы напрямую парсим это содержимое YAML и снова используем ту же Pydantic-модель, чтобы валидировать YAML-содержимое:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
 
 /// tip | Совет
 
index 85d9050ffc5c557e15b637b33c962e9329979124..273862bae92af0fbf0702a2107e5d4f5220a5273 100644 (file)
@@ -20,7 +20,7 @@
 
 И затем вы можете установить `status_code` в этом *временном* объекте ответа.
 
-{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
 
 После этого вы можете вернуть любой объект, который вам нужен, как обычно (`dict`, модель базы данных и т.д.).
 
index 2872d6c0ade52085b701a8986b49dec7be94d1df..d3662ef8eddfeae1e08144c4db038ba87eb56e69 100644 (file)
@@ -6,7 +6,7 @@
 
 Затем установить cookies в этом временном объекте ответа.
 
-{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
 
 После этого можно вернуть любой объект, как и раньше (например, `dict`, объект модели базы данных и так далее).
 
@@ -24,7 +24,7 @@
 
 Затем установите cookies и верните этот объект:
 
-{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
 
 /// tip | Совет
 
index b452810714739dee486769875a2122391a974c78..60facdd8570175669ed567305d4741f7d0089605 100644 (file)
@@ -54,7 +54,7 @@
 
 Вы можете поместить ваш XML-контент в строку, поместить её в `Response` и вернуть:
 
-{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
 
 ## Примечания { #notes }
 
index 8f24f05b0789389d1e1b960efb0c0f72b9968e58..dc821983bcf1bb0e5685d8f1e9826c37fe573e67 100644 (file)
@@ -6,7 +6,7 @@
 
 А затем вы можете устанавливать HTTP-заголовки в этом *временном* объекте ответа.
 
-{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
 
 После этого вы можете вернуть любой нужный объект, как обычно (например, `dict`, модель из базы данных и т.д.).
 
@@ -22,7 +22,7 @@
 
 Создайте ответ, как описано в [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}, и передайте заголовки как дополнительный параметр:
 
-{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
 
 /// note | Технические детали
 
index 41e62d4bf31f0022fe4a91403953fa36037c156f..a6bfb7c54615892cd37fa07be6580dab4c0d5009 100644 (file)
@@ -20,7 +20,7 @@
 * Она возвращает объект типа `HTTPBasicCredentials`:
     * Он содержит отправленные `username` и `password`.
 
-{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
+{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
 
 Когда вы впервые откроете URL (или нажмёте кнопку «Execute» в документации), браузер попросит ввести имя пользователя и пароль:
 
@@ -40,7 +40,7 @@
 
 Затем можно использовать `secrets.compare_digest()`, чтобы убедиться, что `credentials.username` равен `"stanleyjobson"`, а `credentials.password` — `"swordfish"`.
 
-{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
+{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
 
 Это было бы похоже на:
 
@@ -104,4 +104,4 @@ Pythonу придётся сравнить весь общий префикс `s
 
 После того как обнаружено, что учётные данные некорректны, верните `HTTPException` со статус-кодом ответа 401 (тем же, что и при отсутствии учётных данных) и добавьте HTTP-заголовок `WWW-Authenticate`, чтобы браузер снова показал окно входа:
 
-{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
+{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}
index 8408faebff981833faa9321a082b37ed8e61672a..15537e2b40ad2b7f83e48daf4a1fca900e161085 100644 (file)
@@ -54,7 +54,7 @@ $ pip install "fastapi[all]"
 
 Вы можете использовать все те же возможности валидации и инструменты, что и для Pydantic‑моделей, например разные типы данных и дополнительную валидацию через `Field()`.
 
-{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
 
 /// tip | Совет
 
@@ -70,7 +70,7 @@ $ pip install "fastapi[all]"
 
 Затем вы можете использовать новый объект `settings` в вашем приложении:
 
-{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
 
 ### Запуск сервера { #run-the-server }
 
@@ -104,11 +104,11 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 Например, у вас может быть файл `config.py` со следующим содержимым:
 
-{* ../../docs_src/settings/app01_py39/config.py *}
+{* ../../docs_src/settings/app01_py310/config.py *}
 
 А затем использовать его в файле `main.py`:
 
-{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
 
 /// tip | Совет
 
@@ -126,7 +126,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 Продолжая предыдущий пример, ваш файл `config.py` может выглядеть так:
 
-{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
+{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
 
 Обратите внимание, что теперь мы не создаем экземпляр по умолчанию `settings = Settings()`.
 
@@ -134,7 +134,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 Теперь мы создаем зависимость, которая возвращает новый `config.Settings()`.
 
-{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
+{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
 
 /// tip | Совет
 
@@ -146,13 +146,13 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 Затем мы можем запросить ее в *функции-обработчике пути* как зависимость и использовать там, где нужно.
 
-{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
+{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
 
 ### Настройки и тестирование { #settings-and-testing }
 
 Далее будет очень просто предоставить другой объект настроек во время тестирования, создав переопределение зависимости для `get_settings`:
 
-{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
+{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
 
 В переопределении зависимости мы задаем новое значение `admin_email` при создании нового объекта `Settings`, а затем возвращаем этот новый объект.
 
@@ -193,7 +193,7 @@ APP_NAME="ChimichangApp"
 
 Затем обновите ваш `config.py` так:
 
-{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
+{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
 
 /// tip | Совет
 
@@ -226,7 +226,7 @@ def get_settings():
 
 Но так как мы используем декоратор `@lru_cache` сверху, объект `Settings` будет создан только один раз — при первом вызове. ✔️
 
-{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
+{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
 
 Затем при любых последующих вызовах `get_settings()` в зависимостях для следующих запросов, вместо выполнения внутреннего кода `get_settings()` и создания нового объекта `Settings`, будет возвращаться тот же объект, что был возвращен при первом вызове, снова и снова.
 
index fa5a683f45f0c00fb3fdb308511fb607e907ea4e..4fd5649ce3e4c95610944df47861ffcbd1c6322c 100644 (file)
@@ -10,7 +10,7 @@
 
 Сначала создайте основное, верхнего уровня, приложение **FastAPI** и его *операции пути*:
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
 
 ### Подприложение { #sub-application }
 
@@ -18,7 +18,7 @@
 
 Это подприложение — обычное стандартное приложение FastAPI, но именно оно будет «смонтировано»:
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
 
 ### Смонтируйте подприложение { #mount-the-sub-application }
 
@@ -26,7 +26,7 @@
 
 В этом случае оно будет смонтировано по пути `/subapi`:
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
 
 ### Проверьте автоматическую документацию API { #check-the-automatic-api-docs }
 
index 460e2e4660ebd4f01eff4fb36c247f7dbe825411..68adcb5151ce32625bc0dd43627e4408175fcdae 100644 (file)
@@ -27,7 +27,7 @@ $ pip install jinja2
 - Объявите параметр `Request` в *операции пути*, которая будет возвращать шаблон.
 - Используйте созданный `templates`, чтобы отрендерить и вернуть `TemplateResponse`; передайте имя шаблона, объект `request` и словарь «context» с парами ключ-значение для использования внутри шаблона Jinja2.
 
-{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
 
 /// note | Примечание
 
index 82caea845b8a49a8ad29b14d7ff9d623f803b7dd..452342cdd2c610a5393b6b3a7939287315ec0530 100644 (file)
@@ -2,11 +2,11 @@
 
 Если вам нужно, чтобы `lifespan` выполнялся в ваших тестах, вы можете использовать `TestClient` вместе с оператором `with`:
 
-{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
 
 
 Вы можете узнать больше подробностей в статье [Запуск lifespan в тестах на официальном сайте документации Starlette.](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
 
 Для устаревших событий `startup` и `shutdown` вы можете использовать `TestClient` следующим образом:
 
-{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}
index b6626679e4b05e9ff502dea307c9361ebb805917..f6fa6a04bec27da4f10bb82b1c8ffc662eee9fed 100644 (file)
@@ -4,7 +4,7 @@
 
 Для этого используйте `TestClient` с менеджером контекста `with`, подключаясь к WebSocket:
 
-{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
 
 /// note | Примечание
 
index cdf500c0e2c8c50da5e86b5993f02e770fcd0d4a..0c091cdeda97d5be5ad239d8f2dce2878febf0fa 100644 (file)
@@ -29,7 +29,7 @@
 
 Для этого нужно обратиться к запросу напрямую.
 
-{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
 
 Если объявить параметр *функции-обработчика пути* с типом `Request`, **FastAPI** поймёт, что нужно передать объект `Request` в этот параметр.
 
index fa5e4738eb69ef62bf00f45d8563023bba79a63d..446cc2505ed3e0c1985e8b85020ace4531c475ba 100644 (file)
@@ -38,13 +38,13 @@ $ pip install websockets
 
 Для примера нам нужен наиболее простой способ, который позволит сосредоточиться на серверной части веб‑сокетов и получить рабочий код:
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
 
 ## Создание `websocket` { #create-a-websocket }
 
 Создайте `websocket` в своем **FastAPI** приложении:
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
 
 /// note | Технические детали
 
@@ -58,7 +58,7 @@ $ pip install websockets
 
 Через эндпоинт веб-сокета вы можете получать и отправлять сообщения.
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
 
 Вы можете получать и отправлять двоичные, текстовые и JSON данные.
 
@@ -154,7 +154,7 @@ $ fastapi dev main.py
 
 Если веб-сокет соединение закрыто, то `await websocket.receive_text()` вызовет исключение `WebSocketDisconnect`, которое можно поймать и обработать как в этом примере:
 
-{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
+{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
 
 Чтобы воспроизвести пример:
 
index 41d3a169c73899c670b99995784dc55d03c1a86a..aa630c228e92c86711106b488903ec0a1ff5ebbe 100644 (file)
@@ -18,7 +18,7 @@
 
 После этого смонтируйте его на путь.
 
-{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
+{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
 
 /// note | Примечание
 
index 17b54aad2f25cb2b57c05f7cceecf09b9098a421..1f713c3f39b8a089a95bb8c357e5d003deb9bc64 100644 (file)
@@ -137,7 +137,7 @@ def read_url():
 
 ### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
 
-Одна из основных возможностей, нужных системам API, — «<abbr title="также называемая маршаллингом или преобразованием">сериализация</abbr>» данных, то есть преобразование данных из кода (Python) во что-то, что можно отправить по сети. Например, преобразование объекта с данными из базы в JSON-объект. Преобразование объектов `datetime` в строки и т. п.
+Одна из основных возможностей, нужных системам API, — «<dfn title="также называемая маршаллингом, преобразованием">сериализация</dfn>» данных, то есть преобразование данных из кода (Python) во что-то, что можно отправить по сети. Например, преобразование объекта с данными из базы в JSON-объект. Преобразование объектов `datetime` в строки и т. п.
 
 Ещё одна важная возможность, востребованная API, — валидация данных: убеждаться, что данные валидны с учётом заданных параметров. Например, что какое-то поле — `int`, а не произвольная строка. Это особенно полезно для входящих данных.
 
@@ -145,7 +145,7 @@ def read_url():
 
 Именно для этих возможностей и был создан Marshmallow. Это отличная библиотека, я много ей пользовался раньше.
 
-Но она появилась до того, как в Python появились аннотации типов. Поэтому для определения каждой <abbr title="описание того, как данные должны быть сформированы">схемы</abbr> нужно использовать специальные утилиты и классы, предоставляемые Marshmallow.
+Но она появилась до того, как в Python появились аннотации типов. Поэтому для определения каждой <dfn title="определение того, как должны быть сформированы данные">схемы</dfn> нужно использовать специальные утилиты и классы, предоставляемые Marshmallow.
 
 /// check | Вдохновило **FastAPI** на
 
@@ -155,7 +155,7 @@ def read_url():
 
 ### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
 
-Ещё одна важная возможность для API — <abbr title="чтение и преобразование данных в объекты Python">парсинг</abbr> данных из входящих HTTP-запросов.
+Ещё одна важная возможность для API — <dfn title="чтение и преобразование в данные Python">парсинг</dfn> данных из входящих HTTP-запросов.
 
 Webargs — это инструмент, созданный для этого поверх нескольких фреймворков, включая Flask.
 
@@ -245,7 +245,7 @@ Flask-apispec был создан теми же разработчиками, ч
 
 В нём встроена система внедрения зависимостей, вдохновлённая Angular 2. Требуется предварительная регистрация «инжектируемых» компонентов (как и во всех известных мне системах внедрения зависимостей), что добавляет многословности и повторяемости кода.
 
-Поскольку параметры описываются с помощью типов TypeScript (аналог аннотаций типов в Python), поддержка редактора весьма хороша.
\9fоÑ\81колÑ\8cкÑ\83 Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ð¾Ð¿Ð¸Ñ\81Ñ\8bваÑ\8eÑ\82Ñ\81Ñ\8f Ñ\81 Ð¿Ð¾Ð¼Ð¾Ñ\89Ñ\8cÑ\8e Ñ\82ипов TypeScript (аналог Ð°Ð½Ð½Ð¾Ñ\82аÑ\86ий Ñ\82ипов Ð² Python), Ð¿Ð¾Ð´Ð´ÐµÑ\80жка Ñ\80едакÑ\82оÑ\80а ÐºÐ¾Ð´Ð° Ð²ÐµÑ\81Ñ\8cма Ñ\85оÑ\80оÑ\88а.
 
 Но так как данные о типах TypeScript не сохраняются после компиляции в JavaScript, он не может полагаться на типы для одновременного определения валидации, сериализации и документации. Из‑за этого и некоторых проектных решений для получения валидации, сериализации и автоматической генерации схем приходится добавлять декораторы во многих местах. В итоге это становится довольно многословным.
 
@@ -359,7 +359,7 @@ Hug вдохновил **FastAPI** объявлять параметр `response
 
 В нём были автоматические валидация данных, сериализация данных и генерация схемы OpenAPI на основе тех же аннотаций типов в нескольких местах.
 
-Определение схемы тела запроса не использовало те же аннотации типов Python, как в Pydantic, — это было ближе к Marshmallow, поэтому поддержка редактора была бы хуже, но всё равно APIStar оставался лучшим доступным вариантом.
\9eпÑ\80еделение Ñ\81Ñ\85емÑ\8b Ñ\82ела Ð·Ð°Ð¿Ñ\80оÑ\81а Ð½Ðµ Ð¸Ñ\81полÑ\8cзовало Ñ\82е Ð¶Ðµ Ð°Ð½Ð½Ð¾Ñ\82аÑ\86ии Ñ\82ипов Python, ÐºÐ°Ðº Ð² Pydantic, â\80\94 Ñ\8dÑ\82о Ð±Ñ\8bло Ð±Ð»Ð¸Ð¶Ðµ Ðº Marshmallow, Ð¿Ð¾Ñ\8dÑ\82омÑ\83 Ð¿Ð¾Ð´Ð´ÐµÑ\80жка Ñ\80едакÑ\82оÑ\80а ÐºÐ¾Ð´Ð° Ð±Ñ\8bла Ð±Ñ\8b Ñ\85Ñ\83же, Ð½Ð¾ Ð²Ñ\81Ñ\91 Ñ\80авно APIStar Ð¾Ñ\81Ñ\82авалÑ\81Ñ\8f Ð»Ñ\83Ñ\87Ñ\88им Ð´Ð¾Ñ\81Ñ\82Ñ\83пнÑ\8bм Ð²Ð°Ñ\80ианÑ\82ом.
 
 На тот момент у него были лучшие показатели в бенчмарках (его превосходил только Starlette).
 
@@ -419,7 +419,7 @@ Pydantic — это библиотека для определения вали
 
 ### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
 
-Starlette — это лёгкий <abbr title="Новый стандарт построения асинхронных веб-сервисов Python">ASGI</abbr> фреймворк/набор инструментов, идеально подходящий для создания высокопроизводительных asyncio‑сервисов.
+Starlette — это лёгкий <dfn title="Новый стандарт построения асинхронных веб-приложений на Python">ASGI</dfn> фреймворк/набор инструментов, идеально подходящий для создания высокопроизводительных asyncio‑сервисов.
 
 Он очень простой и интуитивный. Спроектирован так, чтобы его было легко расширять, и чтобы компоненты были модульными.
 
index 15d4e108ab875b88580a5dda838b536c0c752215..bff32aaf49dffcb71aa5686370c9fa7fa6e15a40 100644 (file)
@@ -4,7 +4,7 @@
 
 ## Нет времени? { #in-a-hurry }
 
-<abbr title="too long; didn't read  слишком длинно; не читал"><strong>TL;DR:</strong></abbr>
+<abbr title="too long; didn't read - слишком длинно; не читал"><strong>TL;DR:</strong></abbr>
 
 Если вы используете сторонние библиотеки, которые нужно вызывать с `await`, например:
 
@@ -68,13 +68,13 @@ def results():
 
 Асинхронный код значит, что в языке 💬 есть способ сказать компьютеру/программе 🤖, что в некоторый момент кода ему 🤖 придётся подождать, пока *что-то ещё* где-то в другом месте завершится. Назовём это *что-то ещё* «медленный файл» 📝.
 
\98 Ð¿Ð¾ÐºÐ° Ð¼Ñ\8b Ð¶Ð´Ñ\91м Ð·Ð°Ð²ÐµÑ\80Ñ\88ениÑ\8f Ñ\80абоÑ\82Ñ\8b Ñ\81 Â«Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ñ\8bи файлом» 📝, компьютер может заняться другой работой.
\98 Ð¿Ð¾ÐºÐ° Ð¼Ñ\8b Ð¶Ð´Ñ\91м Ð·Ð°Ð²ÐµÑ\80Ñ\88ениÑ\8f Ñ\80абоÑ\82Ñ\8b Ñ\81 Â«Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ñ\8bм файлом» 📝, компьютер может заняться другой работой.
 
 Затем компьютер/программа 🤖 будет возвращаться каждый раз, когда появится возможность (пока снова где-то идёт ожидание), или когда 🤖 завершит всю текущую работу. И он 🤖 проверит, не завершилась ли какая-либо из задач, которых он ждал, и сделает то, что нужно.
 
 Далее он 🤖 возьмёт первую завершившуюся задачу (скажем, наш «медленный файл» 📝) и продолжит делать с ней то, что требуется.
 
-Это «ожидание чего-то ещё» обычно относится к операциям <abbr title="Input and Output  Ввод/вывод">I/O</abbr>, которые относительно «медленные» (по сравнению со скоростью процессора и оперативной памяти), например ожидание:
+Это «ожидание чего-то ещё» обычно относится к операциям <abbr title="Input and Output - Ввод/вывод">I/O</abbr>, которые относительно «медленные» (по сравнению со скоростью процессора и оперативной памяти), например ожидание:
 
 * отправки данных клиентом по сети
 * получения клиентом данных, отправленных вашей программой по сети
@@ -85,7 +85,7 @@ def results():
 * возврата результатов запроса к базе данных
 * и т.д.
 
-Поскольку основное время выполнения уходит на ожидание операций <abbr title="Input and Output  Ввод/вывод">I/O</abbr>, их называют операциями, «ограниченными вводом-выводом» (I/O bound).
+Поскольку основное время выполнения уходит на ожидание операций <abbr title="Input and Output - Ввод/вывод">I/O</abbr>, их называют операциями, «ограниченными вводом-выводом» (I/O bound).
 
 Это называется «асинхронным», потому что компьютеру/программе не нужно «синхронизироваться» с медленной задачей, простаивая и выжидая точный момент её завершения, чтобы забрать результат и продолжить работу.
 
@@ -277,7 +277,7 @@ def results():
 
 В этом сценарии каждый уборщик (включая вас) был бы процессором, выполняющим свою часть работы.
 
-И так как основное время выполнения уходит на реальную работу (а не ожидание), а работу в компьютере выполняет <abbr title="Central Processing Unit  Центральный процессор">CPU</abbr>, такие задачи называют «ограниченными процессором» (CPU bound).
+И так как основное время выполнения уходит на реальную работу (а не ожидание), а работу в компьютере выполняет <abbr title="Central Processing Unit - Центральный процессор">CPU</abbr>, такие задачи называют «ограниченными процессором» (CPU bound).
 
 ---
 
@@ -417,7 +417,7 @@ Starlette (и **FastAPI**) основаны на <a href="https://anyio.readthed
 
 Когда вы объявляете *функцию-обработчик пути* обычным `def` вместо `async def`, она запускается во внешнем пуле потоков, который затем «ожидается», вместо прямого вызова (прямой вызов заблокировал бы сервер).
 
-Если вы пришли из другого async-фреймворка, который работает иначе, и привыкли объявлять тривиальные *функции-обработчики пути*, выполняющие только вычисления, через простой `def` ради крошечной выгоды в производительности (около 100 наносекунд), обратите внимание: в **FastAPI** эффект будет противоположным. В таких случаях лучше использовать `async def`, если только ваши *функции-обработчики пути* не используют код, выполняющий блокирующий <abbr title="Input/Output  Ввод/вывод: чтение или запись на диск, сетевые соединения.">I/O</abbr>.
+Если вы пришли из другого async-фреймворка, который работает иначе, и привыкли объявлять тривиальные *функции-обработчики пути*, выполняющие только вычисления, через простой `def` ради крошечной выгоды в производительности (около 100 наносекунд), обратите внимание: в **FastAPI** эффект будет противоположным. В таких случаях лучше использовать `async def`, если только ваши *функции-обработчики пути* не используют код, выполняющий блокирующий <abbr title="Input/Output - Ввод/вывод: чтение или запись на диск, сетевые соединения.">I/O</abbr>.
 
 Тем не менее, в обоих случаях велика вероятность, что **FastAPI** [всё равно будет быстрее](index.md#performance){.internal-link target=_blank} (или как минимум сопоставим) с вашим предыдущим фреймворком.
 
index 612b39f708a54d59209ea47ae313223ec94ef373..c8cacae5f3a0d6e444707e7522efa402eef7c252 100644 (file)
 
 * **Uvicorn**: ASGI-сервер
     * **Starlette**: (использует Uvicorn) веб-микрофреймворк
-        * **FastAPI**: (использует Starlette) API-микрофреймворк с рядом дополнительных возможностей для создания API, включая валидацию данных и т. п.
+        * **FastAPI**: (использует Starlette) API-микрофреймворк с рядом дополнительных возможностей для создания API, включая валидацию данных и т.п.
 
 * **Uvicorn**:
     * Будет иметь наилучшую производительность, так как помимо самого сервера у него немного дополнительного кода.
     * Вы не будете писать приложение непосредственно на Uvicorn. Это означало бы, что Ваш код должен включать как минимум весь код, предоставляемый Starlette (или **FastAPI**). И если Вы так сделаете, то в конечном итоге Ваше приложение будет иметь те же накладные расходы, что и при использовании фреймворка, минимизирующего код Вашего приложения и Ваши ошибки.
-    * Если Вы сравниваете Uvicorn, сравнивайте его с Daphne, Hypercorn, uWSGI и т. д. — серверами приложений.
+    * Если Вы сравниваете Uvicorn, сравнивайте его с Daphne, Hypercorn, uWSGI и т.д. — серверами приложений.
 * **Starlette**:
     * Будет на следующем месте по производительности после Uvicorn. Фактически Starlette запускается под управлением Uvicorn, поэтому он может быть только «медленнее» Uvicorn из‑за выполнения большего объёма кода.
-    * Зато он предоставляет Вам инструменты для создания простых веб‑приложений с маршрутизацией по путям и т. п.
-    * Если Вы сравниваете Starlette, сравнивайте его с Sanic, Flask, Django и т. д. — веб‑фреймворками (или микрофреймворками).
+    * Зато он предоставляет Вам инструменты для создания простых веб‑приложений с маршрутизацией по путям и т.п.
+    * Если Вы сравниваете Starlette, сравнивайте его с Sanic, Flask, Django и т.д. — веб‑фреймворками (или микрофреймворками).
 * **FastAPI**:
     * Точно так же, как Starlette использует Uvicorn и не может быть быстрее него, **FastAPI** использует Starlette, поэтому не может быть быстрее его.
     * FastAPI предоставляет больше возможностей поверх Starlette — те, которые почти всегда нужны при создании API, такие как валидация и сериализация данных. В довесок Вы ещё и получаете автоматическую документацию (автоматическая документация даже не увеличивает накладные расходы при работе приложения, так как она создаётся при запуске).
-    * Если бы Вы не использовали FastAPI, а использовали Starlette напрямую (или другой инструмент вроде Sanic, Flask, Responder и т. д.), Вам пришлось бы самостоятельно реализовать валидацию и сериализацию данных. То есть, в итоге, Ваше приложение имело бы такие же накладные расходы, как если бы оно было создано с использованием FastAPI. И во многих случаях валидация и сериализация данных представляют собой самый большой объём кода, написанного в приложениях.
+    * Если бы Вы не использовали FastAPI, а использовали Starlette напрямую (или другой инструмент вроде Sanic, Flask, Responder и т.д.), Вам пришлось бы самостоятельно реализовать валидацию и сериализацию данных. То есть, в итоге, Ваше приложение имело бы такие же накладные расходы, как если бы оно было создано с использованием FastAPI. И во многих случаях валидация и сериализация данных представляют собой самый большой объём кода, написанного в приложениях.
     * Таким образом, используя FastAPI, Вы экономите время разработки, уменьшаете количество ошибок, строк кода и, вероятно, получите ту же производительность (или лучше), как и если бы не использовали его (поскольку Вам пришлось бы реализовать все его возможности в своём коде).
     * Если Вы сравниваете FastAPI, сравнивайте его с фреймворком веб‑приложений (или набором инструментов), который обеспечивает валидацию данных, сериализацию и документацию, такими как Flask-apispec, NestJS, Molten и им подобные. Фреймворки с интегрированной автоматической валидацией данных, сериализацией и документацией.
index 207d1604d79bf5886ce1060bfa69f70740a741b4..173dbb962d4fe544f3708d6cb28108b2fc8e7245 100644 (file)
 
 В [предыдущей главе про HTTPS](https.md){.internal-link target=_blank} мы разобрались, как HTTPS обеспечивает шифрование для вашего API.
 
-Также мы увидели, что HTTPS обычно обеспечивает компонент, **внешний** по отношению к серверу вашего приложения — **TLS Termination Proxy**.
+Также мы увидели, что HTTPS обычно обеспечивает компонент, **внешний** по отношению к серверу вашего приложения — **прокси-сервер TSL-терминации**.
 
 И должен быть компонент, отвечающий за **обновление HTTPS‑сертификатов** — это может быть тот же самый компонент или отдельный.
 
 ### Примеры инструментов для HTTPS { #example-tools-for-https }
 
-Некоторые инструменты, которые можно использовать как TLS Termination Proxy:
+Некоторые инструменты, которые можно использовать как прокси-сервер TSL-терминации:
 
 * Traefik
     * Автоматически обновляет сертификаты ✨
@@ -47,7 +47,7 @@
     * С внешним компонентом (например, cert-manager) для обновления сертификатов
 * Обрабатывается внутри облачного провайдера как часть его услуг (см. ниже 👇)
 
-Другой вариант — использовать **облачный сервис**, который возьмёт на себя больше задач, включая настройку HTTPS. Там могут быть ограничения или дополнительная стоимость и т.п., но в таком случае вам не придётся самим настраивать TLS Termination Proxy.
+Другой вариант — использовать **облачный сервис**, который возьмёт на себя больше задач, включая настройку HTTPS. Там могут быть ограничения или дополнительная стоимость и т.п., но в таком случае вам не придётся самим настраивать прокси-сервер TSL-терминации.
 
 В следующих главах я покажу конкретные примеры.
 
 
 Процесс‑менеджер, вероятно, будет тем, кто слушает **порт** на IP. И он будет передавать всю коммуникацию воркер‑процессам.
 
-Эти воркеры будут запускать ваше приложение, выполнять основные вычисления для получения **запроса** и возврата **ответа**, и загружать всё, что вы кладёте в переменные, в RAM.
+Эти воркеры будут запускать ваше приложение, выполнять основные вычисления для получения **HTTP‑запроса** и возврата **HTTP‑ответа**, и загружать всё, что вы кладёте в переменные, в RAM.
 
 <img src="/img/deployment/concepts/process-ram.drawio.svg">
 
 
 Ваш сервер(а) — это **ресурс**, который ваши программы могут потреблять или **использовать**: время вычислений на CPU и доступную оперативную память (RAM).
 
-Какую долю системных ресурсов вы хотите потреблять/использовать? Можно подумать «немного», но на практике вы, скорее всего, захотите потреблять **максимум без падений**.
+Какую долю системных ресурсов вы хотите потреблять/использовать? Можно подумать «немного», но на практике вы, вероятно, захотите потреблять **максимум без падений**.
 
 Если вы платите за 3 сервера, но используете лишь малую часть их RAM и CPU, вы, вероятно, **тратите деньги впустую** 💸 и **электроэнергию серверов** 🌎 и т.п.
 
index 9e8562be709ae1094b59fab60b96e58cbcf47353..791057fe56f66da64fcb972509eb219d86187b98 100644 (file)
@@ -14,7 +14,7 @@
 <summary>Предпросмотр Dockerfile 👀</summary>
 
 ```Dockerfile
-FROM python:3.9
+FROM python:3.14
 
 WORKDIR /code
 
@@ -166,7 +166,7 @@ def read_item(item_id: int, q: str | None = None):
 
 ```{ .dockerfile .annotate }
 # (1)!
-FROM python:3.9
+FROM python:3.14
 
 # (2)!
 WORKDIR /code
@@ -273,9 +273,9 @@ CMD fastapi run app/main.py --port 80
 └── requirements.txt
 ```
 
-#### За прокси-сервером TLS терминации { #behind-a-tls-termination-proxy }
+#### За прокси-сервером TSL-терминации { #behind-a-tls-termination-proxy }
 
-Если вы запускаете контейнер за прокси-сервером завершения TLS (балансировщиком нагрузки), таким как Nginx или Traefik, добавьте опцию `--proxy-headers`. Это сообщит Uvicorn (через FastAPI CLI), что приложение работает за HTTPS и можно доверять соответствующим заголовкам.
+Если вы запускаете контейнер за прокси-сервером TSL-терминации (балансировщиком нагрузки), таким как Nginx или Traefik, добавьте опцию `--proxy-headers`. Это сообщит Uvicorn (через FastAPI CLI), что приложение работает за HTTPS и можно доверять соответствующим заголовкам.
 
 ```Dockerfile
 CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]
@@ -390,7 +390,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
 Тогда в `Dockerfile` нужно изменить пути копирования:
 
 ```{ .dockerfile .annotate hl_lines="10  13" }
-FROM python:3.9
+FROM python:3.14
 
 WORKDIR /code
 
@@ -454,7 +454,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
 
 ## Репликация — количество процессов { #replication-number-of-processes }
 
-Если у вас есть <abbr title="Группа машин, настроенных так, чтобы быть соединенными и работать вместе определенным образом.">кластер</abbr> машин с **Kubernetes**, Docker Swarm Mode, Nomad или другой похожей системой для управления распределёнными контейнерами на нескольких машинах, скорее всего вы будете **управлять репликацией** на **уровне кластера**, а не использовать **менеджер процессов** (например, Uvicorn с воркерами) в каждом контейнере.
+Если у вас есть <dfn title="Группа машин, настроенных так, чтобы быть соединенными и работать вместе определенным образом.">кластер</dfn> машин с **Kubernetes**, Docker Swarm Mode, Nomad или другой похожей системой для управления распределёнными контейнерами на нескольких машинах, скорее всего вы будете **управлять репликацией** на **уровне кластера**, а не использовать **менеджер процессов** (например, Uvicorn с воркерами) в каждом контейнере.
 
 Одна из таких систем управления распределёнными контейнерами, как Kubernetes, обычно имеет встроенный способ управлять **репликацией контейнеров**, поддерживая **балансировку нагрузки** для входящих запросов — всё это на **уровне кластера**.
 
@@ -462,17 +462,17 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
 
 ### Балансировщик нагрузки { #load-balancer }
 
-При использовании контейнеров обычно есть компонент, **слушающий главный порт**. Это может быть другой контейнер — **прокси завершения TLS** для обработки **HTTPS** или похожий инструмент.
+При использовании контейнеров обычно есть компонент, **слушающий главный порт**. Это может быть другой контейнер — **прокси-сервер TSL-терминации** для обработки **HTTPS** или похожий инструмент.
 
 Поскольку этот компонент принимает **нагрузку** запросов и распределяет её между воркерами **сбалансированно**, его часто называют **балансировщиком нагрузки**.
 
 /// tip | Подсказка
 
-Тот же компонент **прокси завершения TLS**, который обрабатывает HTTPS, скорее всего также будет **балансировщиком нагрузки**.
+Тот же компонент **прокси-сервер TSL-терминации**, который обрабатывает HTTPS, скорее всего также будет **балансировщиком нагрузки**.
 
 ///
 
-При работе с контейнерами система, которую вы используете для запуска и управления ими, уже имеет внутренние средства для передачи **сетевого взаимодействия** (например, HTTP-запросов) от **балансировщика нагрузки** (который также может быть **прокси завершения TLS**) к контейнеру(-ам) с вашим приложением.
+При работе с контейнерами система, которую вы используете для запуска и управления ими, уже имеет внутренние средства для передачи **сетевого взаимодействия** (например, HTTP-запросов) от **балансировщика нагрузки** (который также может быть **прокси-сервером TSL-терминации**) к контейнеру(-ам) с вашим приложением.
 
 ### Один балансировщик — несколько контейнеров-воркеров { #one-load-balancer-multiple-worker-containers }
 
@@ -499,7 +499,7 @@ CMD ["fastapi", "run", "main.py", "--port", "80"]
 В таких случаях вы можете использовать опцию командной строки `--workers`, чтобы указать нужное количество воркеров:
 
 ```{ .dockerfile .annotate }
-FROM python:3.9
+FROM python:3.14
 
 WORKDIR /code
 
index 05a03255e8a29a796f07ce076a6be503f93c17ad..ffeccfd7dabc841fd9fc6230295094624499118f 100644 (file)
@@ -65,7 +65,7 @@
 
 Чаще всего всё начинается с **приобретения** **имени домена**. Затем вы настраиваете его на DNS‑сервере (возможно, у того же облачного провайдера).
 
-Скорее всего, вы получите облачный сервер (виртуальную машину) или что-то подобное, и у него будет <abbr title="Не изменяется">постоянный</abbr> **публичный IP-адрес**.
+Скорее всего, вы получите облачный сервер (виртуальную машину) или что-то подобное, и у него будет <dfn title="Со временем не меняется. Не динамический.">постоянный</dfn> **публичный IP-адрес**.
 
 На DNS‑сервере(ах) вы настроите запись («`A record`» - запись типа A), указывающую, что **ваш домен** должен указывать на публичный **IP‑адрес вашего сервера**.
 
index ffb77641dd32b00f1b6400f729bf703658978ade..7e735593be4c2e3a57dd0afe548bb1baa67256bc 100644 (file)
@@ -18,6 +18,6 @@
 
 Например, мы, команда, стоящая за FastAPI, создали <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>, чтобы сделать развёртывание приложений FastAPI в облаке как можно более простым и прямолинейным, с тем же удобством для разработчика, что и при работе с FastAPI.
 
\92 Ñ\8dÑ\82ом Ð±Ð»Ð¾ÐºÐµ Ñ\8f покажу вам некоторые из основных концепций, которые вы, вероятно, должны иметь в виду при развертывании приложения **FastAPI** (хотя большинство из них применимо к любому другому типу веб-приложений).
¯ покажу вам некоторые из основных концепций, которые вы, вероятно, должны иметь в виду при развертывании приложения **FastAPI** (хотя большинство из них применимо к любому другому типу веб-приложений).
 
 В последующих разделах вы узнаете больше деталей и методов, необходимых для этого. ✨
index 58d5aa110ddb0a2fbcdae67daf72741907525f55..4195d689fee41e097cec02e02404e725d2258834 100644 (file)
@@ -1,12 +1,12 @@
 # О версиях FastAPI { #about-fastapi-versions }
 
-**FastAPI** Ñ\83же Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f Ð² Ð¿Ñ\80одакÑ\88ене во многих приложениях и системах. Покрытие тестами поддерживается на уровне 100%. Но его разработка всё ещё движется быстрыми темпами.
+**FastAPI** Ñ\83же Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f Ð² Ð¿Ñ\80одакÑ\88н во многих приложениях и системах. Покрытие тестами поддерживается на уровне 100%. Но его разработка всё ещё движется быстрыми темпами.
 
 Часто добавляются новые функции, регулярно исправляются баги, код продолжает постоянно совершенствоваться.
 
 По указанным причинам текущие версии до сих пор `0.x.x`. Это говорит о том, что каждая версия может содержать обратно несовместимые изменения, следуя <a href="https://semver.org/" class="external-link" target="_blank">Семантическому версионированию</a>.
 
-Уже Ñ\81ейÑ\87аÑ\81 Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ñ\81оздаваÑ\82Ñ\8c Ð¿Ñ\80иложениÑ\8f Ð² Ð¿Ñ\80одакÑ\88ене, используя **FastAPI** (и скорее всего так и делаете), главное убедиться в том, что вы используете версию, которая корректно работает с вашим кодом.
+Уже Ñ\81ейÑ\87аÑ\81 Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ñ\81оздаваÑ\82Ñ\8c Ð¿Ñ\80иложениÑ\8f Ð² Ð¿Ñ\80одакÑ\88н, используя **FastAPI** (и скорее всего так и делаете), главное убедиться в том, что вы используете версию, которая корректно работает с вашим кодом.
 
 ## Закрепите вашу версию `fastapi` { #pin-your-fastapi-version }
 
index 6291b79d26f78dda5aed095bf66ea905dddd076f..759127420f04657777dd02fa9f42dbfd2dedaac4 100644 (file)
@@ -161,7 +161,7 @@ Hello World from Python
 
 Эти переменные окружения могут работать только с **текстовыми строками**, поскольку они являются внешними по отношению к Python и должны быть совместимы с другими программами и остальной системой (и даже с различными операционными системами, такими как Linux, Windows, macOS).
 
-ЭÑ\82о Ð¾Ð·Ð½Ð°Ñ\87аеÑ\82, Ñ\87Ñ\82о **лÑ\8eбое Ð·Ð½Ð°Ñ\87ение**, Ñ\81Ñ\87иÑ\82анное Ð² Python Ð¸Ð· Ð¿ÐµÑ\80еменной Ð¾ÐºÑ\80Ñ\83жениÑ\8f, **бÑ\83деÑ\82 `str`**, Ð¸ Ð»Ñ\8eбое Ð¿Ñ\80еобÑ\80азование Ðº Ð´Ñ\80Ñ\83гомÑ\83 Ñ\82ипÑ\83 Ð¸Ð»Ð¸ Ð»Ñ\8eбаÑ\8f Ð¿Ñ\80овеÑ\80ка должны быть выполнены в коде.
+ЭÑ\82о Ð¾Ð·Ð½Ð°Ñ\87аеÑ\82, Ñ\87Ñ\82о **лÑ\8eбое Ð·Ð½Ð°Ñ\87ение**, Ñ\81Ñ\87иÑ\82анное Ð² Python Ð¸Ð· Ð¿ÐµÑ\80еменной Ð¾ÐºÑ\80Ñ\83жениÑ\8f, **бÑ\83деÑ\82 `str`**, Ð¸ Ð»Ñ\8eбое Ð¿Ñ\80еобÑ\80азование Ðº Ð´Ñ\80Ñ\83гомÑ\83 Ñ\82ипÑ\83 Ð¸Ð»Ð¸ Ð»Ñ\8eбаÑ\8f Ð²Ð°Ð»Ð¸Ð´Ð°Ñ\86иÑ\8f должны быть выполнены в коде.
 
 Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md){.internal-link target=_blank}.
 
index 72cf55e7b0b3679d39ac2f14dc347555ea3ad911..a46e0053eef89020a44d6ef2ace3259bf64a1b82 100644 (file)
@@ -52,7 +52,7 @@ FastAPI CLI берет путь к вашей Python-программе (нап
 
 Для работы в режиме продакшн вместо `fastapi dev` нужно использовать `fastapi run`. 🚀
 
-Внутри **FastAPI CLI** используется <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>, высокопроизводительный, готовый к работе в продакшне ASGI-сервер. 😎
+Внутри **FastAPI CLI** используется <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>, высокопроизводительный, готовый к работе в продакшн ASGI-сервер. 😎
 
 ## `fastapi dev` { #fastapi-dev }
 
index 703ff951ef2bdfdefefe8151a6eea2a86c649e94..0bc3dbb2d17df506ae8edcde0d826c5c06e36e99 100644 (file)
@@ -6,7 +6,7 @@
 
 ### Основано на открытых стандартах { #based-on-open-standards }
 
-* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> для создания API, включая объявления <abbr title="также известные как HTTP-методы, например: POST, GET, PUT, DELETE">операций</abbr> <abbr title="также известен как: эндпоинты, маршруты)">пути</abbr>, параметров, тел запросов, безопасности и т. д.
+* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> для создания API, включая объявления <dfn title="также известны как HTTP-методы, например: POST, GET, PUT, DELETE">операций</dfn> <dfn title="также известен как: эндпоинты, маршруты">пути</dfn>, параметров, тел запросов, безопасности и т.д.
 * Автоматическая документация моделей данных с помощью <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (так как сама спецификация OpenAPI основана на JSON Schema).
 * Разработан вокруг этих стандартов, после тщательного их изучения. Это не дополнительная надстройка поверх.
 * Это также позволяет использовать автоматическую **генерацию клиентского кода** на многих языках.
@@ -107,7 +107,7 @@ FastAPI имеет продуманные значения **по умолчан
     * Объекты JSON (`dict`).
     * Массив JSON (`list`) с определёнными типами элементов.
     * Строковые (`str`) поля с ограничением минимальной и максимальной длины.
-    * Числа (`int`, `float`) с минимальными и максимальными значениями и т. п.
+    * Числа (`int`, `float`) с минимальными и максимальными значениями и т.п.
 
 * Проверка для более экзотических типов, таких как:
     * URL.
@@ -126,24 +126,24 @@ FastAPI имеет продуманные значения **по умолчан
 * HTTP Basic.
 * **OAuth2** (также с **токенами JWT**). Ознакомьтесь с руководством [OAuth2 с JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
 * Ключи API в:
-    * Заголовках.
+    * HTTP-заголовках.
     * Параметрах запросов.
     * Cookies и т.п.
 
 Вдобавок все функции безопасности от Starlette (включая **сессионные cookies**).
 
-Все инструменты и компоненты спроектированы для многократного использования и легко интегрируются с вашими системами, хранилищами данных, реляционными и NoSQL базами данных и т. д.
+Все инструменты и компоненты спроектированы для многократного использования и легко интегрируются с вашими системами, хранилищами данных, реляционными и NoSQL базами данных и т.д.
 
 ### Внедрение зависимостей { #dependency-injection }
 
-FastAPI включает в себя чрезвычайно простую в использовании, но чрезвычайно мощную систему <abbr title='известную как: "components", "resources", "services", "providers"'><strong>Внедрения зависимостей</strong></abbr>.
+FastAPI включает в себя чрезвычайно простую в использовании, но чрезвычайно мощную систему <dfn title='также известна как: "компоненты", "ресурсы", "сервисы", "провайдеры"'><strong>Внедрения зависимостей</strong></dfn>.
 
 * Даже зависимости могут иметь зависимости, создавая иерархию или **«граф» зависимостей**.
 * Всё **автоматически обрабатывается** фреймворком.
 * Все зависимости могут запрашивать данные из запросов и **дополнять операции пути** ограничениями и автоматической документацией.
 * **Автоматическая проверка** даже для параметров *операций пути*, определённых в зависимостях.
-* Поддержка сложных систем аутентификации пользователей, **соединений с базами данных** и т. д.
-* **Никаких компромиссов** с базами данных, интерфейсами и т. д. Но при этом — лёгкая интеграция со всеми ними.
+* Поддержка сложных систем аутентификации пользователей, **соединений с базами данных** и т.д.
+* **Никаких компромиссов** с базами данных, интерфейсами и т.д. Но при этом — лёгкая интеграция со всеми ними.
 
 ### Нет ограничений на "Плагины" { #unlimited-plug-ins }
 
@@ -153,8 +153,8 @@ FastAPI включает в себя чрезвычайно простую в и
 
 ### Проверен { #tested }
 
-* 100% <abbr title="Количество автоматически проверяемого кода">покрытие тестами</abbr>.
-* 100% <abbr title="Аннотации типов Python, благодаря которым ваш редактор и внешние инструменты могут обеспечить вам лучшую поддержку">аннотирование типов</abbr> в кодовой базе.
+* 100% <dfn title="Количество автоматически проверяемого кода">покрытие тестами</dfn>.
+* 100% <dfn title="Аннотации типов Python, благодаря которым ваш редактор кода и внешние инструменты могут обеспечить вам лучшую поддержку">аннотирование типов</dfn> в кодовой базе.
 * Используется в продакшн‑приложениях.
 
 ## Возможности Starlette { #starlette-features }
@@ -179,7 +179,7 @@ FastAPI включает в себя чрезвычайно простую в и
 
 **FastAPI** полностью совместим с (и основан на) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Поэтому любой дополнительный код Pydantic, который у вас есть, также будет работать.
 
-Включая внешние библиотеки, также основанные на Pydantic, такие как <abbr title="Object-Relational Mapper">ORM</abbr>’ы, <abbr title="Object-Document Mapper">ODM</abbr>’ы для баз данных.
+Включая внешние библиотеки, также основанные на Pydantic, такие как <abbr title="Object-Relational Mapper - объектно-реляционный маппер">ORM</abbr>’ы, <abbr title="Object-Document Mapper - объектно-документный маппер">ODM</abbr>’ы для баз данных.
 
 Это также означает, что во многих случаях вы можете передавать тот же объект, который получили из запроса, **непосредственно в базу данных**, так как всё проверяется автоматически.
 
@@ -190,10 +190,10 @@ FastAPI включает в себя чрезвычайно простую в и
 * **Никакой нервотрёпки**:
     * Не нужно изучать новые схемы в микроязыках.
     * Если вы знаете типы в Python, вы знаете, как использовать Pydantic.
-* Прекрасно сочетается с вашим **<abbr title="Integrated Development Environment - Интегрированная среда разработки: попросту «редактора кода»">IDE</abbr>/<abbr title="Программа, проверяющая ошибки в коде">linter</abbr>/мозгом**:
+* Прекрасно сочетается с вашим **<abbr title="Integrated Development Environment - Интегрированная среда разработки: похоже на редактор кода">IDE</abbr>/<dfn title="Программа, которая проверяет код на ошибки">линтер</dfn>/мозгом**:
     * Потому что структуры данных pydantic — это всего лишь экземпляры классов, определённых вами; автозавершение, проверка кода, mypy и ваша интуиция — всё будет работать с вашими валидированными данными.
 * Валидация **сложных структур**:
-    * Использование иерархических моделей Pydantic; `List`, `Dict` и т. п. из модуля `typing` (входит в стандартную библиотеку Python).
+    * Использование иерархических моделей Pydantic; `List`, `Dict` и т.п. из модуля `typing` (входит в стандартную библиотеку Python).
     * Валидаторы позволяют чётко и легко определять, проверять и документировать сложные схемы данных в виде JSON Schema.
     * У вас могут быть глубоко **вложенные объекты JSON**, и все они будут проверены и аннотированы.
 * **Расширяемость**:
index 9cdd53376daeaee044ab069543b3122bf3d747e8..e2395fe8b935be8e39cb61123badb253faeb5d51 100644 (file)
@@ -30,7 +30,7 @@
 
 ## Исследования { #investigation }
 
\91лагодаÑ\80Ñ\8f Ð¾Ð¿Ñ\8bÑ\82Ñ\83 Ð¸Ñ\81полÑ\8cзованиÑ\8f Ñ\81Ñ\83Ñ\89еÑ\81Ñ\82вÑ\83Ñ\8eÑ\89иÑ\85 Ð°Ð»Ñ\8cÑ\82еÑ\80наÑ\82ив, Ð¼Ñ\8b Ñ\81 ÐºÐ¾Ð»Ð»ÐµÐ³Ð°Ð¼Ð¸ Ð¸Ð·Ñ\83Ñ\87или Ð¸Ñ\85 Ð¾Ñ\81новнÑ\8bе Ð¸Ð´ÐµÐ¸ Ð¸ Ñ\81комбиниÑ\80овали Ñ\81обÑ\80аннÑ\8bе Ð·Ð½Ð°Ð½Ð¸Ñ\8f Ð½Ð°Ð¸Ð»Ñ\83Ñ\87Ñ\88им Ð¾Ð±Ñ\80азом.
\98Ñ\81полÑ\8cзÑ\83Ñ\8f Ð²Ñ\81е Ñ\81Ñ\83Ñ\89еÑ\81Ñ\82вовавÑ\88ие Ñ\80анее Ð°Ð»Ñ\8cÑ\82еÑ\80наÑ\82ивÑ\8b, Ñ\8f Ð¿Ð¾Ð»Ñ\83Ñ\87ил Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾Ñ\81Ñ\82Ñ\8c Ñ\83 ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ð¸Ð· Ð½Ð¸Ñ\85 Ñ\87емÑ\83\82о Ð½Ð°Ñ\83Ñ\87иÑ\82Ñ\8cÑ\81Ñ\8f, Ð¿Ð¾Ð·Ð°Ð¸Ð¼Ñ\81Ñ\82воваÑ\82Ñ\8c Ð¸Ð´ÐµÐ¸ Ð¸ Ð¾Ð±Ñ\8aединиÑ\82Ñ\8c Ð¸Ñ\85 Ð½Ð°Ð¸Ð»Ñ\83Ñ\87Ñ\88им Ð¾Ð±Ñ\80азом Ð´Ð»Ñ\8f Ñ\81ебÑ\8f Ð¸ Ð´Ð»Ñ\8f ÐºÐ¾Ð¼Ð°Ð½Ð´ Ñ\80азÑ\80абоÑ\82Ñ\87иков, Ñ\81 ÐºÐ¾Ñ\82оÑ\80Ñ\8bми Ñ\8f Ñ\80абоÑ\82ал.
 
 Например, стало ясно, что необходимо брать за основу стандартные аннотации типов Python.
 
 
 Я проверил несколько идей на самых популярных редакторах кода: PyCharm, VS Code, редакторы на базе Jedi.
 
\94аннÑ\8bе Ð¿Ð¾ Ñ\80едакÑ\82оÑ\80ам Ñ\8f Ð²Ð·Ñ\8fл Ð¸Ð· <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">опÑ\80оÑ\81а Python-разработчиков</a>, который охватывает около 80% пользователей.
¡Ð¾Ð³Ð»Ð°Ñ\81но Ð¿Ð¾Ñ\81леднемÑ\83 <a href="https://www.jetbrains.com/research/python-developers-survey-2018/#development-tools" class="external-link" target="_blank">опÑ\80оÑ\81Ñ\83 Python-разработчиков</a>, который охватывает около 80% пользователей.
 
 Это означает, что **FastAPI** был специально проверен на редакторах, используемых 80% Python-разработчиками. И поскольку большинство других редакторов, как правило, работают аналогичным образом, все его преимущества должны работать практически для всех редакторов.
 
 Таким образом, я смог найти наилучшие способы сократить дублирование кода, обеспечить повсеместное автозавершение, проверку типов и ошибок и т.д.
 
-И все это, чтобы все пользователи могли получать наилучший опыт разработки.
+И все это, чтобы все разработчики могли получать наилучший опыт разработки.
 
 ## Зависимости { #requirements }
 
@@ -58,7 +58,7 @@
 
 По моим предложениям был изменён код этого фреймворка, чтобы сделать его полностью совместимым с JSON Schema, поддержать различные способы определения ограничений и улучшить поддержку в редакторах кода (проверки типов, автозавершение) на основе тестов в нескольких редакторах.
 
 то же время, я принимал участие в разработке <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>, ещё один из основных компонентов FastAPI.
о время разработки я также внес вклад в <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a>, другую ключевую зависимость.
 
 ## Разработка { #development }
 
index 5675cecc52036609f637dd2c0917c3280d87eeff..596563c541d7a66589232cac6a52107ee561d771 100644 (file)
@@ -8,7 +8,7 @@
 
 Например, вы можете создать подкласс `HTTPBearer`, который будет возвращать ошибку `403 Forbidden` вместо стандартной `401 Unauthorized`:
 
-{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
+{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
 
 /// tip | Совет
 
index d0845b91e27420d01f3a520111be9c9924624e37..6efa30608e7c4219c063f9f62da47cf7cee65750 100644 (file)
@@ -4,9 +4,9 @@
 
 ## О безопасности, API и документации { #about-security-apis-and-docs }
 
-Скрытие пользовательских интерфейсов документации в продакшн *не должно* быть способом защиты вашего API.
+Скрытие пользовательских интерфейсов документации в продакшн не должно быть способом защиты вашего API.
 
-Это не добавляет дополнительной безопасности вашему API, *операции пути* (обработчики пути) всё равно будут доступны по своим путям.
+Это не добавляет дополнительной безопасности вашему API, операции пути (обработчики пути) всё равно будут доступны по своим путям.
 
 Если в вашем коде есть уязвимость, она всё равно останется.
 
@@ -29,7 +29,7 @@
 
 Например:
 
-{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
 
 Здесь мы объявляем настройку `openapi_url` с тем же значением по умолчанию — `"/openapi.json"`.
 
index b3b1c1ba6241e8153946a1c5d5f05bc26802d076..f4f2a0e549a959a10b38fb281e7e858a7347391a 100644 (file)
@@ -18,7 +18,7 @@ FastAPI преобразует эти настройки в **JSON**, чтобы
 
 Но вы можете отключить её, установив `syntaxHighlight` в `False`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
 
 …и после этого Swagger UI больше не будет показывать подсветку синтаксиса:
 
@@ -28,7 +28,7 @@ FastAPI преобразует эти настройки в **JSON**, чтобы
 
 Аналогично вы можете задать тему подсветки синтаксиса с ключом "syntaxHighlight.theme" (обратите внимание, что посередине стоит точка):
 
-{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
 
 Эта настройка изменит цветовую тему подсветки синтаксиса:
 
@@ -46,7 +46,7 @@ FastAPI включает некоторые параметры конфигур
 
 Например, чтобы отключить `deepLinking`, можно передать такие настройки в `swagger_ui_parameters`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
 
 ## Другие параметры Swagger UI { #other-swagger-ui-parameters }
 
index f524911e65129c6f435a5cded5713f891148fa5c..e3c31b32c5a6b64d5c1c19b5ffc64ac8eb902af7 100644 (file)
@@ -18,7 +18,7 @@
 
 Чтобы отключить её, установите их URL в значение `None` при создании вашего приложения `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
 
 ### Подключить пользовательскую документацию { #include-the-custom-docs }
 
@@ -34,7 +34,7 @@
 
 Аналогично и для ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
 
 /// tip | Совет
 
@@ -50,7 +50,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Чтобы убедиться, что всё работает, создайте *операцию пути*:
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
 
 ### Тестирование { #test-it }
 
@@ -118,7 +118,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 * Импортируйте `StaticFiles`.
 * Смонтируйте экземпляр `StaticFiles()` в определённый путь.
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
 
 ### Протестируйте статические файлы { #test-the-static-files }
 
@@ -144,7 +144,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Чтобы отключить её, установите их URL в значение `None` при создании вашего приложения `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
 
 ### Подключить пользовательскую документацию со статическими файлами { #include-the-custom-docs-for-static-files }
 
@@ -160,7 +160,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Аналогично и для ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
 
 /// tip | Совет
 
@@ -176,7 +176,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Чтобы убедиться, что всё работает, создайте *операцию пути*:
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
 
 ### Тестирование UI со статическими файлами { #test-static-files-ui }
 
index 1d69cbdb3a9c43baf2b4a1ab115226a66ef71581..197a1790a25bfbe90ea37f53d7907f2bbbb061d1 100644 (file)
@@ -24,7 +24,7 @@
 * `version`: Версия вашего API, например `2.5.0`.
 * `openapi_version`: Версия используемой спецификации OpenAPI. По умолчанию — последняя: `3.1.0`.
 * `summary`: Краткое описание API.
-* `description`: Описание вашего API; может включать Markdown и будет отображается в документации.
+* `description`: Описание вашего API; может включать Markdown и будет отображаться в документации.
 * `routes`: Список маршрутов — это каждая зарегистрированная *операция пути*. Берутся из `app.routes`.
 
 /// info | Информация
 
 Сначала напишите приложение **FastAPI** как обычно:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
 
 ### Сгенерируйте схему OpenAPI { #generate-the-openapi-schema }
 
 Затем используйте ту же вспомогательную функцию для генерации схемы OpenAPI внутри функции `custom_openapi()`:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
 
 ### Измените схему OpenAPI { #modify-the-openapi-schema }
 
 Теперь можно добавить расширение ReDoc, добавив кастомный `x-logo` в «объект» `info` в схеме OpenAPI:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
 
 ### Кэшируйте схему OpenAPI { #cache-the-openapi-schema }
 
 
 Она будет создана один раз, а затем тот же кэшированный вариант будет использоваться для последующих запросов.
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
 
 ### Переопределите метод { #override-the-method }
 
 Теперь вы можете заменить метод `.openapi()` на вашу новую функцию.
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
 
 ### Проверьте { #check-it }
 
index 50c321e7dd9211a20c1bdc935538c0c02f40eca4..9e28d61822bfe7f932971ffa73744539ce280ac7 100644 (file)
@@ -35,7 +35,7 @@
 
 Вот небольшой пример того, как можно интегрировать Strawberry с FastAPI:
 
-{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
+{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
 
 Подробнее о Strawberry можно узнать в <a href="https://strawberry.rocks/" class="external-link" target="_blank">документации Strawberry</a>.
 
index 228c125dde77c3def177a87d30cbb7a06227e376..75e7fff265d0ebee13c18072ef40993787735b3e 100644 (file)
@@ -1,13 +1,13 @@
 # Как сделать — Рецепты { #how-to-recipes }
 
-Здесь вы найдете разные рецепты и руководства «как сделать» по различным темам.
+Здесь вы найдете разные рецепты и руководства «как сделать» по **различным темам**.
 
-Большинство из этих идей более-менее независимы, и в большинстве случаев вам стоит изучать их только если они напрямую относятся к вашему проекту.
+Большинство из этих идей более-менее **независимы**, и в большинстве случаев вам стоит изучать их только если они напрямую относятся к **вашему проекту**.
 
 Если что-то кажется интересным и полезным для вашего проекта, смело изучайте; в противном случае, вероятно, можно просто пропустить.
 
 /// tip | Совет
 
-Если вы хотите изучить FastAPI структурированно (рекомендуется), вместо этого читайте [Учебник — Руководство пользователя](../tutorial/index.md){.internal-link target=_blank} по главам.
+Если вы хотите **изучить FastAPI** структурированно (рекомендуется), вместо этого читайте [Учебник — Руководство пользователя](../tutorial/index.md){.internal-link target=_blank} по главам.
 
 ///
index b1a0c9a2e99696aa30aaeae7171648c0df873ca5..877014a08623a38fd19e385bfeaca77833dbd605 100644 (file)
@@ -40,7 +40,7 @@ FastAPI — это современный, быстрый (высокопрои
 * **Скорость**: Очень высокая производительность, на уровне **NodeJS** и **Go** (благодаря Starlette и Pydantic). [Один из самых быстрых доступных фреймворков Python](#performance).
 * **Быстрота разработки**: Увеличьте скорость разработки фич примерно на 200–300%. *
 * **Меньше ошибок**: Сократите примерно на 40% количество ошибок, вызванных человеком (разработчиком). *
-* **Интуитивность**: Отличная поддержка редактора кода. <abbr title="также известное как: автодополнение, автозавершение, IntelliSense">Автозавершение</abbr> везде. Меньше времени на отладку.
+* **Интуитивность**: Отличная поддержка редактора кода. <dfn title="также известное как: автодополнение, автозавершение, IntelliSense">Автозавершение</dfn> везде. Меньше времени на отладку.
 * **Простота**: Разработан так, чтобы его было легко использовать и осваивать. Меньше времени на чтение документации.
 * **Краткость**: Минимизируйте дублирование кода. Несколько возможностей из каждого объявления параметров. Меньше ошибок.
 * **Надежность**: Получите код, готовый к продакшн. С автоматической интерактивной документацией.
@@ -127,7 +127,7 @@ FastAPI — это современный, быстрый (высокопрои
 
 <a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
 
-Если вы создаёте приложение <abbr title="Command Line Interface  Интерфейс командной строки">CLI</abbr> для использования в терминале вместо веб-API, посмотрите <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
+Если вы создаёте приложение <abbr title="Command Line Interface - Интерфейс командной строки">CLI</abbr> для использования в терминале вместо веб-API, посмотрите <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
 
 **Typer** — младший брат FastAPI. И он задуман как **FastAPI для CLI**. ⌨️ 🚀
 
@@ -368,7 +368,7 @@ item: Item
 * Валидацию данных:
     * Автоматические и понятные ошибки, когда данные некорректны.
     * Валидацию даже для глубоко вложенных объектов JSON.
-* <abbr title="также известное как: сериализация, парсинг, маршалинг">Преобразование</abbr> входных данных: из сети в данные и типы Python. Чтение из:
+* <dfn title="также известное как: сериализация, парсинг, маршалинг">Преобразование</dfn> входных данных: из сети в данные и типы Python. Чтение из:
     * JSON.
     * Параметров пути.
     * Параметров запроса.
@@ -376,7 +376,7 @@ item: Item
     * HTTP-заголовков.
     * Форм.
     * Файлов.
-* <abbr title="также известное как: сериализация, парсинг, маршалинг">Преобразование</abbr> выходных данных: из данных и типов Python в данные сети (например, JSON):
+* <dfn title="также известное как: сериализация, парсинг, маршалинг">Преобразование</dfn> выходных данных: из данных и типов Python в данные сети (например, JSON):
     * Преобразование типов Python (`str`, `int`, `float`, `bool`, `list` и т.д.).
     * Объекты `datetime`.
     * Объекты `UUID`.
@@ -439,7 +439,7 @@ item: Item
 
 * Объявление **параметров** из других источников: **HTTP-заголовки**, **cookies**, **поля формы** и **файлы**.
 * Как задать **ограничения валидации** вроде `maximum_length` или `regex`.
-* Очень мощную и простую в использовании систему **<abbr title="также известна как: компоненты, ресурсы, провайдеры, сервисы, инъекции">внедрения зависимостей</abbr>**.
+* Очень мощную и простую в использовании систему **<dfn title="также известна как: компоненты, ресурсы, провайдеры, сервисы, инъекции">внедрения зависимостей</dfn>**.
 * Безопасность и аутентификацию, включая поддержку **OAuth2** с **JWT токенами** и **HTTP Basic** аутентификацию.
 * Более продвинутые (но столь же простые) приёмы объявления **глубоко вложенных JSON-моделей** (спасибо Pydantic).
 * Интеграцию **GraphQL** с <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> и другими библиотеками.
@@ -524,7 +524,7 @@ FastAPI зависит от Pydantic и Starlette.
 
 * <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> — обязателен, если вы хотите использовать `TestClient`.
 * <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> — обязателен, если вы хотите использовать конфигурацию шаблонов по умолчанию.
-* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - обязателен, если вы хотите поддерживать <abbr title="преобразование строки, полученной из HTTP-запроса, в данные Python">«парсинг»</abbr> форм через `request.form()`.
+* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - обязателен, если вы хотите поддерживать <dfn title="преобразование строки, полученной из HTTP-запроса, в данные Python">«парсинг»</dfn> форм через `request.form()`.
 
 Используется FastAPI:
 
index dbedf76fe35cc1ea50bc928746227707da98968e..8155457e387e1152e9ae3cc75eab5622a1fe7275 100644 (file)
@@ -18,7 +18,7 @@
     - 🤖 Автоматически сгенерированный фронтенд‑клиент.
     - 🧪 [Playwright](https://playwright.dev) для End‑to‑End тестирования.
     - 🦇 Поддержка тёмной темы.
-- 🐋 [Docker Compose](https://www.docker.com) для разработки и продакшна.
+- 🐋 [Docker Compose](https://www.docker.com) для разработки и продакшн.
 - 🔒 Безопасное хэширование паролей по умолчанию.
 - 🔑 Аутентификация по JWT‑токенам.
 - 📫 Восстановление пароля по электронной почте.
index ae4a1e2b79c519a6931a3cff6a0cc99f1fe99d9b..95153c3882b33196231a91a939369c3d7aa2e500 100644 (file)
@@ -2,7 +2,7 @@
 
 Python поддерживает необязательные «подсказки типов» (их также называют «аннотациями типов»).
 
-Эти **«подсказки типов»** или аннотации — это специальный синтаксис, позволяющий объявлять <abbr title="например: str, int, float, bool">тип</abbr> переменной.
+Эти **«подсказки типов»** или аннотации — это специальный синтаксис, позволяющий объявлять <dfn title="например: str, int, float, bool">тип</dfn> переменной.
 
 Объявляя типы для ваших переменных, редакторы кода и инструменты смогут лучше вас поддерживать.
 
@@ -22,7 +22,7 @@ Python поддерживает необязательные «подсказк
 
 Давайте начнем с простого примера:
 
-{* ../../docs_src/python_types/tutorial001_py39.py *}
+{* ../../docs_src/python_types/tutorial001_py310.py *}
 
 Вызов этой программы выводит:
 
@@ -34,9 +34,9 @@ John Doe
 
 * Принимает `first_name` и `last_name`.
 * Преобразует первую букву каждого значения в верхний регистр с помощью `title()`.
-* <abbr title="Объединяет в одно целое. Содержимое одного — сразу после другого.">Соединяет</abbr> их пробелом посередине.
+* <dfn title="Соединяет их в одно. Содержимое одного — сразу после другого.">Соединяет</dfn> их пробелом посередине.
 
-{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
 
 ### Отредактируем пример { #edit-it }
 
@@ -78,7 +78,7 @@ John Doe
 
 Это и есть «подсказки типов»:
 
-{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
 
 Это не то же самое, что объявление значений по умолчанию, как, например:
 
@@ -106,7 +106,7 @@ John Doe
 
 Посмотрите на эту функцию — у неё уже есть подсказки типов:
 
-{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
 
 Так как редактор кода знает типы переменных, вы получаете не только автозавершение, но и проверки ошибок:
 
@@ -114,7 +114,7 @@ John Doe
 
 Теперь вы знаете, что нужно исправить — преобразовать `age` в строку с помощью `str(age)`:
 
-{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
 
 ## Объявление типов { #declaring-types }
 
@@ -133,29 +133,32 @@ John Doe
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
 
-### Generic-типы с параметрами типов { #generic-types-with-type-parameters }
+### Модуль `typing` { #typing-module }
 
\95Ñ\81Ñ\82Ñ\8c Ñ\81Ñ\82Ñ\80Ñ\83кÑ\82Ñ\83Ñ\80Ñ\8b Ð´Ð°Ð½Ð½Ñ\8bÑ\85, ÐºÐ¾Ñ\82оÑ\80Ñ\8bе Ð¼Ð¾Ð³Ñ\83Ñ\82 Ñ\81одеÑ\80жаÑ\82Ñ\8c Ð´Ñ\80Ñ\83гие Ð·Ð½Ð°Ñ\87ениÑ\8f, Ð½Ð°Ð¿Ñ\80имеÑ\80, `dict`, `list`, `set` Ð¸ `tuple`. Ð\98 Ð²Ð½Ñ\83Ñ\82Ñ\80енние Ð·Ð½Ð°Ñ\87ениÑ\8f Ñ\82оже Ð¼Ð¾Ð³Ñ\83Ñ\82 Ð¸Ð¼ÐµÑ\82Ñ\8c Ñ\81вой Ñ\82ип.
\94лÑ\8f Ð½ÐµÐºÐ¾Ñ\82оÑ\80Ñ\8bÑ\85 Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ\82елÑ\8cнÑ\8bÑ\85 Ñ\81Ñ\86енаÑ\80иев Ð¼Ð¾Ð¶ÐµÑ\82 Ð¿Ð¾Ð½Ð°Ð´Ð¾Ð±Ð¸Ñ\82Ñ\8cÑ\81Ñ\8f Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82иÑ\80оваÑ\82Ñ\8c Ñ\87Ñ\82о-Ñ\82о Ð¸Ð· Ñ\81Ñ\82андаÑ\80Ñ\82ного Ð¼Ð¾Ð´Ñ\83лÑ\8f `typing`. Ð\9dапÑ\80имеÑ\80, ÐºÐ¾Ð³Ð´Ð° Ð²Ñ\8b Ñ\85оÑ\82иÑ\82е Ð¾Ð±Ñ\8aÑ\8fвиÑ\82Ñ\8c, Ñ\87Ñ\82о Ñ\87Ñ\82о-Ñ\82о Ð¸Ð¼ÐµÐµÑ\82 Â«Ð»Ñ\8eбой Ñ\82ип», Ð¼Ð¾Ð¶Ð½Ð¾ Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c `Any` Ð¸Ð· `typing`:
 
-Такие типы, которые содержат внутренние типы, называют «**generic**»-типами. И их можно объявлять, в том числе с указанием внутренних типов.
+```python
+from typing import Any
 
-Чтобы объявлять эти типы и их внутренние типы, вы можете использовать стандартный модуль Python `typing`. Он существует специально для поддержки подсказок типов.
 
-#### Новые версии Python { #newer-versions-of-python }
-
-Синтаксис с использованием `typing` **совместим** со всеми версиями, от Python 3.6 до самых новых, включая Python 3.9, Python 3.10 и т.д.
+def some_function(data: Any):
+    print(data)
+```
 
-По мере развития Python **новые версии** получают улучшенную поддержку этих аннотаций типов, и во многих случаях вам даже не нужно импортировать и использовать модуль `typing`, чтобы объявлять аннотации типов.
+### Generic-типы { #generic-types }
 
\95Ñ\81ли Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð²Ñ\8bбÑ\80аÑ\82Ñ\8c Ð±Ð¾Ð»ÐµÐµ Ñ\81вежÑ\83Ñ\8e Ð²ÐµÑ\80Ñ\81иÑ\8e Python Ð´Ð»Ñ\8f Ð¿Ñ\80оекÑ\82а, Ð²Ñ\8b Ð¿Ð¾Ð»Ñ\83Ñ\87иÑ\82е Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ\82елÑ\8cнÑ\83Ñ\8e Ð¿Ñ\80оÑ\81Ñ\82оÑ\82Ñ\83.
\9dекоÑ\82оÑ\80Ñ\8bе Ñ\82ипÑ\8b Ð¼Ð¾Ð³Ñ\83Ñ\82 Ð¿Ñ\80инимаÑ\82Ñ\8c Â«Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ñ\82ипов» Ð² ÐºÐ²Ð°Ð´Ñ\80аÑ\82нÑ\8bÑ\85 Ñ\81кобкаÑ\85, Ñ\87Ñ\82обÑ\8b Ð¾Ð¿Ñ\80еделиÑ\82Ñ\8c Ð¸Ñ\85 Ð²Ð½Ñ\83Ñ\82Ñ\80енние Ñ\82ипÑ\8b. Ð\9dапÑ\80имеÑ\80, Â«Ñ\81пиÑ\81ок Ñ\81Ñ\82Ñ\80ок» Ð¾Ð±Ñ\8aÑ\8fвлÑ\8fеÑ\82Ñ\81Ñ\8f ÐºÐ°Ðº `list[str]`.
 
\92о Ð²Ñ\81ей Ð´Ð¾ÐºÑ\83менÑ\82аÑ\86ии ÐµÑ\81Ñ\82Ñ\8c Ð¿Ñ\80имеÑ\80Ñ\8b, Ñ\81овмеÑ\81Ñ\82имÑ\8bе Ñ\81 ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ð²ÐµÑ\80Ñ\81ией Python (когда ÐµÑ\81Ñ\82Ñ\8c Ñ\80азлиÑ\87иÑ\8f).
¢Ð°ÐºÐ¸Ðµ Ñ\82ипÑ\8b, ÐºÐ¾Ñ\82оÑ\80Ñ\8bе Ð¿Ñ\80инимаÑ\8eÑ\82 Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ñ\82ипов, Ð½Ð°Ð·Ñ\8bваÑ\8eÑ\82Ñ\81Ñ\8f **Generic-Ñ\82ипами** Ð¸Ð»Ð¸ **Generics**.
 
\9dапÑ\80имеÑ\80, Â«**Python 3.6+**» Ð¾Ð·Ð½Ð°Ñ\87аеÑ\82 Ñ\81овмеÑ\81Ñ\82имоÑ\81Ñ\82Ñ\8c Ñ\81 Python 3.6 Ð¸ Ð²Ñ\8bÑ\88е (вклÑ\8eÑ\87аÑ\8f 3.7, 3.8, 3.9, 3.10 Ð¸ Ñ\82.д.). Ð\90 Â«**Python 3.9+**» â\80\94 Ñ\81овмеÑ\81Ñ\82имоÑ\81Ñ\82Ñ\8c Ñ\81 Python 3.9 Ð¸ Ð²Ñ\8bÑ\88е (вклÑ\8eÑ\87аÑ\8f 3.10 Ð¸ Ñ\82.п.).
\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ñ\82е Ð¶Ðµ Ð²Ñ\81Ñ\82Ñ\80оеннÑ\8bе Ñ\82ипÑ\8b ÐºÐ°Ðº generics (Ñ\81 ÐºÐ²Ð°Ð´Ñ\80аÑ\82нÑ\8bми Ñ\81кобками Ð¸ Ñ\82ипами Ð²Ð½Ñ\83Ñ\82Ñ\80и):
 
-Если вы можете использовать **последние версии Python**, используйте примеры для самой новой версии — у них будет **самый лучший и простой синтаксис**, например, «**Python 3.10+**».
+* `list`
+* `tuple`
+* `set`
+* `dict`
 
 #### List { #list }
 
@@ -167,7 +170,7 @@ John Doe
 
 Так как список — это тип, содержащий внутренние типы, укажите их в квадратных скобках:
 
-{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
 
 /// info | Информация
 
@@ -193,7 +196,7 @@ John Doe
 
 Аналогично вы бы объявили `tuple` и `set`:
 
-{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
 
 Это означает:
 
@@ -208,7 +211,7 @@ John Doe
 
 Второй параметр типа — для значений `dict`:
 
-{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
 
 Это означает:
 
@@ -220,44 +223,20 @@ John Doe
 
 Вы можете объявить, что переменная может быть **одним из нескольких типов**, например, `int` или `str`.
 
-В Python 3.6 и выше (включая Python 3.10) вы можете использовать тип `Union` из `typing` и перечислить в квадратных скобках все допустимые типы.
-
-В Python 3.10 также появился **новый синтаксис**, где допустимые типы можно указать через <abbr title='также называется «побитовый оператор OR», но это значение здесь нерелевантно'>вертикальную черту (`|`)</abbr>.
+Чтобы это определить, используйте <dfn title='также называется «побитовый оператор OR», но это значение здесь нерелевантно'>вертикальную черту (`|`)</dfn> для разделения обоих типов.
 
-//// tab | Python 3.10+
+Это называется «объединение» (union), потому что переменная может быть чем угодно из объединения этих двух множеств типов.
 
 ```Python hl_lines="1"
 {!> ../../docs_src/python_types/tutorial008b_py310.py!}
 ```
 
-////
-
-//// tab | Python 3.9+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008b_py39.py!}
-```
-
-////
-
-В обоих случаях это означает, что `item` может быть `int` или `str`.
+Это означает, что `item` может быть `int` или `str`.
 
 #### Возможно `None` { #possibly-none }
 
 Вы можете объявить, что значение может иметь определённый тип, например `str`, но также может быть и `None`.
 
-В Python 3.6 и выше (включая Python 3.10) это можно объявить, импортировав и используя `Optional` из модуля `typing`.
-
-```Python hl_lines="1  4"
-{!../../docs_src/python_types/tutorial009_py39.py!}
-```
-
-Использование `Optional[str]` вместо просто `str` позволит редактору кода помочь вам обнаружить ошибки, когда вы предполагаете, что значение всегда `str`, хотя на самом деле оно может быть и `None`.
-
-`Optional[Something]` — это на самом деле сокращение для `Union[Something, None]`, они эквивалентны.
-
-Это также означает, что в Python 3.10 вы можете использовать `Something | None`:
-
 //// tab | Python 3.10+
 
 ```Python hl_lines="1"
@@ -266,96 +245,7 @@ John Doe
 
 ////
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009_py39.py!}
-```
-
-////
-
-//// tab | Python 3.9+ альтернативный вариант
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009b_py39.py!}
-```
-
-////
-
-#### Использовать `Union` или `Optional` { #using-union-or-optional }
-
-Если вы используете версию Python ниже 3.10, вот совет с моей весьма **субъективной** точки зрения:
-
-* 🚨 Избегайте использования `Optional[SomeType]`
-* Вместо этого ✨ **используйте `Union[SomeType, None]`** ✨.
-
-Оба варианта эквивалентны и внутри одинаковы, но я бы рекомендовал `Union` вместо `Optional`, потому что слово «**optional**» («необязательный») может навести на мысль, что значение необязательное, хотя на самом деле оно означает «может быть `None`», даже если параметр не является необязательным и всё ещё обязателен.
-
-Мне кажется, `Union[SomeType, None]` более явно выражает смысл.
-
-Речь только о словах и названиях. Но эти слова могут влиять на то, как вы и ваши коллеги думаете о коде.
-
-В качестве примера возьмём эту функцию:
-
-{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
-
-Параметр `name` определён как `Optional[str]`, но он **не необязательный** — вы не можете вызвать функцию без этого параметра:
-
-```Python
-say_hi()  # О нет, это вызывает ошибку! 😱
-```
-
-Параметр `name` всё ещё **обязателен** (не *optional*), потому что у него нет значения по умолчанию. При этом `name` принимает `None` как значение:
-
-```Python
-say_hi(name=None)  # Это работает, None допустим 🎉
-```
-
-Хорошая новость: как только вы перейдёте на Python 3.10, об этом можно не переживать — вы сможете просто использовать `|` для объединения типов:
-
-{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
-
-И тогда вам не придётся задумываться о названиях вроде `Optional` и `Union`. 😎
-
-#### Generic-типы { #generic-types }
-
-Типы, которые принимают параметры типов в квадратных скобках, называются **Generic-типами** или **Generics**, например:
-
-//// tab | Python 3.10+
-
-Вы можете использовать те же встроенные типы как generics (с квадратными скобками и типами внутри):
-
-* `list`
-* `tuple`
-* `set`
-* `dict`
-
-И, как и в предыдущих версиях Python, из модуля `typing`:
-
-* `Union`
-* `Optional`
-* ...и другие.
-
-В Python 3.10, как альтернативу generics `Union` и `Optional`, можно использовать <abbr title='также называется «побитовый оператор OR», но это значение здесь нерелевантно'>вертикальную черту (`|`)</abbr> для объявления объединений типов — это гораздо лучше и проще.
-
-////
-
-//// tab | Python 3.9+
-
-Вы можете использовать те же встроенные типы как generics (с квадратными скобками и типами внутри):
-
-* `list`
-* `tuple`
-* `set`
-* `dict`
-
-И generics из модуля `typing`:
-
-* `Union`
-* `Optional`
-* ...и другие.
-
-////
+Использование `str | None` вместо просто `str` позволит редактору кода помочь вам обнаружить ошибки, когда вы предполагаете, что значение всегда `str`, хотя на самом деле оно может быть и `None`.
 
 ### Классы как типы { #classes-as-types }
 
@@ -363,11 +253,11 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 
 Допустим, у вас есть класс `Person` с именем:
 
-{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
 
 Тогда вы можете объявить переменную типа `Person`:
 
-{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
 
 И снова вы получите полную поддержку редактора кода:
 
@@ -401,21 +291,15 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 
 **FastAPI** целиком основан на Pydantic.
 
-Вы увидите намного больше всего этого на практике в [Руководстве пользователя](tutorial/index.md){.internal-link target=_blank}.
-
-/// tip | Совет
-
-У Pydantic есть особое поведение, когда вы используете `Optional` или `Union[Something, None]` без значения по умолчанию. Подробнее читайте в документации Pydantic: <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a>.
-
-///
+Вы увидите намного больше всего этого на практике в [Учебник - Руководство пользователя](tutorial/index.md){.internal-link target=_blank}.
 
 ## Подсказки типов с аннотациями метаданных { #type-hints-with-metadata-annotations }
 
-В Python также есть возможность добавлять **дополнительные <abbr title="Данные о данных, в данном случае — информация о типе, например описание.">метаданные</abbr>** к подсказкам типов с помощью `Annotated`.
+В Python также есть возможность добавлять **дополнительные <dfn title="Данные о данных, в данном случае — информация о типе, например описание.">метаданные</dfn>** к подсказкам типов с помощью `Annotated`.
 
\9dаÑ\87инаÑ\8f Ñ\81 Python 3.9, `Annotated` Ð²Ñ\85одиÑ\82 Ð² Ñ\81Ñ\82андаÑ\80Ñ\82нÑ\83Ñ\8e Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ\82екÑ\83, Ð¿Ð¾Ñ\8dÑ\82омÑ\83 Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82иÑ\80оваÑ\82Ñ\8c ÐµÐ³Ð¾ из `typing`.
\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð¸Ð¼Ð¿Ð¾Ñ\80Ñ\82иÑ\80оваÑ\82Ñ\8c `Annotated` из `typing`.
 
-{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
 
 Сам Python ничего не делает с `Annotated`. А для редакторов кода и других инструментов тип по-прежнему `str`.
 
@@ -453,7 +337,7 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 * **Документирования** API с использованием OpenAPI:
     * что затем используется пользовательскими интерфейсами автоматической интерактивной документации.
 
\92Ñ\81Ñ\91 Ñ\8dÑ\82о Ð¼Ð¾Ð¶ÐµÑ\82 Ð·Ð²Ñ\83Ñ\87аÑ\82Ñ\8c Ð°Ð±Ñ\81Ñ\82Ñ\80акÑ\82но. Ð\9dе Ð²Ð¾Ð»Ð½Ñ\83йÑ\82еÑ\81Ñ\8c. Ð\92Ñ\8b Ñ\83видиÑ\82е Ð²Ñ\81Ñ\91 Ñ\8dÑ\82о Ð² Ð´ÐµÐ¹Ñ\81Ñ\82вии Ð² [РÑ\83ководÑ\81Ñ\82ве пользователя](tutorial/index.md){.internal-link target=_blank}.
\92Ñ\81Ñ\91 Ñ\8dÑ\82о Ð¼Ð¾Ð¶ÐµÑ\82 Ð·Ð²Ñ\83Ñ\87аÑ\82Ñ\8c Ð°Ð±Ñ\81Ñ\82Ñ\80акÑ\82но. Ð\9dе Ð²Ð¾Ð»Ð½Ñ\83йÑ\82еÑ\81Ñ\8c. Ð\92Ñ\8b Ñ\83видиÑ\82е Ð²Ñ\81Ñ\91 Ñ\8dÑ\82о Ð² Ð´ÐµÐ¹Ñ\81Ñ\82вии Ð² [УÑ\87ебник - Ð Ñ\83ководÑ\81Ñ\82во пользователя](tutorial/index.md){.internal-link target=_blank}.
 
 Важно то, что, используя стандартные типы Python в одном месте (вместо добавления дополнительных классов, декораторов и т.д.), **FastAPI** сделает за вас большую часть работы.
 
index 8d7b7442f91d910e8ec4ba94513a42e0f1eb1b26..9fa7a850291b98821f46d36a2abade698b358bb5 100644 (file)
@@ -15,7 +15,7 @@
 
 Сначала импортируйте `BackgroundTasks` и объявите параметр в вашей функции‑обработчике пути с типом `BackgroundTasks`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
 
 **FastAPI** создаст объект типа `BackgroundTasks` для вас и передаст его через этот параметр.
 
 
 Так как операция записи не использует `async` и `await`, мы определим функцию как обычную `def`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
 
 ## Добавление фоновой задачи { #add-the-background-task }
 
 Внутри вашей функции‑обработчика пути передайте функцию задачи объекту фоновых задач методом `.add_task()`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
 
 `.add_task()` принимает следующие аргументы:
 
@@ -47,7 +47,7 @@
 
 ## Встраивание зависимостей { #dependency-injection }
 
-Использование `BackgroundTasks` также работает с системой встраивания зависимостей, вы можете объявить параметр типа `BackgroundTasks` на нескольких уровнях: в функции‑обработчике пути, в зависимости (dependable), в подзависимости и т. д.
+Использование `BackgroundTasks` также работает с системой встраивания зависимостей, вы можете объявить параметр типа `BackgroundTasks` на нескольких уровнях: в функции‑обработчике пути, в зависимости (dependable), в подзависимости и т.д.
 
 **FastAPI** знает, что делать в каждом случае и как переиспользовать один и тот же объект, так чтобы все фоновые задачи были объединены и затем выполнены в фоне:
 
@@ -73,7 +73,7 @@
 
 ## Предостережение { #caveat }
 
-Если вам нужно выполнять тяжелые вычисления в фоне, и при этом они не обязательно должны запускаться тем же процессом (например, вам не нужно делиться памятью, переменными и т. п.), вам могут подойти более мощные инструменты, такие как <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>.
+Если вам нужно выполнять тяжелые вычисления в фоне, и при этом они не обязательно должны запускаться тем же процессом (например, вам не нужно делиться памятью, переменными и т.п.), вам могут подойти более мощные инструменты, такие как <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>.
 
 Они обычно требуют более сложной конфигурации, менеджера очереди сообщений/заданий (например, RabbitMQ или Redis), но позволяют запускать фоновые задачи в нескольких процессах и, что особенно важно, на нескольких серверах.
 
index 76304523c951fa4c14c2a2f712451b8c50e92936..3fb36d5a227ac5f918ac0970b5b7562cbf0bc3e9 100644 (file)
@@ -85,7 +85,7 @@ from app.routers import items
 
 Точно так же, как и в случае с классом `FastAPI`, вам нужно импортировать и создать его «экземпляр»:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
 
 ### *Операции пути* с `APIRouter` { #path-operations-with-apirouter }
 
@@ -93,7 +93,7 @@ from app.routers import items
 
 Используйте его так же, как вы использовали бы класс `FastAPI`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
 
 Вы можете думать об `APIRouter` как об «мини-классе `FastAPI`».
 
@@ -117,7 +117,7 @@ from app.routers import items
 
 Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомный HTTP-заголовок `X-Token`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
 
 /// tip | Подсказка
 
@@ -149,7 +149,7 @@ from app.routers import items
 
 Таким образом, вместо того чтобы добавлять всё это в каждую *операцию пути*, мы можем добавить это в `APIRouter`.
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
 
 Так как путь каждой *операции пути* должен начинаться с `/`, как здесь:
 
@@ -208,7 +208,7 @@ async def read_item(item_id: str):
 
 Поэтому мы используем относительный импорт с `..` для зависимостей:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
 
 #### Как работает относительный импорт { #how-relative-imports-work }
 
@@ -279,7 +279,7 @@ from ...dependencies import get_token_header
 
 Но мы всё равно можем добавить _ещё_ `tags`, которые будут применяться к конкретной *операции пути*, а также дополнительные `responses`, специфичные для этой *операции пути*:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
 
 /// tip | Подсказка
 
@@ -305,13 +305,13 @@ from ...dependencies import get_token_header
 
 И мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого `APIRouter`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
 
 ### Импорт `APIRouter` { #import-the-apirouter }
 
 Теперь мы импортируем другие подмодули, содержащие `APIRouter`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
 
 Так как файлы `app/routers/users.py` и `app/routers/items.py` являются подмодулями, входящими в один и тот же Python-пакет `app`, мы можем использовать одну точку `.` для импорта через «относительные импорты».
 
@@ -374,13 +374,13 @@ from .routers.users import router
 
 Поэтому, чтобы иметь возможность использовать обе в одном файле, мы импортируем подмодули напрямую:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
 
 ### Подключение `APIRouter` для `users` и `items` { #include-the-apirouters-for-users-and-items }
 
 Теперь давайте подключим `router` из подмодулей `users` и `items`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
 
 /// info | Примечание
 
@@ -420,13 +420,13 @@ from .routers.users import router
 
 Для этого примера всё будет очень просто. Но допустим, что поскольку он используется совместно с другими проектами в организации, мы не можем модифицировать его и добавить `prefix`, `dependencies`, `tags` и т.д. непосредственно в `APIRouter`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
 
 Но мы всё равно хотим задать пользовательский `prefix` при подключении `APIRouter`, чтобы все его *операции пути* начинались с `/admin`, хотим защитить его с помощью `dependencies`, которые у нас уже есть для этого проекта, и хотим включить `tags` и `responses`.
 
 Мы можем объявить всё это, не изменяя исходный `APIRouter`, передав эти параметры в `app.include_router()`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
 
 Таким образом исходный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации.
 
@@ -447,7 +447,7 @@ from .routers.users import router
 
 Здесь мы делаем это... просто чтобы показать, что можем 🤷:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
 
 и это будет работать корректно вместе со всеми другими *операциями пути*, добавленными через `app.include_router()`.
 
index 9d94004947accf7b5f054da2f71886ffb9d7fd58..ddd9c6fdd9bb5524f9103b97b653d491635f04e3 100644 (file)
@@ -52,7 +52,7 @@
 }
 ```
 
-/// note | Ð\92нимание
+/// note | Ð\97амеÑ\82ка
 
 Обратите внимание, что хотя параметр `item` был объявлен таким же способом, как и раньше, теперь предполагается, что он находится внутри тела с ключом `item`.
 
 q: str | None = None
 ```
 
-Или в Python 3.9:
-
-```Python
-q: Union[str, None] = None
-```
-
 Например:
 
 {* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
index 4c914b97f0d831d700e7ec26f8e9660b3daf916f..6610b209c233df7752ff821166f07801cf3d3291 100644 (file)
@@ -163,7 +163,7 @@ images: list[Image]
 
 например так:
 
-{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
+{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
 
 ## Поддержка редактора кода везде { #editor-support-everywhere }
 
@@ -193,7 +193,7 @@ images: list[Image]
 
 В этом случае вы принимаете любой `dict`, пока у него есть ключи типа `int` со значениями типа `float`:
 
-{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
+{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
 
 /// tip | Совет
 
index 537d7ebc9625e1bbc1894cb54ca933e3497d3020..3e55607da5db4ef1b13383b6190c350f95618cb1 100644 (file)
@@ -72,7 +72,7 @@
 * Проведёт валидацию данных.
     * Если данные некорректны, вернёт понятную и наглядную ошибку, указывающую, где именно и что было некорректно.
 * Передаст полученные данные в параметр `item`.
-    * Поскольку внутри функции вы объявили его с типом `Item`, у вас будет поддержка со стороны редактора кода (автозавершение и т. п.) для всех атрибутов и их типов.
+    * Поскольку внутри функции вы объявили его с типом `Item`, у вас будет поддержка со стороны редактора кода (автозавершение и т.п.) для всех атрибутов и их типов.
 * Сгенерирует определения <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> для вашей модели; вы можете использовать их и в других местах, если это имеет смысл для вашего проекта.
 * Эти схемы будут частью сгенерированной схемы OpenAPI и будут использоваться автоматической документацией <abbr title="User Interfaces - Пользовательские интерфейсы">UIs</abbr>.
 
@@ -148,14 +148,14 @@ JSON Schema ваших моделей будет частью сгенериро
 Параметры функции будут распознаны следующим образом:
 
 * Если параметр также объявлен в **пути**, он будет использоваться как path-параметр.
-* Если параметр имеет **скалярный тип** (например, `int`, `float`, `str`, `bool` и т. п.), он будет интерпретирован как параметр **запроса**.
+* Если параметр имеет **скалярный тип** (например, `int`, `float`, `str`, `bool` и т.п.), он будет интерпретирован как параметр **запроса**.
 * Если параметр объявлен как тип **модели Pydantic**, он будет интерпретирован как **тело** запроса.
 
 /// note | Заметка
 
 FastAPI понимает, что значение `q` не является обязательным из-за значения по умолчанию `= None`.
 
-Аннотации типов `str | None` (Python 3.10+) или `Union` в `Union[str, None]` (Python 3.9+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`.
+Аннотация типов `str | None` не используется FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`.
 
 Но добавление аннотаций типов позволит вашему редактору кода лучше вас поддерживать и обнаруживать ошибки.
 
index 182813afdf6ce67b030b7a63d2baa87657dbdffe..9b34cf030063887cda6f3d089c3049e8e3121549 100644 (file)
@@ -46,7 +46,7 @@
 
 В некоторых случаях (не особо часто встречающихся) вам может понадобиться **ограничить** cookies, которые вы хотите получать.
 
-Теперь ваш API сам решает, <abbr title="Это шутка, на всякий случай. Это не имеет никакого отношения к согласию на использование cookie, но забавно, что даже API теперь может отклонять несчастные cookies. Съешьте печеньку. 🍪">принимать ли cookies</abbr>. 🤪🍪
+Теперь у вашего API есть возможность контролировать своё <dfn title="Это шутка, на всякий случай. Это не имеет никакого отношения к согласию на использование cookie, но забавно, что даже API теперь может отклонять несчастные cookies. Съешьте печеньку. 🍪">согласие на использование cookie</dfn>. 🤪🍪
 
 Вы можете сконфигурировать Pydantic-модель так, чтобы запретить (`forbid`) любые дополнительные (`extra`) поля:
 
@@ -54,9 +54,9 @@
 
 Если клиент попробует отправить **дополнительные cookies**, то в ответ он получит **ошибку**.
 
-Бедные баннеры cookies, они всеми силами пытаются получить ваше согласие — и всё ради того, чтобы <abbr title="Это ещё одна шутка. Не обращайте на меня внимания. Выпейте кофе со своей печенькой. ☕">API его отклонил</abbr>. 🍪
+Бедные баннеры cookies, они всеми силами пытаются получить ваше согласие — и всё ради того, чтобы <dfn title="Это ещё одна шутка. Не обращайте на меня внимания. Выпейте кофе со своей печенькой. ☕">API его отклонил</dfn>. 🍪
 
-Например, если клиент попытается отправить cookie `santa_tracker` со значением `good-list-please`, то в ответ он получит **ошибку**, сообщающую ему, что cookie `santa_tracker` <abbr title="Санта не одобряет пропажу печенья. 🎅 Ладно, больше никаких шуток про печенье.">не разрешён</abbr>:
+Например, если клиент попытается отправить cookie `santa_tracker` со значением `good-list-please`, то в ответ он получит **ошибку**, сообщающую ему, что `santa_tracker` <dfn title="Санта не одобряет пропажу печенья. 🎅 Ладно, больше никаких шуток про печенье.">cookie не разрешён</dfn>:
 
 ```json
 {
@@ -73,4 +73,4 @@
 
 ## Заключение { #summary }
 
-Вы можете использовать **Pydantic-модели** для объявления <abbr title="Съешьте последнюю печеньку, прежде чем уйти. 🍪">**cookies**</abbr> в **FastAPI**. 😎
+Вы можете использовать **Pydantic-модели** для объявления <dfn title="Съешьте последнюю печеньку, прежде чем уйти. 🍪">**cookies**</dfn> в **FastAPI**. 😎
index 2d2eff8d7cbc75ea179dc5a6cc27f57b935eb7b9..8dad3873e4f57a39062a3247383de241bfa2e7a9 100644 (file)
 
 /// info | Дополнительная информация
 
-Имейте в виду, что, поскольку браузеры обрабатывают cookies особым образом и «за кулисами», они не позволяют JavaScript просто так получать к ним доступ.
+Имейте в виду, что, поскольку **браузеры обрабатывают cookies** особым образом и «за кулисами», они **не** позволяют **JavaScript** просто так получать к ним доступ.
 
-Если вы откроете интерфейс документации API на `/docs`, вы сможете увидеть документацию по cookies для ваших операций пути.
+Если вы откроете **интерфейс документации API** на `/docs`, вы сможете увидеть **документацию** по cookies для ваших *операции пути*.
 
-Но даже если вы заполните данные и нажмёте «Execute», поскольку UI документации работает с JavaScript, cookies отправлены не будут, и вы увидите сообщение об ошибке, как будто вы не указали никаких значений.
+Но даже если вы **заполните данные** и нажмёте «Execute», поскольку UI документации работает с **JavaScript**, cookies отправлены не будут, и вы увидите сообщение об **ошибке**, как будто вы не указали никаких значений.
 
 ///
 
index d09a31e2c3509fd78b33a1cdbed7a7769a2983eb..feaa1596830cc1015a30f0f3c54eaf8d25173c51 100644 (file)
@@ -46,7 +46,7 @@
 * Отдельных HTTP-методов (`POST`, `PUT`) или всех вместе, используя `"*"`.
 * Отдельных HTTP-заголовков или всех вместе, используя `"*"`.
 
-{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
 
 `CORSMiddleware` использует "запрещающие" значения по умолчанию, поэтому вам нужно явным образом разрешить использование отдельных источников, методов или заголовков, чтобы браузеры могли использовать их в кросс-доменном контексте.
 
@@ -77,7 +77,7 @@
 
 ## Больше информации { #more-info }
 
-Для получения более подробной информации о <abbr title="Cross-Origin Resource Sharing  совместное использование ресурсов между источниками">CORS</abbr> обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">документации CORS от Mozilla</a>.
+Для получения более подробной информации о <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">документации CORS от Mozilla</a>.
 
 /// note | Технические детали
 
index 51955835e6e879a02d7001c055d3ddd35f004321..483fe808696273da5e7f71e8131700b1b99475aa 100644 (file)
@@ -6,7 +6,7 @@
 
 В вашем FastAPI приложении, импортируйте и вызовите `uvicorn` напрямую:
 
-{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
 
 ### Описание `__name__ == "__main__"` { #about-name-main }
 
@@ -42,7 +42,7 @@ $ python myapp.py
 
 то встроенная переменная `__name__`, автоматически создаваемая Python в вашем файле, будет иметь значение строкового типа `"__main__"`.
 
-Тогда выполнится условие и эта часть кода:
+Тогда эта часть кода:
 
 ```Python
     uvicorn.run(app, host="0.0.0.0", port=8000)
@@ -59,7 +59,7 @@ $ python myapp.py
 ```Python
 from myapp import app
 
-# Some more code
+# Еще немного кода
 ```
 
 то автоматическая создаваемая внутри файла `myapp.py` переменная  `__name__` будет иметь значение отличающееся от `"__main__"`.
@@ -99,7 +99,7 @@ from myapp import app
 
 ---
 
-Если используете Pycharm, вы можете выполнить следующие шаги:
+Если используете PyCharm, вы можете выполнить следующие шаги:
 
 * Открыть "Run" меню.
 * Выбрать опцию "Debug...".
index a38e885d43f308857d758be8f0b75dd4b6b43e8d..9a3171e9f1ed56dbd39867fae7244fdf414df269 100644 (file)
@@ -4,7 +4,7 @@
 
 ## `dict` из предыдущего примера { #a-dict-from-the-previous-example }
 
-В предыдущем примере мы возвращали `dict` из нашей зависимости:
+В предыдущем примере мы возвращали `dict` из нашей зависимости («dependable»):
 
 {* ../../docs_src/dependencies/tutorial001_an_py310.py hl[9] *}
 
@@ -67,7 +67,7 @@ fluffy = Cat(name="Mr Fluffy")
 
 Это относится и к вызываемым объектам без параметров. Работа с ними происходит точно так же, как и для *функций-обработчиков пути* без параметров.
 
-Теперь мы можем изменить зависимость `common_parameters`, указанную выше, на класс `CommonQueryParams`:
+Теперь мы можем изменить зависимость («dependable») `common_parameters`, указанную выше, на класс `CommonQueryParams`:
 
 {* ../../docs_src/dependencies/tutorial002_an_py310.py hl[11:15] *}
 
@@ -101,7 +101,7 @@ fluffy = Cat(name="Mr Fluffy")
 
 Обратите внимание, что в приведенном выше коде мы два раза пишем `CommonQueryParams`:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ non-Annotated
+//// tab | Python 3.10+ без Annotated
 
 /// tip | Подсказка
 
@@ -137,7 +137,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 В этом случае первый `CommonQueryParams`, в:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
 
 ////
 
-//// tab | Python 3.9+ non-Annotated
+//// tab | Python 3.10+ без Annotated
 
 /// tip | Подсказка
 
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
 
 На самом деле можно написать просто:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ non-Annotated
+//// tab | Python 3.10+ без Annotated
 
 /// tip | Подсказка
 
@@ -197,7 +197,7 @@ commons = Depends(CommonQueryParams)
 
 Но вы видите, что здесь мы имеем некоторое повторение кода, дважды написав `CommonQueryParams`:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ non-Annotated
+//// tab | Python 3.10+ без Annotated
 
 /// tip | Подсказка
 
@@ -225,7 +225,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 Вместо того чтобы писать:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.9+ non-Annotated
+//// tab | Python 3.10+ без Annotated
 
 /// tip | Подсказка
 
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 ...следует написать:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
 
 ////
 
-//// tab | Python 3.9+ non-Annotated
+//// tab | Python 3.10+ без Annotated
 
 /// tip | Подсказка
 
index ef566444850fa1e2337e2eb415eb3a37e05cf22a..4cfc4e699fa1aaa8fcfb0844f525be93233d62ba 100644 (file)
@@ -14,7 +14,7 @@
 
 Это должен быть `list` состоящий из `Depends()`:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
 
 Зависимости из dependencies выполнятся так же, как и обычные зависимости. Но их значения (если они были) не будут переданы в *функцию операции пути*.
 
@@ -30,7 +30,7 @@
 
 /// info | Примечание
 
-В этом примере мы используем выдуманные пользовательские заголовки `X-Key` и `X-Token`.
+В этом примере мы используем выдуманные пользовательские HTTP-заголовки `X-Key` и `X-Token`.
 
 Но в реальных проектах, при внедрении системы безопасности, вы получите больше пользы используя интегрированные [средства защиты (следующая глава)](../security/index.md){.internal-link target=_blank}.
 
 
 ### Требования к зависимостям { #dependency-requirements }
 
-Они могут объявлять требования к запросу (например заголовки) или другие подзависимости:
+Они могут объявлять требования к запросу (например HTTP-заголовки) или другие подзависимости:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
 
 ### Вызов исключений { #raise-exceptions }
 
 Зависимости из dependencies могут вызывать исключения с помощью `raise`, как и обычные зависимости:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
 
 ### Возвращаемые значения { #return-values }
 
@@ -58,7 +58,7 @@
 
 Таким образом, вы можете переиспользовать обычную зависимость (возвращающую значение), которую вы уже используете где-то в другом месте, и хотя значение не будет использоваться, зависимость будет выполнена:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
 
 ## Зависимости для группы *операций путей* { #dependencies-for-a-group-of-path-operations }
 
index dc202db616b5be98bdfb3faf2f6a77674e9957cd..03a7c083c431be99317c4d9d03c29c2be6ad4399 100644 (file)
@@ -1,6 +1,6 @@
 # Зависимости с yield { #dependencies-with-yield }
 
-FastAPI поддерживает зависимости, которые выполняют некоторые <abbr title='иногда также называемые "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code" и т.п.'>дополнительные шаги после завершения</abbr>.
+FastAPI поддерживает зависимости, которые выполняют некоторые <dfn title='иногда также называемые "код выхода", "код очистки", "код завершения", "код закрытия", "код выхода менеджера контекста" и т.п.'>дополнительные шаги после завершения</dfn>.
 
 Для этого используйте `yield` вместо `return`, а дополнительные шаги (код) напишите после него.
 
@@ -29,15 +29,15 @@ FastAPI поддерживает зависимости, которые выпо
 
 Перед созданием ответа будет выполнен только код до и включая оператор `yield`:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
 
 Значение, полученное из `yield`, внедряется в *операции пути* и другие зависимости:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
 
 Код, следующий за оператором `yield`, выполняется после ответа:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
 
 /// tip | Подсказка
 
@@ -57,7 +57,7 @@ FastAPI поддерживает зависимости, которые выпо
 
 Точно так же можно использовать `finally`, чтобы убедиться, что обязательные шаги при выходе выполнены независимо от того, было ли исключение или нет.
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
 
 ## Подзависимости с `yield` { #sub-dependencies-with-yield }
 
@@ -67,7 +67,7 @@ FastAPI поддерживает зависимости, которые выпо
 
 Например, `dependency_c` может зависеть от `dependency_b`, а `dependency_b` — от `dependency_a`:
 
-{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
 
 И все они могут использовать `yield`.
 
@@ -75,7 +75,7 @@ FastAPI поддерживает зависимости, которые выпо
 
 И, в свою очередь, `dependency_b` нуждается в том, чтобы значение из `dependency_a` (здесь `dep_a`) было доступно для её кода выхода.
 
-{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
 
 Точно так же можно иметь часть зависимостей с `yield`, часть — с `return`, и какие-то из них могут зависеть друг от друга.
 
@@ -109,7 +109,7 @@ FastAPI поддерживает зависимости, которые выпо
 
 ///
 
-{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
+{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
 
 Если вы хотите перехватывать исключения и формировать на их основе пользовательский ответ, создайте [Пользовательский обработчик исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
 
@@ -117,7 +117,7 @@ FastAPI поддерживает зависимости, которые выпо
 
 Если вы ловите исключение с помощью `except` в зависимости с `yield` и не вызываете его снова (или не вызываете новое исключение), FastAPI не сможет заметить, что было исключение — так же, как это происходит в обычном Python:
 
-{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
+{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
 
 В этом случае клиент получит *HTTP 500 Internal Server Error*, как и должно быть, поскольку мы не вызываем `HTTPException` или что-то подобное, но на сервере **не будет никаких логов** или других указаний на то, какая была ошибка. 😱
 
@@ -127,7 +127,7 @@ FastAPI поддерживает зависимости, которые выпо
 
 Вы можете повторно вызвать то же самое исключение с помощью `raise`:
 
-{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
+{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
 
 Теперь клиент получит тот же *HTTP 500 Internal Server Error*, но на сервере в логах будет наше пользовательское `InternalError`. 😎
 
@@ -190,7 +190,7 @@ participant tasks as Background tasks
 
 Но если вы знаете, что не будете использовать зависимость после возврата из *функции-обработчика пути*, вы можете использовать `Depends(scope="function")`, чтобы сообщить FastAPI, что он должен закрыть зависимость после возврата из *функции-обработчика пути*, но **до того**, как **ответ будет отправлен**.
 
-{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
+{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
 
 `Depends()` принимает параметр `scope`, который может быть:
 
@@ -269,7 +269,7 @@ with open("./somefile.txt") as f:
 Их также можно использовать внутри зависимостей **FastAPI** с `yield`, применяя операторы
 `with` или `async with` внутри функции зависимости:
 
-{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
 
 /// tip | Подсказка
 
index 2347c6dd834741bd98ff1d34e859dddfb856d1e2..f488322a9e8957b49cefc2ba45fbc226c51cd43a 100644 (file)
@@ -6,10 +6,10 @@
 
 В этом случае они будут применяться ко всем *операциям пути* в приложении:
 
-{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
+{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
 
 Все способы [добавления `dependencies` (зависимостей) в *декораторах операций пути*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} по-прежнему применимы, но в данном случае зависимости применяются ко всем *операциям пути* приложения.
 
 ## Зависимости для групп *операций пути* { #dependencies-for-groups-of-path-operations }
 
-Позднее, читая о том, как структурировать более крупные [приложения, содержащие много файлов](../../tutorial/bigger-applications.md){.internal-link target=_blank}, вы узнаете, как объявить один параметр `dependencies` для целой группы *операций пути*.
+Позднее, читая о том, как структурировать более крупные приложения ([приложения, содержащие много файлов](../../tutorial/bigger-applications.md){.internal-link target=_blank}), возможно, состоящие из нескольких файлов, вы узнаете, как объявить один параметр `dependencies` для целой группы *операций пути*.
index 98b0d59c6a965a0e059557a87e457d24795beeaf..29f735ab61c5c80cf57465b41837575a41cda870 100644 (file)
@@ -1,6 +1,6 @@
 # Зависимости { #dependencies }
 
-**FastAPI** имеет очень мощную, но интуитивную систему **<abbr title="также известно как: компоненты, ресурсы, провайдеры, сервисы, внедряемые зависимости">Инъекция зависимостей</abbr>**.
+**FastAPI** имеет очень мощную, но интуитивную систему **<dfn title="также известно как: компоненты, ресурсы, провайдеры, сервисы, внедряемые зависимости">Инъекция зависимостей</dfn>**.
 
 Она спроектирована так, чтобы быть очень простой в использовании и облегчать любому разработчику интеграцию других компонентов с **FastAPI**.
 
index da31a6682f6215c3564857d4c7e53a4a95030471..3c71defd89c436e0133eeca4f0bb168557853437 100644 (file)
@@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
 
 Если одна из ваших зависимостей объявлена несколько раз для одной и той же *функции операции пути*, например, несколько зависимостей имеют общую подзависимость, **FastAPI** будет знать, что вызывать эту подзависимость нужно только один раз за запрос.
 
-При этом возвращаемое значение будет сохранено в <abbr title="Система для хранения значений, сгенерированных компьютером, для их повторного использования вместо повторного вычисления.">"кэш"</abbr> и будет передано всем "зависимым" функциям, которые нуждаются в нем внутри этого конкретного запроса, вместо того, чтобы вызывать зависимость несколько раз для одного и того же запроса.
+При этом возвращаемое значение будет сохранено в <dfn title="Вспомогательная система для хранения вычисленных/сгенерированных значений, чтобы переиспользовать их вместо повторного вычисления.">«кэш»</dfn> и будет передано всем "зависимым" функциям, которые нуждаются в нем внутри этого конкретного запроса, вместо того, чтобы вызывать зависимость несколько раз для одного и того же запроса.
 
 В расширенном сценарии, когда вы знаете, что вам нужно, чтобы зависимость вызывалась на каждом шаге (возможно, несколько раз) в одном и том же запросе, вместо использования "кэшированного" значения, вы можете установить параметр `use_cache=False` при использовании `Depends`:
 
-//// tab | Python 3.9+
+//// tab | Python 3.10+
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
 
 ////
 
-//// tab | Python 3.9+ без Annotated
+//// tab | Python 3.10+ без Annotated
 
 /// tip | Подсказка
 
index 16981f79de62be9d11c5707c339b3ec1051b8deb..28e2a49c0ae69beec1115d49e5735c6d434917cd 100644 (file)
@@ -10,9 +10,9 @@
 
 Представим, что у вас есть база данных `fake_db`, которая принимает только JSON-совместимые данные.
 
-Например, он не принимает объекты `datetime`, так как они не совместимы с JSON.
+Например, она не принимает объекты `datetime`, так как они не совместимы с JSON.
 
-В таком случае объект `datetime` следует преобразовать в строку соответствующую <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">формату ISO</a>.
+В таком случае объект `datetime` следует преобразовать в строку, соответствующую <a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">формату ISO</a>.
 
 Точно так же эта база данных не может принять Pydantic-модель (объект с атрибутами), а только `dict`.
 
index 03156f2b4e7d79b237efb6a1142e1da8d6e0b3c0..f9b63ca70ed1671ebae450e838bbc3c2bfd35d03 100644 (file)
@@ -190,9 +190,9 @@ some_variable: PlaneItem | CarItem
 
 Таким же образом вы можете объявлять HTTP-ответы, возвращающие списки объектов.
 
-Для этого используйте стандартный `typing.List` в Python (или просто `list` в Python 3.9 и выше):
+Для этого используйте стандартный `list` в Python:
 
-{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
+{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
 
 ## Ответ с произвольным `dict` { #response-with-arbitrary-dict }
 
@@ -200,9 +200,9 @@ some_variable: PlaneItem | CarItem
 
 Это полезно, если вы заранее не знаете корректных названий полей/атрибутов (которые будут нужны при использовании Pydantic-модели).
 
-В этом случае вы можете использовать `typing.Dict` (или просто `dict` в Python 3.9 и выше):
+В этом случае вы можете использовать `dict`:
 
-{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
+{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
 
 ## Резюме { #recap }
 
index 798c03d5175332aaa76c5aa131b5d0c093f88d2f..cee264ff4617d0def5290117a38f02c729d46c88 100644 (file)
@@ -2,7 +2,7 @@
 
 Самый простой файл FastAPI может выглядеть так:
 
-{* ../../docs_src/first_steps/tutorial001_py39.py *}
+{* ../../docs_src/first_steps/tutorial001_py310.py *}
 
 Скопируйте это в файл `main.py`.
 
@@ -183,7 +183,7 @@ Deploying to FastAPI Cloud...
 
 ### Шаг 1: импортируйте `FastAPI` { #step-1-import-fastapi }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
 
 `FastAPI` — это класс на Python, который предоставляет всю функциональность для вашего API.
 
@@ -197,7 +197,7 @@ Deploying to FastAPI Cloud...
 
 ### Шаг 2: создайте экземпляр `FastAPI` { #step-2-create-a-fastapi-instance }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
 
 Здесь переменная `app` будет экземпляром класса `FastAPI`.
 
@@ -266,12 +266,12 @@ https://example.com/items/foo
 
 #### Определите *декоратор операции пути (path operation decorator)* { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
 
 `@app.get("/")` сообщает **FastAPI**, что функция прямо под ним отвечает за обработку запросов, поступающих:
 
 * по пути `/`
-* с использованием <abbr title="метод HTTP GET"><code>get</code> операции</abbr>
+* с использованием <dfn title="метод HTTP GET"><code>get</code> операции</dfn>
 
 /// info | Информация о `@decorator`
 
@@ -320,7 +320,7 @@ https://example.com/items/foo
 * **операция**: `get`.
 * **функция**: функция ниже «декоратора» (ниже `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
 
 Это функция на Python.
 
@@ -332,7 +332,7 @@ https://example.com/items/foo
 
 Вы также можете определить её как обычную функцию вместо `async def`:
 
-{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
 
 /// note | Примечание
 
@@ -342,7 +342,7 @@ https://example.com/items/foo
 
 ### Шаг 5: верните содержимое { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
 
 Вы можете вернуть `dict`, `list`, отдельные значения `str`, `int` и т.д.
 
index 2e00d7075905b10b0591bcc98e9f47eca8c7f2fc..fbd82cf28a4a6f89fb376e5c893eb3c2cc498ebb 100644 (file)
@@ -11,7 +11,7 @@
 * Элемент, к которому клиент пытался получить доступ, не существует.
 * и т.д.
 
-В таких случаях обычно возвращается **HTTP-код статуса ответа** в диапазоне **400** (от 400 до 499).
+В таких случаях обычно возвращают **HTTP статус-код** в диапазоне **400** (от 400 до 499).
 
 Они похожи на двухсотые HTTP статус-коды (от 200 до 299), которые означают, что запрос обработан успешно.
 
@@ -25,7 +25,7 @@
 
 ### Импортируйте `HTTPException` { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
 
 ### Вызовите `HTTPException` в своем коде { #raise-an-httpexception-in-your-code }
 
@@ -39,7 +39,7 @@
 
 В данном примере, когда клиент запрашивает элемент по несуществующему ID, возникает исключение со статус-кодом `404`:
 
-{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
 
 ### Возвращаемый ответ { #the-resulting-response }
 
 
 ## Добавление пользовательских заголовков { #add-custom-headers }
 
-В некоторых ситуациях полезно иметь возможность добавлять пользовательские заголовки к ошибке HTTP. Например, для некоторых типов безопасности.
+В некоторых ситуациях полезно иметь возможность добавлять пользовательские HTTP-заголовки к ошибке HTTP. Например, для некоторых типов безопасности.
 
 Скорее всего, вам не потребуется использовать его непосредственно в коде.
 
 Но в случае, если это необходимо для продвинутого сценария, можно добавить пользовательские заголовки:
 
-{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
 
 ## Установка пользовательских обработчиков исключений { #install-custom-exception-handlers }
 
@@ -89,7 +89,7 @@
 
 Можно добавить собственный обработчик исключений с помощью `@app.exception_handler()`:
 
-{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
 
 Здесь, если запросить `/unicorns/yolo`, то *операция пути* вызовет `UnicornException`.
 
 
 Обработчик исключения получит объект `Request` и исключение.
 
-{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
 
 Теперь, если перейти к `/items/foo`, то вместо стандартной JSON-ошибки с:
 
@@ -159,7 +159,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
 
 Например, для этих ошибок можно вернуть обычный текстовый ответ вместо JSON:
 
-{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
 
 /// note | Технические детали
 
@@ -183,7 +183,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
 
 Вы можете использовать его при разработке приложения для регистрации тела и его отладки, возврата пользователю и т.д.
 
-{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
 
 Теперь попробуйте отправить недействительный элемент, например:
 
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
 
 Если вы хотите использовать исключение вместе с теми же обработчиками исключений по умолчанию из **FastAPI**, вы можете импортировать и повторно использовать обработчики исключений по умолчанию из `fastapi.exception_handlers`:
 
-{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
 
 В этом примере вы просто `выводите в терминал` ошибку с очень выразительным сообщением, но идея вам понятна. Вы можете использовать исключение, а затем просто повторно использовать стандартные обработчики исключений.
index e4fe5fb5443b42ab6751c6182a5c94658223aacb..221655aa5dd9d4ab3885a5a33a7c6788e2d2d41f 100644 (file)
@@ -18,7 +18,7 @@
 
 Вы можете задать их следующим образом:
 
-{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
+{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
 
 /// tip | Подсказка
 
@@ -36,7 +36,7 @@
 
 К примеру:
 
-{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
 
 ## Метаданные для тегов { #metadata-for-tags }
 
@@ -58,7 +58,7 @@
 
 Создайте метаданные для ваших тегов и передайте их в параметре `openapi_tags`:
 
-{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
 
 Помните, что вы можете использовать Markdown внутри описания, к примеру "login" будет отображен жирным шрифтом (**login**) и "fancy" будет отображаться курсивом (_fancy_).
 
@@ -72,7 +72,7 @@
 
 Используйте параметр `tags` с вашими *операциями пути* (и `APIRouter`ами), чтобы присвоить им различные теги:
 
-{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
 
 /// info | Дополнительная информация
 
 
 К примеру, чтобы задать её отображение по адресу `/api/v1/openapi.json`:
 
-{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
 
 Если вы хотите отключить схему OpenAPI полностью, вы можете задать `openapi_url=None`, это также отключит пользовательские интерфейсы документации, которые её используют.
 
 
 К примеру, чтобы задать отображение Swagger UI по адресу `/documentation` и отключить ReDoc:
 
-{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}
index a83d3c0111f2b8e55eadd8cf6fbda10e162920d5..734545cd8befb4e559eb3612f5d8553960a59eae 100644 (file)
@@ -1,10 +1,8 @@
 # Middleware (Промежуточный слой) { #middleware }
 
-Вы можете добавить промежуточный слой (middleware) в **FastAPI** приложение.
-
-"Middleware" это функция, которая выполняется с каждым запросом до его обработки какой-либо конкретной *операцией пути*.
-А также с каждым ответом перед его возвращением.
+Вы можете добавить middleware (промежуточный слой) в **FastAPI** приложение.
 
+"Middleware" - это функция, которая выполняется с каждым **запросом** до его обработки какой-либо конкретной *операцией пути*. А также с каждым **ответом** перед его возвращением.
 
 * Она принимает каждый поступающий **запрос**.
 * Может что-то сделать с этим **запросом** или выполнить любой нужный код.
 
 ## Создание middleware { #create-a-middleware }
 
-Для создания middleware используйте декоратор `@app.middleware("http")`.
+Для создания middleware используйте декоратор `@app.middleware("http")` поверх функции.
 
 Функция middleware получает:
 
-* `request` (объект запроса).
+* `request`.
 * Функцию `call_next`, которая получает `request` в качестве параметра.
     * Эта функция передаёт `request` соответствующей *операции пути*.
-    * Затем она возвращает ответ `response`, сгенерированный *операцией пути*.
-* Также имеется возможность видоизменить `response`, перед тем как его вернуть.
+    * Затем она возвращает `response`, сгенерированный соответствующей *операцией пути*.
+* Также имеется возможность видоизменить `response` перед тем как его вернуть.
 
-{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
 
-/// tip | Ð\9fÑ\80имеÑ\87ание
+/// tip | Ð¡Ð¾Ð²ÐµÑ\82
 
-Имейте в виду, что можно добавлять свои собственные заголовки <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">при помощи префикса 'X-'</a>.
+Имейте в виду, что можно добавлять проприетарные HTTP-заголовки <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">с префиксом `X-`</a>.
 
\95Ñ\81ли Ð¶Ðµ Ð²Ñ\8b Ñ\85оÑ\82иÑ\82е Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ñ\81обÑ\81Ñ\82веннÑ\8bе Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¸, ÐºÐ¾Ñ\82оÑ\80Ñ\8bе ÐºÐ»Ð¸ÐµÐ½Ñ\82 Ñ\81можеÑ\82 Ñ\83видеÑ\82Ñ\8c Ð² Ð±Ñ\80аÑ\83зеÑ\80е, Ñ\82о Ð²Ð°Ð¼ Ð¿Ð¾Ñ\82Ñ\80ебÑ\83еÑ\82Ñ\81Ñ\8f Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð¸Ñ\85 Ð² Ð½Ð°Ñ\81Ñ\82Ñ\80ойки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}), Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8f Ð¿Ð°Ñ\80амеÑ\82Ñ\80 `expose_headers`, Ñ\81м. Ð´Ð¾ÐºÑ\83менÑ\82аÑ\86иÑ\8e <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">Starlette's CORS docs</a>.
\9dо ÐµÑ\81ли Ð²Ñ\8b Ñ\85оÑ\82иÑ\82е, Ñ\87Ñ\82обÑ\8b ÐºÐ»Ð¸ÐµÐ½Ñ\82 Ð² Ð±Ñ\80аÑ\83зеÑ\80е Ð¼Ð¾Ð³ Ð²Ð¸Ð´ÐµÑ\82Ñ\8c Ð²Ð°Ñ\88и Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8cÑ\81кие Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¸, Ð½ÐµÐ¾Ð±Ñ\85одимо Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð¸Ñ\85 Ð² Ð½Ð°Ñ\81Ñ\82Ñ\80ойки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}), Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8f Ð¿Ð°Ñ\80амеÑ\82Ñ\80 `expose_headers`, Ð¾Ð¿Ð¸Ñ\81аннÑ\8bй Ð² <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">докÑ\83менÑ\82аÑ\86ии Ð¿Ð¾ CORS Starlette</a>.
 
 ///
 
 
 ### До и после `response` { #before-and-after-the-response }
 
-Вы можете добавить код, использующий `request` до передачи его какой-либо *операции пути*.
+Вы можете добавить код, использующий `request`, до передачи его какой-либо *операции пути*.
 
 А также после формирования `response`, до того, как вы его вернёте.
 
 Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки запроса и генерации ответа:
 
-{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
 
-/// tip | Ð\9fÑ\80имеÑ\87ание
+/// tip | Ð¡Ð¾Ð²ÐµÑ\82
 
\9cÑ\8b Ð¸Ñ\81полÑ\8cзÑ\83ем <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> Ð²Ð¼ÐµÑ\81Ñ\82о `time.time()` Ð´Ð»Ñ\8f Ð¾Ð±ÐµÑ\81пеÑ\87ениÑ\8f Ð±Ð¾Ð»Ñ\8cÑ\88ей Ñ\82оÑ\87ноÑ\81Ñ\82и Ð½Ð°Ñ\88иÑ\85 Ð¿Ñ\80имеÑ\80ов. 🤓
\9cÑ\8b Ð¸Ñ\81полÑ\8cзÑ\83ем <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> Ð²Ð¼ÐµÑ\81Ñ\82о `time.time()` Ð´Ð»Ñ\8f Ð¾Ð±ÐµÑ\81пеÑ\87ениÑ\8f Ð±Ð¾Ð»Ñ\8cÑ\88ей Ñ\82оÑ\87ноÑ\81Ñ\82и Ð² Ñ\82акиÑ\85 Ñ\81лÑ\83Ñ\87аÑ\8fÑ\85. 🤓
 
 ///
 
@@ -94,4 +92,4 @@ app.add_middleware(MiddlewareB)
 
 О других middleware вы можете узнать больше в разделе [Advanced User Guide: Advanced Middleware](../advanced/middleware.md){.internal-link target=_blank}.
 
-В следующем разделе вы можете прочитать, как настроить <abbr title="Cross-Origin Resource Sharing  совместное использование ресурсов между источниками">CORS</abbr> с помощью middleware.
+В следующем разделе вы можете прочитать, как настроить <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> с помощью middleware.
index 112a1efca57a1c773c2f8ebe50a8b99587eaf104..31531c67f1ab9a3b452802e136adb794b309a06a 100644 (file)
@@ -4,7 +4,7 @@
 
 /// warning | Внимание
 
\9fомниÑ\82е, Ñ\87Ñ\82о Ñ\8dÑ\82и Ð¿Ð°Ñ\80амеÑ\82Ñ\80Ñ\8b Ð¿ÐµÑ\80едаÑ\8eÑ\82Ñ\81Ñ\8f Ð½ÐµÐ¿Ð¾Ñ\81Ñ\80едÑ\81Ñ\82венно *декоÑ\80аÑ\82оÑ\80Ñ\83 Ð¾Ð¿ÐµÑ\80аÑ\86ий Ð¿Ñ\83Ñ\82и*, Ð° Ð½Ðµ Ð²Ð°Ñ\88ей *Ñ\84Ñ\83нкÑ\86ии-обÑ\80абоÑ\82Ñ\87икÑ\83 Ð¾Ð¿ÐµÑ\80аÑ\86ий Ð¿Ñ\83Ñ\82и*.
+Помните, что эти параметры передаются непосредственно *декоратору операций пути*, а не вашей *функции-обработчику пути*.
 
 ///
 
@@ -46,7 +46,7 @@
 
 **FastAPI** поддерживает это так же, как и в случае с обычными строками:
 
-{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
 
 ## Краткое и развёрнутое содержание { #summary-and-description }
 
@@ -56,7 +56,7 @@
 
 ## Описание из строк документации { #description-from-docstring }
 
-Так как описания обычно длинные и содержат много строк, вы можете объявить описание *операции пути* в функции <abbr title="многострочный текст, первое выражение внутри функции (не присвоенный какой-либо переменной), используемый для документации">строки документации</abbr> и **FastAPI** прочитает её отсюда.
+Так как описания обычно длинные и содержат много строк, вы можете объявить описание *операции пути* в <dfn title="многострочная строка, первое выражение внутри функции (не присвоенное какой-либо переменной), используемая для документации">строке документации</dfn> функции, и **FastAPI** прочитает её оттуда.
 
 Вы можете использовать <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> в строке документации, и он будет интерпретирован и отображён корректно (с учетом отступа в строке документации).
 
@@ -90,9 +90,9 @@ OpenAPI указывает, что каждой *операции пути* не
 
 ## Обозначение *операции пути* как устаревшей { #deprecate-a-path-operation }
 
-Если вам необходимо пометить *операцию пути* как <abbr title="устаревшее, не рекомендовано к использованию">устаревшую</abbr>, при этом не удаляя её, передайте параметр `deprecated`:
+Если вам необходимо пометить *операцию пути* как <dfn title="устаревшая, рекомендуется не использовать">устаревшую</dfn>, при этом не удаляя её, передайте параметр `deprecated`:
 
-{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
 
 Он будет четко помечен как устаревший в интерактивной документации:
 
index f0fe7880510cc1c998f79fa98379cfbeb52bb0e1..6c1148b60cfbc89d4e098c34be5f4195b32b01d9 100644 (file)
@@ -44,7 +44,7 @@ Path-параметр всегда является обязательным, п
 
 И если вам больше ничего не нужно указывать для этого параметра, то нет необходимости использовать `Query`.
 
\9dо Ð²Ð°Ð¼ Ð¿Ð¾-пÑ\80ежнемÑ\83 Ð½Ñ\83жно Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c `Path` Ð´Ð»Ñ\8f path-паÑ\80амеÑ\82Ñ\80а `item_id`. Ð\98 ÐµÑ\81ли Ð¿Ð¾ ÐºÐ°ÐºÐ¾Ð¹-либо Ð¿Ñ\80иÑ\87ине Ð²Ñ\8b Ð½Ðµ Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c `Annotated`, Ñ\82о Ð¼Ð¾Ð³Ñ\83Ñ\82 Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½Ñ\83Ñ\82Ñ\8c Ð½ÐµÐ±Ð¾Ð»Ñ\8cÑ\88ие Ñ\81ложноÑ\81Ñ\82и.
\9dо Ð²Ð°Ð¼ Ð¿Ð¾-пÑ\80ежнемÑ\83 Ð½Ñ\83жно Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c `Path` Ð´Ð»Ñ\8f path-паÑ\80амеÑ\82Ñ\80а `item_id`. Ð\98 Ð¿Ð¾ ÐºÐ°ÐºÐ¾Ð¹-либо Ð¿Ñ\80иÑ\87ине Ð²Ñ\8b Ð½Ðµ Ñ\85оÑ\82иÑ\82е Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c `Annotated`.
 
 Если вы поместите параметр со значением по умолчанию перед другим параметром, у которого нет значения по умолчанию, то Python укажет на ошибку.
 
@@ -54,11 +54,11 @@ Path-параметр всегда является обязательным, п
 
 Поэтому вы можете определить функцию так:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
 
 Но имейте в виду, что если вы используете `Annotated`, вы не столкнётесь с этой проблемой, так как вы не используете значения по умолчанию параметров функции для `Query()` или `Path()`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
 
 ## Задайте нужный вам порядок параметров, полезные приёмы { #order-the-parameters-as-you-need-tricks }
 
@@ -83,13 +83,13 @@ Path-параметр всегда является обязательным, п
 
 Python не будет ничего делать с `*`, но он будет знать, что все следующие параметры являются именованными аргументами (парами ключ-значение), также известными как <abbr title="От: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>, даже если у них нет значений по умолчанию.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
 
 ### Лучше с `Annotated` { #better-with-annotated }
 
 Имейте в виду, что если вы используете `Annotated`, то, поскольку вы не используете значений по умолчанию для параметров функции, у вас не возникнет подобной проблемы и вам, вероятно, не придётся использовать `*`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
 
 ## Валидация числовых данных: больше или равно { #number-validations-greater-than-or-equal }
 
@@ -97,7 +97,7 @@ Python не будет ничего делать с `*`, но он будет з
 
 В этом примере при указании `ge=1`, параметр `item_id` должен быть целым числом "`g`reater than or `e`qual" — больше или равно `1`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
 
 ## Валидация числовых данных: больше и меньше или равно { #number-validations-greater-than-and-less-than-or-equal }
 
@@ -106,7 +106,7 @@ Python не будет ничего делать с `*`, но он будет з
 * `gt`: больше (`g`reater `t`han)
 * `le`: меньше или равно (`l`ess than or `e`qual)
 
-{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
 
 ## Валидация числовых данных: числа с плавающей точкой, больше и меньше { #number-validations-floats-greater-than-and-less-than }
 
@@ -118,7 +118,7 @@ Python не будет ничего делать с `*`, но он будет з
 
 То же самое справедливо и для <abbr title="less than – меньше чем"><code>lt</code></abbr>.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
 
 ## Резюме { #recap }
 
index 83a7ed3ffe7842bf3906d3af4b85a59c2700195a..7295697487640ebe094e6e4dabe359fea5cdc65c 100644 (file)
@@ -2,7 +2,7 @@
 
 Вы можете определить "параметры" или "переменные" пути, используя синтаксис форматированных строк Python:
 
-{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
 
 Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
 
@@ -16,7 +16,7 @@
 
 Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python:
 
-{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
 
 Здесь, `item_id` объявлен типом `int`.
 
@@ -26,7 +26,7 @@
 
 ///
 
-## <abbr title="также известное как: сериализация, парсинг, маршаллинг">Преобразование</abbr> данных { #data-conversion }
+## <dfn title="также известно как: сериализация, парсинг, маршаллинг">Преобразование</dfn> данных { #data-conversion }
 
 Если запустите этот пример и перейдёте по адресу: <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, то увидите ответ:
 
@@ -38,7 +38,7 @@
 
 Обратите внимание на значение `3`, которое получила (и вернула) функция. Это целочисленный Python `int`, а не строка `"3"`.
 
-Используя такое объявление типов, **FastAPI** выполняет автоматический <abbr title="преобразование строк из HTTP-запроса в типы данных Python">"парсинг"</abbr> запросов.
+Используя такое объявление типов, **FastAPI** выполняет автоматический HTTP-запрос <dfn title="преобразование строки, которая приходит из HTTP-запроса, в данные Python">"парсинг"</dfn>.
 
 ///
 
 
 Поскольку *операции пути* выполняются в порядке их объявления, необходимо, чтобы путь для `/users/me` был объявлен раньше, чем путь для `/users/{user_id}`:
 
-{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
 
 Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`.
 
 Аналогично, вы не можете переопределить операцию с путем:
 
-{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
 
 Первый будет выполняться всегда, так как путь совпадает первым.
 
 
 Затем создайте атрибуты класса с фиксированными допустимыми значениями:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
 
 /// tip | Подсказка
 
-Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия <abbr title="Технически, архитектуры моделей глубокого обучения">моделей</abbr> Машинного обучения.
+Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия <dfn title="Технически, архитектуры моделей глубокого обучения">моделей</dfn> Машинного обучения.
 
 ///
 
 
 Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
 
 ### Проверьте документацию { #check-the-docs }
 
 
 Вы можете сравнить это значение с *элементом перечисления* класса `ModelName`:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
 
 #### Получение *значения перечисления* { #get-the-enumeration-value }
 
 Можно получить фактическое значение (в данном случае - `str`) с помощью `model_name.value` или в общем случае `your_enum_member.value`:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
 
 /// tip | Подсказка
 
 
 Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
\92Ñ\8b Ð¾Ñ\82пÑ\80авиÑ\82е ÐºÐ»Ð¸ÐµÐ½Ñ\82Ñ\83 такой JSON-ответ:
+{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
\9dа Ñ\81Ñ\82оÑ\80оне ÐºÐ»Ð¸ÐµÐ½Ñ\82а Ð²Ñ\8b Ð¿Ð¾Ð»Ñ\83Ñ\87иÑ\82е такой JSON-ответ:
 
 ```JSON
 {
@@ -226,7 +226,7 @@ OpenAPI не поддерживает способов объявления *п
 
 Можете использовать так:
 
-{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
 
 /// tip | Подсказка
 
@@ -241,7 +241,7 @@ OpenAPI не поддерживает способов объявления *п
 Используя **FastAPI** вместе со стандартными объявлениями типов Python (короткими и интуитивно понятными), вы получаете:
 
 * Поддержку редактора кода (проверку ошибок, автозавершение и т.п.)
-* "<abbr title="преобразование строк из HTTP-запроса в типы данных Python">Парсинг</abbr>" данных
+* "<dfn title="преобразование строки, которая приходит из HTTP-запроса, в данные Python">Парсинг</dfn>" данных
 * Валидацию данных
 * Аннотации API и автоматическую документацию
 
index 5ad7f1d99dc39cb13646bbe164b407aafe723da4..7f29740acc25fb756b8793ea81019fe6b4d1e8eb 100644 (file)
@@ -6,7 +6,7 @@
 
 /// note | Заметка
 
-Этот функционал доступен с версии `0.115.0`. 🤓
+Это поддерживается начиная с версии FastAPI `0.115.0`. 🤓
 
 ///
 
index 2bc2fb22c59898cf2ad508c9d983cb412d7fbbce..43cbcad03ce14711370e1f91ab73942398a04031 100644 (file)
@@ -47,40 +47,16 @@ FastAPI поймёт, что значение `q` не обязательно, 
 
 У нас была такая аннотация типа:
 
-//// tab | Python 3.10+
-
 ```Python
 q: str | None = None
 ```
 
-////
-
-//// tab | Python 3.9+
-
-```Python
-q: Union[str, None] = None
-```
-
-////
-
 Мы «обернём» это в `Annotated`, и получится:
 
-//// tab | Python 3.10+
-
 ```Python
 q: Annotated[str | None] = None
 ```
 
-////
-
-//// tab | Python 3.9+
-
-```Python
-q: Annotated[Union[str, None]] = None
-```
-
-////
-
 Обе версии означают одно и то же: `q` — параметр, который может быть `str` или `None`, и по умолчанию равен `None`.
 
 А теперь к самому интересному. 🎉
@@ -109,7 +85,7 @@ q: Annotated[Union[str, None]] = None
 
 ## Альтернатива (устаревшее): `Query` как значение по умолчанию { #alternative-old-query-as-the-default-value }
 
-В предыдущих версиях FastAPI (до <abbr title="до 2023-03">0.95.0</abbr>) требовалось использовать `Query` как значение по умолчанию для параметра вместо помещения его в `Annotated`. Скорее всего вы ещё встретите такой код, поэтому поясню.
+В предыдущих версиях FastAPI (до <dfn title="до 2023-03">0.95.0</dfn>) требовалось использовать `Query` как значение по умолчанию для параметра вместо помещения его в `Annotated`. Скорее всего вы ещё встретите такой код, поэтому поясню.
 
 /// tip | Подсказка
 
@@ -191,7 +167,7 @@ q: str = Query(default="rick")
 
 ## Регулярные выражения { #add-regular-expressions }
 
-Вы можете определить <abbr title="Регулярное выражение (regex, regexp) - это последовательность символов, задающая шаблон поиска для строк.">регулярное выражение</abbr> `pattern`, которому должен соответствовать параметр:
+Вы можете определить <dfn title="Регулярное выражение (regex, regexp) — это последовательность символов, задающая шаблон поиска для строк.">регулярное выражение</dfn> `pattern`, которому должен соответствовать параметр:
 
 {* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
 
@@ -211,7 +187,7 @@ q: str = Query(default="rick")
 
 Допустим, вы хотите объявить, что query-параметр `q` должен иметь `min_length` равный `3` и значение по умолчанию `"fixedquery"`:
 
-{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
 
 /// note | Примечание
 
@@ -241,7 +217,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
 
 Поэтому, когда вам нужно объявить значение как обязательное при использовании `Query`, просто не указывайте значение по умолчанию:
 
-{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
 
 ### Обязательный, но может быть `None` { #required-can-be-none }
 
@@ -292,7 +268,7 @@ http://localhost:8000/items/?q=foo&q=bar
 
 Можно также определить значение по умолчанию как `list`, если ничего не передано:
 
-{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
 
 Если вы перейдёте по адресу:
 
@@ -315,7 +291,7 @@ http://localhost:8000/items/
 
 Можно использовать `list` напрямую вместо `list[str]`:
 
-{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
 
 /// note | Примечание
 
@@ -371,7 +347,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
 
 Предположим, этот параметр вам больше не нравится.
 
-Его нужно оставить на какое‑то время, так как клиенты его используют, но вы хотите, чтобы в документации он явно отображался как <abbr title="устаревший, не рекомендуется использовать">устаревший</abbr>.
+Его нужно оставить на какое‑то время, так как клиенты его используют, но вы хотите, чтобы в документации он явно отображался как <dfn title="устаревший, не рекомендуется использовать">устаревший</dfn>.
 
 Тогда передайте параметр `deprecated=True` в `Query`:
 
@@ -401,7 +377,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
 
 ///
 
-Например, эта кастомная проверка убеждается, что ID элемента начинается с `isbn-` для номера книги <abbr title="ISBN означает International Standard Book Number - Международный стандартный книжный номер">ISBN</abbr> или с `imdb-` для ID URL фильма на <abbr title="IMDB (Internet Movie Database) - веб‑сайт с информацией о фильмах">IMDB</abbr>:
+Например, эта кастомная проверка убеждается, что ID элемента начинается с `isbn-` для номера книги <abbr title="International Standard Book Number - Международный стандартный книжный номер">ISBN</abbr> или с `imdb-` для ID URL фильма на <abbr title="Internet Movie Database - Интернетная база данных фильмов: веб‑сайт с информацией о фильмах">IMDB</abbr>:
 
 {* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
 
@@ -435,7 +411,7 @@ http://127.0.0.1:8000/items/?item-query=foobaritems
 
 #### Случайный элемент { #a-random-item }
 
-С помощью `data.items()` мы получаем <abbr title="Объект, по которому можно итерироваться циклом for, например список, множество и т. п.">итерируемый объект</abbr> с кортежами, содержащими ключ и значение для каждого элемента словаря.
+С помощью `data.items()` мы получаем <dfn title="Объект, по которому можно итерироваться циклом for, например список, множество и т.п.">итерируемый объект</dfn> с кортежами, содержащими ключ и значение для каждого элемента словаря.
 
 Мы превращаем этот итерируемый объект в обычный `list` через `list(data.items())`.
 
index be1c0e46e1300c5c8958835d0f294fe2aa1d3f3b..cbacb129c5193d787e5edf038c3fd22dbe94ce31 100644 (file)
@@ -2,7 +2,7 @@
 
 Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры.
 
-{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
 
 Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака `?` в URL-адресе, разделенные символами `&`.
 
@@ -24,7 +24,7 @@ http://127.0.0.1:8000/items/?skip=0&limit=10
 Все те же правила, которые применяются к path-параметрам, также применяются и query-параметрам:
 
 * Поддержка от редактора кода (очевидно)
-* <abbr title="преобразование строки, полученной из HTTP запроса в Python данные">"Парсинг"</abbr> данных
+* <dfn title="преобразование строки, полученной из HTTP-запроса в данные Python">"Парсинг"</dfn> данных
 * Проверка на соответствие данных (Валидация)
 * Автоматическая документация
 
@@ -121,13 +121,13 @@ http://127.0.0.1:8000/items/foo?short=yes
 
 ## Обязательные query-параметры { #required-query-parameters }
 
-Когда вы объявляете значение по умолчанию для параметра, который не является path-параметром (в этом разделе, мы пока что познакомились только с  path-параметрами), то он не является обязательным.
+Когда вы объявляете значение по умолчанию для параметра, который не является path-параметром (в этом разделе мы пока что рассмотрели только query-параметры), то он не является обязательным.
 
 Если вы не хотите задавать конкретное значение, но хотите сделать параметр необязательным, вы можете установить значение по умолчанию равным `None`.
 
 Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию:
 
-{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
 
 Здесь параметр запроса `needy` является обязательным параметром с типом данных  `str`.
 
index 9cfbd53dfe4a9a9da4a7067a90b609e4af1f6301..41922333f86848b4c35f2ef6ec3a66530d4b9449 100644 (file)
@@ -20,13 +20,13 @@ $ pip install python-multipart
 
 Импортируйте `File` и `UploadFile` из модуля `fastapi`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
 
 ## Определите параметры `File` { #define-file-parameters }
 
 Создайте параметры `File` так же, как вы это делаете для `Body` или `Form`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
 
 /// info | Дополнительная информация
 
@@ -54,7 +54,7 @@ $ pip install python-multipart
 
 Определите параметр файла с типом `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
 
 Использование `UploadFile` имеет ряд преимуществ перед `bytes`:
 
@@ -122,7 +122,7 @@ contents = myfile.file.read()
 
 Но когда форма включает файлы, она кодируется как multipart/form-data. Если вы используете `File`, **FastAPI** будет знать, что ему нужно получить файлы из нужной части тела.
 
-Если вы хотите узнать больше об этих кодировках и полях форм, перейдите по ссылке <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network  Сеть разработчиков Mozilla">MDN</abbr> web docs for <code>POST</code></a>.
+Если вы хотите узнать больше об этих кодировках и полях форм, перейдите по ссылке <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> web docs for <code>POST</code></a>.
 
 ///
 
@@ -144,7 +144,7 @@ contents = myfile.file.read()
 
 Вы также можете использовать `File()` вместе с `UploadFile`, например, для установки дополнительных метаданных:
 
-{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
+{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
 
 ## Загрузка нескольких файлов { #multiple-file-uploads }
 
@@ -154,7 +154,7 @@ contents = myfile.file.read()
 
 Для этого необходимо объявить список `bytes` или `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
+{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
 
 Вы получите, как и было объявлено, список `list` из `bytes` или `UploadFile`.
 
@@ -170,7 +170,7 @@ contents = myfile.file.read()
 
 Так же, как и раньше, вы можете использовать `File()` для задания дополнительных параметров, даже для `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
+{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
 
 ## Резюме { #recap }
 
index f8c58356cb68e7566ee664369b7ec81e8e47a987..f4411a27bc0c8e38c3dd4a0dfc36ae40173bffd0 100644 (file)
@@ -24,7 +24,7 @@ $ pip install python-multipart
 
 Вам просто нужно объявить **Pydantic-модель** с полями, которые вы хотите получить как **поля формы**, а затем объявить параметр как `Form`:
 
-{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
+{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
 
 **FastAPI** **извлечёт** данные для **каждого поля** из **данных формы** в запросе и выдаст вам объявленную Pydantic-модель.
 
@@ -48,7 +48,7 @@ $ pip install python-multipart
 
 Вы можете сконфигурировать Pydantic-модель так, чтобы запретить (`forbid`) все дополнительные (`extra`) поля:
 
-{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
+{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
 
 Если клиент попробует отправить дополнительные данные, то в ответ он получит **ошибку**.
 
index 691dc75ba3af9b47451fae1878a94515e3698b32..10836d74fdb3b46ff294f2fe3552b3b6f3ec9663 100644 (file)
@@ -16,13 +16,13 @@ $ pip install python-multipart
 
 ## Импортируйте `File` и `Form` { #import-file-and-form }
 
-{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
 
 ## Определите параметры `File` и `Form` { #define-file-and-form-parameters }
 
 Создайте параметры файла и формы таким же образом, как для `Body` или `Query`:
 
-{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
 
 Файлы и поля формы будут загружены в виде данных формы, и вы получите файлы и поля формы.
 
index e257652b617fa1008d902a6a180672259475fbcc..01f71ac2fc61d8bbb2610c814fc5cadb8d94e2e5 100644 (file)
@@ -18,17 +18,17 @@ $ pip install python-multipart
 
 Импортируйте `Form` из `fastapi`:
 
-{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
 
 ## Определение параметров `Form` { #define-form-parameters }
 
 Создайте параметры формы так же, как это делается для `Body` или `Query`:
 
-{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
 
-Например, в одном из способов использования спецификации OAuth2 (называемом «потоком пароля») требуется отправить `username` и `password` в виде полей формы.
+Например, в одном из способов использования спецификации OAuth2 (называемом «password flow» - аутентификация по паролю) требуется отправить `username` и `password` в виде полей формы.
 
-<abbr title="specification – спецификация">spec</abbr> требует, чтобы поля были строго названы `username` и `password` и отправлялись как поля формы, а не JSON.
+<dfn title="спецификация">спецификация</dfn> требует, чтобы поля были строго названы `username` и `password` и отправлялись как поля формы, а не JSON.
 
 С помощью `Form` вы можете объявить те же настройки, что и с `Body` (и `Query`, `Path`, `Cookie`), включая валидацию, примеры, псевдоним (например, `user-name` вместо `username`) и т.д.
 
@@ -56,7 +56,7 @@ $ pip install python-multipart
 
 Но когда форма содержит файлы, она кодируется как `multipart/form-data`. О работе с файлами вы прочтёте в следующей главе.
 
-Если вы хотите узнать больше про эти кодировки и поля формы, обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network  Сеть разработчиков Mozilla">MDN</abbr> веб-документации для `POST`</a>.
+Если вы хотите узнать больше про эти кодировки и поля формы, обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> веб-документации для `POST`</a>.
 
 ///
 
index 22a811cd57eeff3c4beec40d05a97b25ad6d0680..cd99ce28c704c0e8a149d2ff30729ee6ca657c07 100644 (file)
@@ -183,7 +183,7 @@ FastAPI делает несколько вещей внутри вместе с
 
 Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах документации для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}.
 
-{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
 
 Этот простой случай обрабатывается FastAPI автоматически, потому что аннотация возвращаемого типа — это класс (или подкласс) `Response`.
 
@@ -193,7 +193,7 @@ FastAPI делает несколько вещей внутри вместе с
 
 Вы также можете использовать подкласс `Response` в аннотации типа:
 
-{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
 
 Это тоже сработает, так как `RedirectResponse` — подкласс `Response`, и FastAPI автоматически обработает этот простой случай.
 
@@ -201,7 +201,7 @@ FastAPI делает несколько вещей внутри вместе с
 
 Но когда вы возвращаете произвольный объект, не являющийся валидным типом Pydantic (например, объект базы данных), и аннотируете его таким образом в функции, FastAPI попытается создать модель ответа Pydantic из этой аннотации типа и потерпит неудачу.
 
-То же произойдёт, если у вас будет что-то вроде <abbr title='Объединение нескольких типов означает «любой из этих типов».'>union</abbr> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
+То же произойдёт, если у вас будет что-то вроде <dfn title="Объединение нескольких типов означает «любой из этих типов».">union</dfn> разных типов, где один или несколько не являются валидными типами Pydantic, например, это приведёт к ошибке 💥:
 
 {* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
 
index 30f642b6438baf5bc93758916ad66bda85852e12..13d982e803cc0766322263a56994abbfb457119d 100644 (file)
@@ -8,7 +8,7 @@
 * `@app.delete()`
 * и других.
 
-{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
 
 /// note | Примечание
 
@@ -66,7 +66,7 @@ FastAPI знает об этом и создаст документацию Open
 
 /// tip | Подсказка
 
-Чтобы узнать больше о HTTP кодах статуса и о том, для чего каждый из них предназначен, ознакомьтесь с <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network  Сеть разработчиков Mozilla">MDN</abbr> документацией об HTTP статус-кодах</a>.
+Чтобы узнать больше о HTTP кодах статуса и о том, для чего каждый из них предназначен, ознакомьтесь с <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network - Сеть разработчиков Mozilla">MDN</abbr> документацией об HTTP статус-кодах</a>.
 
 ///
 
@@ -74,7 +74,7 @@ FastAPI знает об этом и создаст документацию Open
 
 Рассмотрим предыдущий пример еще раз:
 
-{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
 
 `201` – это код статуса "Создано".
 
@@ -82,7 +82,7 @@ FastAPI знает об этом и создаст документацию Open
 
 Для удобства вы можете использовать переменные из `fastapi.status`.
 
-{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
 
 Они содержат те же числовые значения, но позволяют использовать автозавершение редактора кода для выбора кода статуса:
 
@@ -90,7 +90,7 @@ FastAPI знает об этом и создаст документацию Open
 
 /// note | Технические детали
 
-Вы также можете использовать `from starlette import status` вместо `from fastapi import status`.
+Вы также можете использовать `from starlette import status`.
 
 **FastAPI** позволяет использовать как `starlette.status`, так и `fastapi.status` исключительно для удобства разработчиков. Но поставляется fastapi.status непосредственно из Starlette.
 
index e4a97c88017d2468ab5c77b49fa0504da0f0f0c6..c7381aae25fc22fe953731a66f1d1a5cf1fd9faa 100644 (file)
@@ -74,7 +74,7 @@ OpenAPI 3.1.0 (используется начиная с FastAPI 0.99.0) доб
 
 Когда вы делаете это, примеры становятся частью внутренней **JSON Schema** для данных тела запроса.
 
-Тем не менее, на <abbr title="2023-08-26">момент написания этого</abbr> Swagger UI, инструмент, отвечающий за отображение UI документации, не поддерживает показ нескольких примеров для данных в **JSON Schema**. Но ниже есть обходной путь.
+Тем не менее, на <dfn title="2023-08-26">момент написания этого</dfn> Swagger UI, инструмент, отвечающий за отображение UI документации, не поддерживает показ нескольких примеров для данных в **JSON Schema**. Но ниже есть обходной путь.
 
 ### Специфические для OpenAPI `examples` { #openapi-specific-examples }
 
index 983e85e661930dfd4d60de444f541690ed5acfab..9b9673b8420d3f6abdf534735be15d8d0bae4112 100644 (file)
@@ -20,7 +20,7 @@
 
 Скопируйте пример в файл `main.py`:
 
-{* ../../docs_src/security/tutorial001_an_py39.py *}
+{* ../../docs_src/security/tutorial001_an_py310.py *}
 
 ## Запуск { #run-it }
 
@@ -132,7 +132,7 @@ OAuth2 был спроектирован так, чтобы бэкенд или
 
 При создании экземпляра класса `OAuth2PasswordBearer` мы передаем параметр `tokenUrl`. Этот параметр содержит URL, который клиент (фронтенд, работающий в браузере пользователя) будет использовать для отправки `username` и `password`, чтобы получить токен.
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
 
 /// tip | Подсказка
 
@@ -170,7 +170,7 @@ oauth2_scheme(some, parameters)
 
 Теперь вы можете передать `oauth2_scheme` как зависимость с `Depends`.
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
 
 Эта зависимость предоставит `str`, который будет присвоен параметру `token` *функции-обработчика пути*.
 
index c6bc07cc1638e69ac0d3ea3df255c7904d201e00..8388b672c73662c5442bba2185a78a30177ee498 100644 (file)
@@ -2,7 +2,7 @@
 
 В предыдущей главе система безопасности (основанная на системе внедрения зависимостей) передавала *функции-обработчику пути* `token` типа `str`:
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
 
 Но это всё ещё не слишком полезно.
 
index ebac013b6c1a5dc656adb6bb497206afb79a8072..bd8da824b3157b24b82384f77e071e079d06cfd1 100644 (file)
@@ -1,56 +1,56 @@
-# Ð\9dаÑ\81Ñ\82Ñ\80ойка Ð°Ð²Ñ\82оÑ\80изаÑ\86ии { #security }
+# Ð\91езопаÑ\81ноÑ\81Ñ\82Ñ\8c { #security }
 
 Существует множество способов обеспечения безопасности, аутентификации и авторизации.
 
-Обычно эта тема является достаточно сложной и трудной.
+Обычно эта тема является достаточно сложной и «трудной».
 
\92о Ð¼Ð½Ð¾Ð³Ð¸Ñ\85 Ñ\84Ñ\80еймвоÑ\80каÑ\85 Ð¸ Ñ\81иÑ\81Ñ\82емаÑ\85 Ñ\82олÑ\8cко Ñ\80абоÑ\82а Ñ\81 Ð¾Ð¿Ñ\80еделением Ð´Ð¾Ñ\81Ñ\82Ñ\83пов Ðº Ð¿Ñ\80иложениÑ\8e Ð¸ Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ией Ñ\82Ñ\80ебÑ\83еÑ\82 Ð·Ð½Ð°Ñ\87иÑ\82елÑ\8cнÑ\8bÑ\85 Ð·Ð°Ñ\82Ñ\80аÑ\82 Ñ\83Ñ\81илий Ð¸ Ð½Ð°Ð¿Ð¸Ñ\81аниÑ\8f Ð¼Ð½Ð¾Ð¶ÐµÑ\81Ñ\82ва ÐºÐ¾Ð´Ð° (во Ð¼Ð½Ð¾Ð³Ð¸Ñ\85 Ñ\81лÑ\83Ñ\87аÑ\8fÑ\85 ÐµÐ³Ð¾ Ð¾Ð±Ñ\8aÑ\91м Ð¼Ð¾Ð¶ÐµÑ\82 Ñ\81оÑ\81Ñ\82авлÑ\8fÑ\82Ñ\8c Ð±Ð¾Ð»ÐµÐµ 50% от всего написанного кода).
\92о Ð¼Ð½Ð¾Ð³Ð¸Ñ\85 Ñ\84Ñ\80еймвоÑ\80каÑ\85 Ð¸ Ñ\81иÑ\81Ñ\82емаÑ\85 Ñ\82олÑ\8cко Ñ\80абоÑ\82а Ñ\81 Ð±ÐµÐ·Ð¾Ð¿Ð°Ñ\81ноÑ\81Ñ\82Ñ\8cÑ\8e Ð¸ Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ией Ñ\82Ñ\80ебÑ\83еÑ\82 Ð·Ð½Ð°Ñ\87иÑ\82елÑ\8cнÑ\8bÑ\85 Ð·Ð°Ñ\82Ñ\80аÑ\82 Ñ\83Ñ\81илий Ð¸ Ð½Ð°Ð¿Ð¸Ñ\81аниÑ\8f Ð¼Ð½Ð¾Ð¶ÐµÑ\81Ñ\82ва ÐºÐ¾Ð´Ð° (во Ð¼Ð½Ð¾Ð³Ð¸Ñ\85 Ñ\81лÑ\83Ñ\87аÑ\8fÑ\85 ÐµÐ³Ð¾ Ð¾Ð±Ñ\8aÑ\91м Ð¼Ð¾Ð¶ÐµÑ\82 Ñ\81оÑ\81Ñ\82авлÑ\8fÑ\82Ñ\8c 50% Ð¸Ð»Ð¸ Ð±Ð¾Ð»ÐµÐµ от всего написанного кода).
 
-**FastAPI** предоставляет несколько инструментов, которые помогут вам настроить **Авторизацию** легко, быстро, стандартным способом, без необходимости изучать все её тонкости.
+**FastAPI** предоставляет несколько инструментов, которые помогут вам работать с **безопасностью** легко, быстро, стандартным способом, без необходимости изучать и разбираться во всех спецификациях по безопасности.
 
-Но сначала давайте рассмотрим некоторые небольшие концепции.
+Но сначала давайте рассмотрим несколько небольших концепций.
 
-## Ð\9aÑ\83да-Ñ\82о Ñ\82оÑ\80опиÑ\88Ñ\8cÑ\81Ñ\8f? { #in-a-hurry }
+## Ð\9dеÑ\82 Ð²Ñ\80емени? { #in-a-hurry }
 
\95Ñ\81ли Ð²Ð°Ð¼ Ð½Ðµ Ð½Ñ\83жна Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\8f Ð¾ ÐºÐ°ÐºÐ¸Ñ\85-либо Ð¸Ð· Ñ\81ледÑ\83Ñ\8eÑ\89иÑ\85 Ñ\82еÑ\80минов Ð¸ Ð²Ð°Ð¼ Ð¿Ñ\80оÑ\81Ñ\82о Ð½Ñ\83жно Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð·Ð°Ñ\89иÑ\82Ñ\83 Ñ\81 Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ией Ð½Ð° Ð¾Ñ\81нове Ð»Ð¾Ð³Ð¸Ð½Ð° Ð¸ Ð¿Ð°Ñ\80олÑ\8f *пÑ\80Ñ\8fмо Ñ\81ейÑ\87аÑ\81*, переходите к следующим главам.
\95Ñ\81ли Ð²Ð°Ð¼ Ð½Ðµ Ð²Ð°Ð¶Ð½Ñ\8b ÐºÐ°ÐºÐ¸Ðµ-либо Ð¸Ð· Ñ\8dÑ\82иÑ\85 Ñ\82еÑ\80минов Ð¸ Ð²Ð°Ð¼ Ð¿Ñ\80оÑ\81Ñ\82о Ð½Ñ\83жно Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð·Ð°Ñ\89иÑ\82Ñ\83 Ñ\81 Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ией Ð½Ð° Ð¾Ñ\81нове Ð¸Ð¼ÐµÐ½Ð¸ Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8f Ð¸ Ð¿Ð°Ñ\80олÑ\8f Ð¿Ñ\80Ñ\8fмо Ñ\81ейÑ\87аÑ\81, переходите к следующим главам.
 
 ## OAuth2 { #oauth2 }
 
-OAuth2 - это протокол, который определяет несколько способов обработки аутентификации и авторизации.
+OAuth2 - это спецификация, которая определяет несколько способов обработки аутентификации и авторизации.
 
\9eн Ð´Ð¾Ð²Ð¾Ð»Ñ\8cно Ð¾Ð±Ñ\88иÑ\80ен Ð¸ Ð¾Ñ\85ваÑ\82Ñ\8bваеÑ\82 несколько сложных вариантов использования.
­Ñ\82о Ð´Ð¾Ð²Ð¾Ð»Ñ\8cно Ð¾Ð±Ñ\88иÑ\80наÑ\8f Ñ\81пеÑ\86иÑ\84икаÑ\86иÑ\8f, Ð¾Ñ\85ваÑ\82Ñ\8bваÑ\8eÑ\89аÑ\8f несколько сложных вариантов использования.
 
-OAuth2 включает в себя способы аутентификации с использованием "третьей стороны".
+Она включает способы аутентификации с использованием «третьей стороны».
 
­Ñ\82о Ñ\82о, Ñ\87Ñ\82о Ð¸Ñ\81полÑ\8cзÑ\83Ñ\8eÑ\82 Ð¿Ð¾Ð´ Ñ\81обой Ð²Ñ\81е ÐºÐ½Ð¾Ð¿ÐºÐ¸ "вÑ\85од Ñ\81 Ð¿Ð¾Ð¼Ð¾Ñ\89Ñ\8cÑ\8e Facebook, Google, X (Twitter), GitHub" Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\85 Ð°Ð²Ñ\82оÑ\80изаÑ\86ии.
\98менно Ñ\8dÑ\82о Ð¸Ñ\81полÑ\8cзÑ\83еÑ\82Ñ\81Ñ\8f Ð²Ð¾ Ð²Ñ\81еÑ\85 Ñ\81иÑ\81Ñ\82емаÑ\85 Ñ\81 ÐºÐ½Ð¾Ð¿ÐºÐ°Ð¼Ð¸ Â«Ð²Ð¾Ð¹Ñ\82и Ñ\81 Ð¿Ð¾Ð¼Ð¾Ñ\89Ñ\8cÑ\8e Facebook, Google, X (Twitter), GitHub».
 
 ### OAuth 1 { #oauth-1 }
 
-Ранее использовался протокол OAuth 1, который сильно отличается от OAuth2 и является более сложным, поскольку он включал прямые описания того, как шифровать сообщение.
+Ранее использовался OAuth 1, который сильно отличается от OAuth2 и является более сложным, поскольку он включал прямые спецификации того, как шифровать обмен данными.
 
 В настоящее время он не очень популярен и не используется.
 
-OAuth2 не указывает, как шифровать сообщение, он ожидает, что ваше приложение будет обслуживаться по протоколу HTTPS.
+OAuth2 не указывает, как шифровать обмен данными, он ожидает, что ваше приложение будет обслуживаться по протоколу HTTPS.
 
 /// tip | Подсказка
 
-В разделе **Развертывание** вы увидите как настроить протокол HTTPS бесплатно, используя Traefik и Let's Encrypt.
+В разделе о **развертывании** вы увидите, как настроить HTTPS бесплатно, используя Traefik и Let's Encrypt.
 
 ///
 
 ## OpenID Connect { #openid-connect }
 
-OpenID Connect - это еще один протокол, основанный на **OAuth2**.
+OpenID Connect — это ещё одна спецификация, основанная на **OAuth2**.
 
-Он просто расширяет OAuth2, уточняя некоторые вещи, не имеющие однозначного определения в OAuth2, в попытке сделать его более совместимым.
+Она просто расширяет OAuth2, уточняя некоторые вещи, которые относительно неоднозначны в OAuth2, стараясь сделать его более совместимым.
 
-Например, для входа в Google используется OpenID Connect (который под собой использует OAuth2).
+Например, для входа в Google используется OpenID Connect (который под капотом использует OAuth2).
 
 Но вход в Facebook не поддерживает OpenID Connect. У него есть собственная вариация OAuth2.
 
-### OpenID (не "OpenID Connect") { #openid-not-openid-connect }
+### OpenID (не «OpenID Connect») { #openid-not-openid-connect }
 
-Также ранее использовался стандарт "OpenID", который пытался решить ту же проблему, что и **OpenID Connect**, но не был основан на OAuth2.
+Также ранее использовалась спецификация «OpenID», которая пыталась решить ту же задачу, что и **OpenID Connect**, но не была основана на OAuth2.
 
 Таким образом, это была полноценная дополнительная система.
 
@@ -62,45 +62,45 @@ OpenAPI (ранее известный как Swagger) - это открытая
 
 **FastAPI** основан на **OpenAPI**.
 
-Это то, что делает возможным наличие множества автоматических интерактивных интерфейсов документирования, сгенерированного кода и т.д.
+Это то, что делает возможными несколько автоматических интерактивных интерфейсов документации, генерацию кода и т.д.
 
\92 OpenAPI ÐµÑ\81Ñ\82Ñ\8c Ñ\81поÑ\81об Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ð½ÐµÑ\81колÑ\8cко "Ñ\81Ñ\85ем" безопасности.
\92 OpenAPI ÐµÑ\81Ñ\82Ñ\8c Ñ\81поÑ\81об Ð¾Ð¿Ñ\80еделиÑ\82Ñ\8c Ð½ÐµÑ\81колÑ\8cко Â«Ñ\81Ñ\85ем» безопасности.
 
¢Ð°ÐºÐ¸Ð¼ Ð¾Ð±Ñ\80азом, Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð²Ð¾Ñ\81полÑ\8cзоваÑ\82Ñ\8cÑ\81Ñ\8f Ð¿Ñ\80еимÑ\83Ñ\89еÑ\81Ñ\82вами Ð\92Ñ\81еÑ\85 Ñ\8dÑ\82иÑ\85 Ñ\81Ñ\82андаÑ\80Ñ\82нÑ\8bÑ\85 Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82ов, включая интерактивные системы документирования.
\98Ñ\81полÑ\8cзÑ\83Ñ\8f Ð¸Ñ\85, Ð²Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð²Ð¾Ñ\81полÑ\8cзоваÑ\82Ñ\8cÑ\81Ñ\8f Ð¿Ñ\80еимÑ\83Ñ\89еÑ\81Ñ\82вами Ð²Ñ\81еÑ\85 Ñ\8dÑ\82иÑ\85 Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82ов, Ð¾Ñ\81нованнÑ\8bÑ\85 Ð½Ð° Ñ\81Ñ\82андаÑ\80Ñ\82аÑ\85, включая интерактивные системы документирования.
 
-OpenAPI Ð¼Ð¾Ð¶ÐµÑ\82 Ð¸Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ñ\81ледÑ\83Ñ\8eÑ\89ие Ñ\81Ñ\85емÑ\8b Ð°Ð²Ñ\82оÑ\80изаÑ\86ии:
+OpenAPI Ð¾Ð¿Ñ\80еделÑ\8fеÑ\82 Ñ\81ледÑ\83Ñ\8eÑ\89ие Ñ\81Ñ\85емÑ\8b Ð±ÐµÐ·Ð¾Ð¿Ð°Ñ\81ноÑ\81Ñ\82и:
 
-* `apiKey`: Ñ\83никалÑ\8cнÑ\8bй Ð¸Ð´ÐµÐ½Ñ\82иÑ\84икаÑ\82оÑ\80 Ð´Ð»Ñ\8f Ð¿Ñ\80иложениÑ\8f, ÐºÐ¾Ñ\82оÑ\80Ñ\8bй Ð¼Ð¾Ð¶ÐµÑ\82 Ð±Ñ\8bÑ\82Ñ\8c Ð¿Ð¾Ð»Ñ\83Ñ\87ен из:
-    * Ð\9fаÑ\80амеÑ\82Ñ\80ов запроса.
-    * Заголовка.
-    * Cookies.
-* `http`: стандартные системы аутентификации по протоколу HTTP, включая:
-    * `bearer`: заголовок `Authorization` со значением `Bearer {уникальный токен}`. Это унаследовано от OAuth2.
-    * Базовая аутентификация по протоколу HTTP.
+* `apiKey`: Ñ\81пеÑ\86иÑ\84иÑ\87нÑ\8bй Ð´Ð»Ñ\8f Ð¿Ñ\80иложениÑ\8f ÐºÐ»Ñ\8eÑ\87, ÐºÐ¾Ñ\82оÑ\80Ñ\8bй Ð¼Ð¾Ð¶ÐµÑ\82 Ð¿Ð¾Ñ\81Ñ\82Ñ\83паÑ\82Ñ\8c из:
+    * Ð¿Ð°Ñ\80амеÑ\82Ñ\80а запроса.
+    * HTTP-заголовка.
+    * cookie.
+* `http`: стандартные системы аутентификации по HTTP, включая:
+    * `bearer`: HTTP-заголовок `Authorization` со значением `Bearer ` плюс токен. Это унаследовано от OAuth2.
+    * Базовая аутентификация по HTTP.
     * HTTP Digest и т.д.
-* `oauth2`: все способы обеспечения безопасности OAuth2 называемые "потоки" (англ. "flows").
-    * Некоторые из этих "потоков" подходят для реализации аутентификации через сторонний сервис использующий OAuth 2.0 (например, Google, Facebook, X (Twitter), GitHub и т.д.):
+* `oauth2`: все способы OAuth2 для обеспечения безопасности (называются «потоками»).
+    * Несколько из этих «потоков» подходят для построения провайдера аутентификации OAuth 2.0 (например, Google, Facebook, X (Twitter), GitHub и т.д.):
         * `implicit`
         * `clientCredentials`
         * `authorizationCode`
-    * Но есть один конкретный "поток", который может быть идеально использован для обработки аутентификации непосредственно в том же приложении:
-        * `password`: в некоторых следующих главах будут рассмотрены примеры этого.
-* `openIdConnect`: способ определить, как автоматически обнаруживать данные аутентификации OAuth2.
-    * Ð­то автоматическое обнаружение определено в спецификации OpenID Connect.
+    * Но есть один конкретный «поток», который можно идеально использовать для обработки аутентификации непосредственно в этом же приложении:
+        * `password`: в некоторых следующих главах будут приведены примеры.
+* `openIdConnect`: имеет способ определить, как автоматически обнаруживать данные аутентификации OAuth2.
+    * Ð\98менно Ñ\8dто автоматическое обнаружение определено в спецификации OpenID Connect.
 
 
 /// tip | Подсказка
 
-Интеграция сторонних сервисов для аутентификации/авторизации таких как Google, Facebook, X (Twitter), GitHub и т.д. осуществляется достаточно легко.
+Интеграция сторонних провайдеров аутентификации/авторизации, таких как Google, Facebook, X (Twitter), GitHub и т.д., также возможна и относительно проста.
 
-Самой Ñ\81ложной Ð¿Ñ\80облемой Ñ\8fвлÑ\8fеÑ\82Ñ\81Ñ\8f Ñ\81оздание Ñ\82акого Ð¿Ñ\80овайдеÑ\80а Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ии/авÑ\82оÑ\80изаÑ\86ии, Ð½Ð¾ **FastAPI** Ð¿Ñ\80едоÑ\81Ñ\82авлÑ\8fеÑ\82 Ð²Ð°Ð¼ Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82Ñ\8b, Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñ\8fÑ\8eÑ\89ие Ð»ÐµÐ³ÐºÐ¾ Ñ\8dÑ\82о Ñ\81делаÑ\82Ñ\8c, Ð²Ñ\8bполнÑ\8fÑ\8f Ð¿Ñ\80и Ñ\8dÑ\82ом Ð²Ñ\81Ñ\8e Ñ\82Ñ\8fжелую работу за вас.
+Самой Ñ\81ложной Ð·Ð°Ð´Ð°Ñ\87ей Ñ\8fвлÑ\8fеÑ\82Ñ\81Ñ\8f Ñ\81оздание Ñ\82акого Ð¿Ñ\80овайдеÑ\80а Ð°Ñ\83Ñ\82енÑ\82иÑ\84икаÑ\86ии/авÑ\82оÑ\80изаÑ\86ии, Ð½Ð¾ **FastAPI** Ð¿Ñ\80едоÑ\81Ñ\82авлÑ\8fеÑ\82 Ð²Ð°Ð¼ Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82Ñ\8b, Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñ\8fÑ\8eÑ\89ие Ð»ÐµÐ³ÐºÐ¾ Ñ\8dÑ\82о Ñ\81делаÑ\82Ñ\8c, Ð²Ñ\8bполнÑ\8fÑ\8f Ð¿Ñ\80и Ñ\8dÑ\82ом Ð²Ñ\81Ñ\8e Ñ\82Ñ\8fжÑ\91лую работу за вас.
 
 ///
 
-## Ð\9fÑ\80еимÑ\83Ñ\89еÑ\81Ñ\82ва **FastAPI** { #fastapi-utilities }
+## Ð\98нÑ\81Ñ\82Ñ\80Ñ\83менÑ\82Ñ\8b **FastAPI** { #fastapi-utilities }
 
-Fast API предоставляет несколько инструментов для каждой из этих схем безопасности в модуле `fastapi.security`, которые упрощают использование этих механизмов безопасности.
+FastAPI предоставляет несколько инструментов для каждой из этих схем безопасности в модуле `fastapi.security`, которые упрощают использование этих механизмов безопасности.
 
\92 Ñ\81ледÑ\83Ñ\8eÑ\89иÑ\85 Ð³Ð»Ð°Ð²Ð°Ñ\85 Ð²Ñ\8b Ñ\83видиÑ\82е, ÐºÐ°Ðº Ð¾Ð±ÐµÐ·Ð¾Ð¿Ð°Ñ\81иÑ\82Ñ\8c Ñ\81вой API, используя инструменты, предоставляемые **FastAPI**.
\92 Ñ\81ледÑ\83Ñ\8eÑ\89иÑ\85 Ð³Ð»Ð°Ð²Ð°Ñ\85 Ð²Ñ\8b Ñ\83видиÑ\82е, ÐºÐ°Ðº Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð±ÐµÐ·Ð¾Ð¿Ð°Ñ\81ноÑ\81Ñ\82Ñ\8c Ð² Ð²Ð°Ñ\88 API, используя инструменты, предоставляемые **FastAPI**.
 
-И вы также увидите, как он автоматически интегрируется в систему интерактивной документации.
+И вы также увидите, как это автоматически интегрируется в систему интерактивной документации.
index 803491f53905cc9252ab18959f84558a305ed81a..7838b07df4136c9770731ec16540bc1e3b9d061f 100644 (file)
@@ -1,10 +1,10 @@
 # OAuth2 с паролем (и хешированием), Bearer с JWT-токенами { #oauth2-with-password-and-hashing-bearer-with-jwt-tokens }
 
-Теперь, когда у нас определен процесс обеспечения безопасности, давайте сделаем приложение действительно безопасным, используя токены <abbr title="JSON Web Tokens  веб‑токены JSON">JWT</abbr> и безопасное хеширование паролей.
+Теперь, когда у нас определен процесс обеспечения безопасности, давайте сделаем приложение действительно безопасным, используя токены <abbr title="JSON Web Tokens - веб‑токены JSON">JWT</abbr> и безопасное хеширование паролей.
 
 Этот код можно реально использовать в своем приложении, сохранять хэши паролей в базе данных и т.д.
 
-Мы продолжим разбираться, начиная с того места, на котором остановились в предыдущей главе.
+Мы продолжим разбираться, начиная с того места, на котором остановились в предыдущей главе, и расширим его.
 
 ## Про JWT { #about-jwt }
 
@@ -43,9 +43,11 @@ $ pip install pyjwt
 </div>
 
 /// info | Дополнительная информация
+
 Если вы планируете использовать алгоритмы цифровой подписи, такие как RSA или ECDSA, вам следует установить зависимость библиотеки криптографии `pyjwt[crypto]`.
 
 Подробнее об этом можно прочитать в <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">документации по установке PyJWT</a>.
+
 ///
 
 ## Хеширование паролей { #password-hashing }
@@ -83,11 +85,13 @@ $ pip install "pwdlib[argon2]"
 </div>
 
 /// tip | Подсказка
+
 С помощью `pwdlib` можно даже настроить его на чтение паролей, созданных **Django**, плагином безопасности **Flask** или многими другими библиотеками.
 
 Таким образом, вы сможете, например, совместно использовать одни и те же данные из приложения Django в базе данных с приложением FastAPI. Или постепенно мигрировать Django-приложение, используя ту же базу данных.
 
 При этом пользователи смогут одновременно входить в систему как из приложения Django, так и из приложения **FastAPI**.
+
 ///
 
 ## Хеширование и проверка паролей { #hash-and-verify-the-passwords }
@@ -97,11 +101,13 @@ $ pip install "pwdlib[argon2]"
 Создайте экземпляр PasswordHash с рекомендованными настройками — он будет использоваться для хэширования и проверки паролей.
 
 /// tip | Подсказка
+
 pwdlib также поддерживает алгоритм хеширования bcrypt, но не включает устаревшие алгоритмы — для работы с устаревшими хэшами рекомендуется использовать библиотеку passlib.
 
 Например, вы можете использовать ее для чтения и проверки паролей, сгенерированных другой системой (например, Django), но хэшировать все новые пароли другим алгоритмом, например Argon2 или Bcrypt.
 
 И при этом быть совместимым со всеми этими системами.
+
 ///
 
 Создайте служебную функцию для хэширования пароля, поступающего от пользователя.
@@ -110,10 +116,16 @@ pwdlib также поддерживает алгоритм хешировани
 
 И еще одну — для аутентификации и возврата пользователя.
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,51,58:59,62:63,72:79] *}
+
+Когда `authenticate_user` вызывается с именем пользователя, которого нет в базе данных, мы все равно запускаем `verify_password` с использованием фиктивного хэша.
+
+Это гарантирует, что эндпоинт отвечает примерно за одно и то же время вне зависимости от того, существует имя пользователя или нет, предотвращая тайминговые атаки (атака по времени), с помощью которых можно было бы перечислять существующие имена пользователей.
 
 /// note | Технические детали
+
 Если проверить новую (фальшивую) базу данных `fake_users_db`, то можно увидеть, как теперь выглядит хэшированный пароль: `"$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc"`.
+
 ///
 
 ## Работа с JWT токенами { #handle-jwt-tokens }
@@ -144,7 +156,7 @@ $ openssl rand -hex 32
 
 Создайте служебную функцию для генерации нового токена доступа.
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,82:90] *}
 
 ## Обновление зависимостей { #update-the-dependencies }
 
@@ -154,7 +166,7 @@ $ openssl rand -hex 32
 
 Если токен недействителен, то сразу же верните HTTP-ошибку.
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[93:110] *}
 
 ## Обновление *операции пути* `/token` { #update-the-token-path-operation }
 
@@ -162,7 +174,7 @@ $ openssl rand -hex 32
 
 Создайте реальный токен доступа JWT и верните его
 
-{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
+{* ../../docs_src/security/tutorial004_an_py310.py hl[121:136] *}
 
 ### Технические подробности о JWT ключе `sub` { #technical-details-about-the-jwt-subject-sub }
 
@@ -202,7 +214,9 @@ Username: `johndoe`
 Password: `secret`
 
 /// check | Проверка
+
 Обратите внимание, что нигде в коде не используется открытый текст пароля "`secret`", мы используем только его хэшированную версию.
+
 ///
 
 <img src="/img/tutorial/security/image08.png">
@@ -225,7 +239,9 @@ Password: `secret`
 <img src="/img/tutorial/security/image10.png">
 
 /// note | Техническая информация
+
 Обратите внимание на HTTP-заголовок `Authorization`, значение которого начинается с `Bearer `.
+
 ///
 
 ## Продвинутое использование `scopes` { #advanced-usage-with-scopes }
index 36ff32c8ef9182b4301affd1af6b17d97dc047c2..4b86a40139debcf3db931041b19704f4a8b14887 100644 (file)
@@ -236,7 +236,7 @@ UserInDB(
 
 <img src="/img/tutorial/security/image06.png">
 
\95Ñ\81ли Ñ\89Ñ\91лкнÑ\83Ñ\82Ñ\8c Ð½Ð° Ð·Ð½Ð°Ñ\87ке Ð·Ð°Ð¼ÐºÐ° Ð¸ Ð²Ñ\8bйÑ\82и Ð¸Ð· Ñ\81иÑ\81Ñ\82емÑ\8b, Ð° Ð·Ð°Ñ\82ем Ð¿Ð¾Ð¿Ñ\8bÑ\82аÑ\82Ñ\8cÑ\81Ñ\8f выполнить ту же операцию ещё раз, будет выдана ошибка HTTP 401:
\95Ñ\81ли Ñ\89Ñ\91лкнÑ\83Ñ\82Ñ\8c Ð½Ð° Ð·Ð½Ð°Ñ\87ке Ð·Ð°Ð¼ÐºÐ° Ð¸ Ð²Ñ\8bйÑ\82и Ð¸Ð· Ñ\81иÑ\81Ñ\82емÑ\8b, Ð° Ð·Ð°Ñ\82ем Ð¿Ð¾Ð¿Ñ\80обоваÑ\82Ñ\8c выполнить ту же операцию ещё раз, будет выдана ошибка HTTP 401:
 
 ```JSON
 {
index 1d034653377d40b9ea769e0d337f9d940c1f9fdc..ed67739cc97d540428e4777c44eed3dcef7c6cd1 100644 (file)
@@ -8,7 +8,7 @@
 
 /// tip | Подсказка
 
-Вы можете использовать любую другую библиотеку для работы с SQL или NoSQL базами данных (иногда их называют <abbr title="Object Relational Mapper  Объектно-реляционный маппер: термин для библиотеки, где некоторые классы представляют SQL-таблицы, а экземпляры представляют строки в этих таблицах">"ORMs"</abbr>), FastAPI ничего не навязывает. 😎
+Вы можете использовать любую другую библиотеку для работы с SQL или NoSQL базами данных (иногда их называют <abbr title="Object Relational Mapper - Объектно-реляционный маппер: термин для библиотеки, где некоторые классы представляют SQL-таблицы, а экземпляры представляют строки в этих таблицах">"ORMs"</abbr>), FastAPI ничего не навязывает. 😎
 
 ///
 
@@ -344,7 +344,7 @@ $ fastapi dev main.py
 
 </div>
 
-Если вы перейдёте в UI API `/docs`, вы увидите, что он обновился: теперь при создании героя он не ожидает получить `id` от клиента и т. д.
+Если вы перейдёте в UI API `/docs`, вы увидите, что он обновился: теперь при создании героя он не ожидает получить `id` от клиента и т.д.
 
 <div class="screenshot">
 <img src="/img/tutorial/sql-databases/image02.png">
@@ -354,4 +354,4 @@ $ fastapi dev main.py
 
 Вы можете использовать <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">**SQLModel**</a> для взаимодействия с SQL базой данных и упростить код с помощью *моделей данных* и *моделей-таблиц*.
 
-Гораздо больше вы можете узнать в документации **SQLModel**, там есть более подробный мини-<a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">туториал по использованию SQLModel с **FastAPI**</a>. 🚀
+Гораздо больше вы можете узнать в документации **SQLModel**, там есть более подробное мини-<a href="https://sqlmodel.tiangolo.com/tutorial/fastapi/" class="external-link" target="_blank">руководство по использованию SQLModel с **FastAPI**</a>. 🚀
index f40cfe9b04b3e0376479db396bb2a03105beeb50..3b0cab8313d2a217c219d3d9c9a781e47139c03e 100644 (file)
@@ -7,7 +7,7 @@
 * Импортируйте `StaticFiles`.
 * "Примонтируйте" экземпляр `StaticFiles()` к определённому пути.
 
-{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
 
 /// note | Технические детали
 
index ab58429c517099d9342ac92ebf8aeb28557de80d..6dd2fe579a3d96328410fea82882a282d2a0bc71 100644 (file)
@@ -30,7 +30,7 @@ $ pip install httpx
 
 Напишите простое утверждение с `assert` дабы проверить истинность Python-выражения (это тоже стандарт `pytest`).
 
-{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
 
 /// tip | Подсказка
 
@@ -76,7 +76,7 @@ $ pip install httpx
 В файле `main.py` находится Ваше приложение **FastAPI**:
 
 
-{* ../../docs_src/app_testing/app_a_py39/main.py *}
+{* ../../docs_src/app_testing/app_a_py310/main.py *}
 
 ### Файл тестов { #testing-file }
 
@@ -92,7 +92,7 @@ $ pip install httpx
 
 Так как оба файла находятся в одной директории, для импорта объекта приложения из файла `main` в файл `test_main` Вы можете использовать относительный импорт:
 
-{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
 
 
 ...и писать дальше тесты, как и раньше.
@@ -119,7 +119,7 @@ $ pip install httpx
 
 Ещё есть операция `POST`, и она может вернуть несколько ошибок.
 
-Обе *операции пути* требуют наличия в запросе заголовка `X-Token`.
+Обе *операции пути* требуют наличия в запросе HTTP-заголовка `X-Token`.
 
 {* ../../docs_src/app_testing/app_b_an_py310/main.py *}
 
@@ -139,7 +139,7 @@ $ pip install httpx
 * Передаёте *path*-параметры или *query*-параметры, вписав их непосредственно в строку URL.
 * Передаёте JSON в теле запроса, передав Python-объект (например: `dict`) через именованный параметр `json`.
 * Если же Вам необходимо отправить *форму с данными* вместо JSON, то используйте параметр `data` вместо `json`.
-* Для передачи *заголовков*, передайте объект `dict` через параметр `headers`.
+* Для передачи *HTTP-заголовков*, передайте объект `dict` через параметр `headers`.
 * Для передачи *cookies* также передайте `dict`, но через параметр `cookies`.
 
 Для получения дополнительной информации о передаче данных на бэкенд с помощью `httpx` или `TestClient` ознакомьтесь с <a href="https://www.python-httpx.org" class="external-link" target="_blank">документацией HTTPX</a>.
index 43136298a3f0be3a318d9e9b6a63211022b586cd..f931cc3c8273e0037f6cffdcb31c63446129bfea 100644 (file)
@@ -53,7 +53,7 @@ $ cd awesome-project
 
 ## Создание виртуального окружения { #create-a-virtual-environment }
 
-Когда вы начинаете работать над Python‑проектом **впервые**, создайте виртуальное окружение **<abbr title="есть и другие опции, но это простой ориентир">внутри вашего проекта</abbr>**.
+Когда вы начинаете работать над Python‑проектом **впервые**, создайте виртуальное окружение **<dfn title="есть и другие опции, но это простой ориентир">внутри вашего проекта</dfn>**.
 
 /// tip | Подсказка
 
@@ -166,7 +166,7 @@ $ source .venv/Scripts/activate
 
 Каждый раз, когда вы устанавливаете **новый пакет** в это окружение, **активируйте** окружение снова.
 
-Это гарантирует, что если вы используете **программу терминала (<abbr title="command line interface  интерфейс командной строки">CLI</abbr>)**, установленную этим пакетом, вы будете использовать именно ту, что из вашего виртуального окружения, а не какую‑то глобально установленную, возможно другой версии, чем вам нужна.
+Это гарантирует, что если вы используете **программу терминала (<abbr title="command line interface - интерфейс командной строки">CLI</abbr>)**, установленную этим пакетом, вы будете использовать именно ту, что из вашего виртуального окружения, а не какую‑то глобально установленную, возможно другой версии, чем вам нужна.
 
 ///