]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
🌐 Sync Russian docs (#14509)
authorMotov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Thu, 11 Dec 2025 21:25:03 +0000 (22:25 +0100)
committerGitHub <noreply@github.com>
Thu, 11 Dec 2025 21:25:03 +0000 (22:25 +0100)
* Translate missing pages

* Update outdated translations

26 files changed:
docs/ru/docs/_llm-test.md
docs/ru/docs/advanced/additional-responses.md
docs/ru/docs/advanced/advanced-dependencies.md
docs/ru/docs/advanced/behind-a-proxy.md
docs/ru/docs/advanced/dataclasses.md
docs/ru/docs/advanced/openapi-callbacks.md
docs/ru/docs/advanced/path-operation-advanced-configuration.md
docs/ru/docs/advanced/response-directly.md
docs/ru/docs/advanced/settings.md
docs/ru/docs/deployment/cloud.md
docs/ru/docs/deployment/fastapicloud.md [new file with mode: 0644]
docs/ru/docs/deployment/index.md
docs/ru/docs/how-to/authentication-error-status-code.md [new file with mode: 0644]
docs/ru/docs/how-to/configure-swagger-ui.md
docs/ru/docs/how-to/custom-request-and-route.md
docs/ru/docs/index.md
docs/ru/docs/project-generation.md
docs/ru/docs/resources/index.md
docs/ru/docs/tutorial/bigger-applications.md
docs/ru/docs/tutorial/cookie-param-models.md
docs/ru/docs/tutorial/first-steps.md
docs/ru/docs/tutorial/handling-errors.md
docs/ru/docs/tutorial/security/index.md
docs/ru/docs/tutorial/sql-databases.md
docs/ru/docs/tutorial/testing.md
docs/ru/docs/virtual-environments.md

index 476cc19244cc383a18cc627c3e0140a20bf1a836..9a15f6bb21a2d49946455eab1255c87628da85aa 100644 (file)
@@ -15,7 +15,7 @@
 
 Тесты:
 
-## Фрагменты кода { #code-snippets}
+## Фрагменты кода { #code-snippets }
 
 //// tab | Тест
 
@@ -53,7 +53,7 @@ LLM, вероятно, переведёт это неправильно. Инт
 
 ////
 
-## Кавычки во фрагментах кода { #quotes-in-code-snippets}
+## Кавычки во фрагментах кода { #quotes-in-code-snippets }
 
 //// tab | Тест
 
index c63c0c08b00a889c62dcec238335db077fa75fa1..1fc3715e4120d8bbf6315533cf27c0e68bd2fddf 100644 (file)
 
 Например, вы можете добавить дополнительный тип содержимого `image/png`, объявив, что ваша операция пути может возвращать JSON‑объект (с типом содержимого `application/json`) или PNG‑изображение:
 
-{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
+{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
 
 /// note | Примечание
 
@@ -237,7 +237,7 @@ new_dict = {**old_dict, "new key": "new value"}
 
 Например:
 
-{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
+{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
 
 ## Дополнительная информация об ответах OpenAPI { #more-information-about-openapi-responses }
 
index 339c0a3631118d9091de0925ae04b8f385b8292e..cc6691b300d4833663973876bd93836438d9f897 100644 (file)
@@ -144,7 +144,7 @@ checker(q="somequery")
 
 ### Фоновые задачи и зависимости с `yield`, технические детали { #background-tasks-and-dependencies-with-yield-technical-details }
 
-До FastAPI 0.106.0 вызывать исключения после `yield` было невозможно: код после `yield` в зависимостях выполнялся уже после отправки ответа, поэтому [Обработчики исключений](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} к тому моменту уже отработали.
+До FastAPI 0.106.0 вызывать исключения после `yield` было невозможно: код после `yield` в зависимостях выполнялся уже после отправки ответа, поэтому [Обработчики исключений](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} к тому моменту уже отработали.
 
 Так было сделано в основном для того, чтобы можно было использовать те же объекты, «отданные» зависимостями через `yield`, внутри фоновых задач, потому что код после `yield` выполнялся после завершения фоновых задач.
 
index 281cb7f7358b1812283b41fc906f9fef50830d4c..7119efe2dc18bd778a87632ffcaed9c44c815d6f 100644 (file)
@@ -64,7 +64,7 @@ https://mysuperapp.com/items/
 
 ///
 
-### Как работают пересылаемые заголовки прокси
+### Как работают пересылаемые заголовки прокси { #how-proxy-forwarded-headers-work }
 
 Ниже показано, как прокси добавляет пересылаемые заголовки между клиентом и сервером приложения:
 
@@ -443,6 +443,14 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 ///
 
+/// note | Технические детали
+
+Свойство `servers` в спецификации OpenAPI является необязательным.
+
+Если вы не укажете параметр `servers`, а `root_path` равен `/`, то свойство `servers` в сгенерированной схеме OpenAPI по умолчанию будет опущено. Это эквивалентно серверу со значением `url` равным `/`.
+
+///
+
 ### Отключить автоматическое добавление сервера из `root_path` { #disable-automatic-server-from-root-path }
 
 Если вы не хотите, чтобы FastAPI добавлял автоматический сервер, используя `root_path`, укажите параметр `root_path_in_servers=False`:
index 816f744048d2ec1887032f0b38f773fd6fb51e8e..c37ce30236e5a789b814e80979d797f46a9ac586 100644 (file)
@@ -4,7 +4,7 @@ FastAPI построен поверх **Pydantic**, и я показывал в
 
 Но FastAPI также поддерживает использование <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> тем же способом:
 
-{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
+{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}
 
 Это по-прежнему поддерживается благодаря **Pydantic**, так как в нём есть <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">встроенная поддержка `dataclasses`</a>.
 
@@ -32,7 +32,7 @@ FastAPI построен поверх **Pydantic**, и я показывал в
 
 Вы также можете использовать `dataclasses` в параметре `response_model`:
 
-{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
+{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}
 
 Этот dataclass будет автоматически преобразован в Pydantic dataclass.
 
@@ -48,7 +48,7 @@ FastAPI построен поверх **Pydantic**, и я показывал в
 
 В таком случае вы можете просто заменить стандартные `dataclasses` на `pydantic.dataclasses`, которая является полностью совместимой заменой (drop-in replacement):
 
-{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
+{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
 
 1. Мы по-прежнему импортируем `field` из стандартных `dataclasses`.
 
index faf58370be79550a19e52e126f0e3055e22edd51..de7e283017639f25f2d714ca2b0310ea8d357a02 100644 (file)
@@ -31,7 +31,7 @@
 
 Эта часть вполне обычна, большая часть кода вам уже знакома:
 
-{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
 
 /// tip | Совет
 
@@ -90,7 +90,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
 
 Сначала создайте новый `APIRouter`, который будет содержать один или несколько обратных вызовов.
 
-{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
 
 ### Создайте *операцию пути* для обратного вызова { #create-the-callback-path-operation }
 
@@ -101,7 +101,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
 * Вероятно, в ней должно быть объявление тела запроса, например `body: InvoiceEvent`.
 * А также может быть объявление модели ответа, например `response_model=InvoiceEventReceived`.
 
-{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
 
 Есть 2 основных отличия от обычной *операции пути*:
 
@@ -169,7 +169,7 @@ https://www.external.org/events/invoices/2expen51ve
 
 Теперь используйте параметр `callbacks` в *декораторе операции пути вашего API*, чтобы передать атрибут `.routes` (это, по сути, просто `list` маршрутов/*операций пути*) из этого маршрутизатора обратных вызовов:
 
-{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
+{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
 
 /// tip | Совет
 
index fcb3cd47f2fcf8554935389c5b55ac11d34507df..78a16a5583f54398a018eac313535aefc9262cc8 100644 (file)
@@ -50,7 +50,7 @@
 
 Эта часть не попадёт в документацию, но другие инструменты (например, Sphinx) смогут использовать остальное.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
 
 ## Дополнительные ответы { #additional-responses }
 
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
 
 ////
 
 //// tab | Pydantic v1
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
 
 ////
 
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
 
 ////
 
 //// tab | Pydantic v1
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
 
 ////
 
index febd40ed4a7759439c2f8d3cb7096382666d1e1c..3c10633e91249a0a189a8953ba7cdd4aa70b5fe7 100644 (file)
@@ -34,7 +34,7 @@
 
 В таких случаях вы можете использовать `jsonable_encoder` для преобразования данных перед передачей их в ответ:
 
-{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
+{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
 
 /// note | Технические детали
 
index a335548c3ce863f942164c2f29a46bb9b3cdc5a3..0ef46fb13c17e4e442a20d5dec789e45b0dfbb88 100644 (file)
@@ -148,7 +148,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 Продолжая предыдущий пример, ваш файл `config.py` может выглядеть так:
 
-{* ../../docs_src/settings/app02/config.py hl[10] *}
+{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
 
 Обратите внимание, что теперь мы не создаем экземпляр по умолчанию `settings = Settings()`.
 
@@ -174,7 +174,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 Далее будет очень просто предоставить другой объект настроек во время тестирования, создав переопределение зависимости для `get_settings`:
 
-{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
+{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
 
 В переопределении зависимости мы задаем новое значение `admin_email` при создании нового объекта `Settings`, а затем возвращаем этот новый объект.
 
@@ -217,7 +217,7 @@ APP_NAME="ChimichangApp"
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/settings/app03_an/config.py hl[9] *}
+{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
 
 /// tip | Совет
 
@@ -229,7 +229,7 @@ APP_NAME="ChimichangApp"
 
 //// tab | Pydantic v1
 
-{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
+{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
 
 /// tip | Совет
 
index a400d18434115e184ff6b0d21c608ce03ee6f0c8..955db2a1578ac82c6a9faeae4706e4cbd26c81cb 100644 (file)
@@ -4,11 +4,19 @@
 
 В большинстве случаев у основных облачных провайдеров есть руководства по развертыванию FastAPI на их платформе.
 
-## Облачные провайдеры — спонсоры { #cloud-providers-sponsors }
+## FastAPI Cloud { #fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, стоящими за **FastAPI**.
+
+Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API с минимальными усилиями.
 
-Некоторые облачные провайдеры ✨ [**спонсируют FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ — это обеспечивает непрерывное и здоровое развитие FastAPI и его экосистемы.
+Он переносит тот же **опыт разработчика** создания приложений с FastAPI на их **развертывание** в облаке. 🎉
+
+FastAPI Cloud — основной спонсор и источник финансирования для open source проектов *FastAPI and friends*. ✨
+
+## Облачные провайдеры — спонсоры { #cloud-providers-sponsors }
 
\98 Ñ\8dÑ\82о Ð¿Ð¾ÐºÐ°Ð·Ñ\8bваеÑ\82 Ð¸Ñ\85 Ð¸Ñ\81кÑ\80еннÑ\8eÑ\8e Ð¿Ñ\80ивеÑ\80женноÑ\81Ñ\82Ñ\8c FastAPI Ð¸ ÐµÐ³Ð¾ Ñ\81ообÑ\89еÑ\81Ñ\82вÑ\83 (вам): Ð¾Ð½Ð¸ Ð½Ðµ Ñ\82олÑ\8cко Ñ\85оÑ\82Ñ\8fÑ\82 Ð¿Ñ\80едоÑ\81Ñ\82авиÑ\82Ñ\8c Ð²Ð°Ð¼ Ñ\85оÑ\80оÑ\88ий Ñ\81еÑ\80виÑ\81, Ð½Ð¾ Ð¸ Ñ\81Ñ\82Ñ\80емÑ\8fÑ\82Ñ\81Ñ\8f Ð³Ð°Ñ\80анÑ\82иÑ\80оваÑ\82Ñ\8c, Ñ\87Ñ\82о Ñ\83 Ð²Ð°Ñ\81 Ð±Ñ\83деÑ\82 Ñ\85оÑ\80оÑ\88ий Ð¸ Ñ\81Ñ\82абилÑ\8cнÑ\8bй Ñ\84Ñ\80еймвоÑ\80к â\80\94 FastAPI. 🙇
\9dекоÑ\82оÑ\80Ñ\8bе Ð´Ñ\80Ñ\83гие Ð¾Ð±Ð»Ð°Ñ\87нÑ\8bе Ð¿Ñ\80овайдеÑ\80Ñ\8b â\9c¨ [**Ñ\81понÑ\81иÑ\80Ñ\83Ñ\8eÑ\82 FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} â\9c¨ Ñ\82оже. 🙇
 
 Возможно, вы захотите попробовать их сервисы и воспользоваться их руководствами:
 
diff --git a/docs/ru/docs/deployment/fastapicloud.md b/docs/ru/docs/deployment/fastapicloud.md
new file mode 100644 (file)
index 0000000..9e7430e
--- /dev/null
@@ -0,0 +1,65 @@
+# FastAPI Cloud { #fastapi-cloud }
+
+Вы можете развернуть своё приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> одной командой, присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
+
+## Вход { #login }
+
+Убедитесь, что у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉).
+
+Затем выполните вход:
+
+<div class="termy">
+
+```console
+$ fastapi login
+
+You are logged in to FastAPI Cloud 🚀
+```
+
+</div>
+
+## Деплой { #deploy }
+
+Теперь разверните приложение одной командой:
+
+<div class="termy">
+
+```console
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
+
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
+```
+
+</div>
+
+Вот и всё! Теперь вы можете открыть своё приложение по этому URL. ✨
+
+## О FastAPI Cloud { #about-fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, что и **FastAPI**.
+
+Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API с минимальными усилиями.
+
+Он переносит тот же **опыт разработчика**, что вы получаете при создании приложений на FastAPI, на их **развертывание** в облаке. 🎉
+
+Он также возьмёт на себя большинство вещей, которые требуются при развертывании приложения, например:
+
+* HTTPS
+* Репликация с автоматическим масштабированием на основе запросов
+* и т.д.
+
+FastAPI Cloud — основной спонсор и источник финансирования open source‑проектов «FastAPI и друзья». ✨
+
+## Развертывание у других облачных провайдеров { #deploy-to-other-cloud-providers }
+
+FastAPI — проект с открытым исходным кодом и основан на стандартах. Вы можете развернуть приложения FastAPI у любого облачного провайдера на ваш выбор.
+
+Следуйте руководствам вашего облачного провайдера, чтобы развернуть приложения FastAPI у них. 🤓
+
+## Развертывание на собственном сервере { #deploy-your-own-server }
+
+Позже в этом руководстве по **развертыванию** я также расскажу все детали — чтобы вы понимали, что происходит, что нужно сделать и как развернуть приложения FastAPI самостоятельно, в том числе на собственных серверах. 🤓
index c85fa0d52913956ef3062a5df12e7f5e7b23ead4..ffb77641dd32b00f1b6400f729bf703658978ade 100644 (file)
 
 ## Стратегии развёртывания { #deployment-strategies }
 
\92 Ð·Ð°Ð²Ð¸Ñ\81имоÑ\81Ñ\82и Ð¾Ñ\82 Ð²Ð°Ñ\88его ÐºÐ¾Ð½ÐºÑ\80еÑ\82ного Ñ\81лÑ\83Ñ\87аÑ\8f, ÐµÑ\81Ñ\82Ñ\8c Ð½ÐµÑ\81колÑ\8cко Ñ\81поÑ\81обов Ñ\81делаÑ\82Ñ\8c Ñ\8dÑ\82о.
\95Ñ\81Ñ\82Ñ\8c Ð½ÐµÑ\81колÑ\8cко Ñ\81поÑ\81обов Ñ\81делаÑ\82Ñ\8c Ñ\8dÑ\82о, Ð² Ð·Ð°Ð²Ð¸Ñ\81имоÑ\81Ñ\82и Ð¾Ñ\82 Ð²Ð°Ñ\88его ÐºÐ¾Ð½ÐºÑ\80еÑ\82ного Ñ\81лÑ\83Ñ\87аÑ\8f Ð¸ Ð¸Ñ\81полÑ\8cзÑ\83емÑ\8bÑ\85 Ð²Ð°Ð¼Ð¸ Ð¸Ð½Ñ\81Ñ\82Ñ\80Ñ\83менÑ\82ов.
 
 Вы можете **развернуть сервер** самостоятельно, используя различные инструменты. Например, можно использовать **облачный сервис**, который выполнит часть работы за вас. Также возможны и другие варианты.
 
+Например, мы, команда, стоящая за FastAPI, создали <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a>, чтобы сделать развёртывание приложений FastAPI в облаке как можно более простым и прямолинейным, с тем же удобством для разработчика, что и при работе с FastAPI.
+
 В этом блоке я покажу вам некоторые из основных концепций, которые вы, вероятно, должны иметь в виду при развертывании приложения **FastAPI** (хотя большинство из них применимо к любому другому типу веб-приложений).
 
 В последующих разделах вы узнаете больше деталей и методов, необходимых для этого. ✨
diff --git a/docs/ru/docs/how-to/authentication-error-status-code.md b/docs/ru/docs/how-to/authentication-error-status-code.md
new file mode 100644 (file)
index 0000000..5675cec
--- /dev/null
@@ -0,0 +1,17 @@
+# Использование старых статус-кодов ошибок аутентификации 403 { #use-old-403-authentication-error-status-codes }
+
+До версии FastAPI `0.122.0`, когда встроенные утилиты безопасности возвращали ошибку клиенту после неудачной аутентификации, они использовали HTTP статус-код `403 Forbidden`.
+
+Начиная с версии FastAPI `0.122.0`, используется более подходящий HTTP статус-код `401 Unauthorized`, и в ответе возвращается имеющий смысл HTTP-заголовок `WWW-Authenticate` в соответствии со спецификациями HTTP, <a href="https://datatracker.ietf.org/doc/html/rfc7235#section-3.1" class="external-link" target="_blank">RFC 7235</a>, <a href="https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized" class="external-link" target="_blank">RFC 9110</a>.
+
+Но если по какой-то причине ваши клиенты зависят от старого поведения, вы можете вернуть его, переопределив метод `make_not_authenticated_error` в ваших Security-классах.
+
+Например, вы можете создать подкласс `HTTPBearer`, который будет возвращать ошибку `403 Forbidden` вместо стандартной `401 Unauthorized`:
+
+{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
+
+/// tip | Совет
+
+Обратите внимание, что функция возвращает экземпляр исключения, не вызывает его. Выброс выполняется остальным внутренним кодом.
+
+///
index 4793cc9db3d797f493e33a87a465841db30bf161..9d104423d7fd9a666483b0eaef8216f57ac7230d 100644 (file)
@@ -40,7 +40,7 @@ FastAPI включает некоторые параметры конфигур
 
 Это включает следующие настройки по умолчанию:
 
-{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
+{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
 
 Вы можете переопределить любую из них, указав другое значение в аргументе `swagger_ui_parameters`.
 
index 1b8d7f7ed3998255ff1c43dbc869b8a5077d5fcd..feef9670ad1e8e97ecd63b813da208ca8161ebf1 100644 (file)
@@ -42,7 +42,7 @@
 
 Таким образом, один и тот же класс маршрута сможет обрабатывать как gzip-сжатые, так и несжатые запросы.
 
-{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
+{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
 
 ### Создать пользовательский класс `GzipRoute` { #create-a-custom-gziproute-class }
 
@@ -54,7 +54,7 @@
 
 Здесь мы используем её, чтобы создать `GzipRequest` из исходного HTTP-запроса.
 
-{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
+{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
 
 /// note | Технические детали
 
 
 Нужно лишь обработать запрос внутри блока `try`/`except`:
 
-{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
+{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
 
 Если произойдёт исключение, экземпляр `Request` всё ещё будет в области видимости, поэтому мы сможем прочитать тело запроса и использовать его при обработке ошибки:
 
-{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
+{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
 
 ## Пользовательский класс `APIRoute` в роутере { #custom-apiroute-class-in-a-router }
 
 Вы также можете задать параметр `route_class` у `APIRouter`:
 
-{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
+{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
 
 В этом примере *операции пути*, объявленные в `router`, будут использовать пользовательский класс `TimedRoute` и получат дополнительный HTTP-заголовок `X-Response-Time` в ответе с временем, затраченным на формирование ответа:
 
-{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
+{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}
index 75cd63223db7fa7677a4ef84d7f70c5915d418c3..b562cbe5bcfd6d2becfe7ea84384cc302884cc04 100644 (file)
@@ -52,14 +52,20 @@ FastAPI — это современный, быстрый (высокопрои
 
 <!-- sponsors -->
 
-{% if sponsors %}
+### Ключевой-спонсор { #keystone-sponsor }
+
+{% for sponsor in sponsors.keystone -%}
+<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+{% endfor -%}
+
+### Золотые и серебряные спонсоры { #gold-and-silver-sponsors }
+
 {% for sponsor in sponsors.gold -%}
 <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor -%}
 {%- for sponsor in sponsors.silver -%}
 <a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
 {% endfor %}
-{% endif %}
 
 <!-- /sponsors -->
 
@@ -444,6 +450,58 @@ item: Item
     * **сессии с использованием cookie**
     * ...и многое другое.
 
+### Разверните приложение (опционально) { #deploy-your-app-optional }
+
+При желании вы можете развернуть своё приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, присоединяйтесь к списку ожидания, если ещё не сделали этого. 🚀
+
+Если у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉), вы можете развернуть ваше приложение одной командой.
+
+Перед развертыванием убедитесь, что вы вошли в систему:
+
+<div class="termy">
+
+```console
+$ fastapi login
+
+You are logged in to FastAPI Cloud 🚀
+```
+
+</div>
+
+Затем разверните приложение:
+
+<div class="termy">
+
+```console
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
+
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
+```
+
+</div>
+
+Вот и всё! Теперь вы можете открыть ваше приложение по этой ссылке. ✨
+
+#### О FastAPI Cloud { #about-fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, что и **FastAPI**.
+
+Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API при минимальных усилиях.
+
+Он переносит тот же **опыт разработчика**, что и при создании приложений на FastAPI, на их **развертывание** в облаке. 🎉
+
+FastAPI Cloud — основной спонсор и источник финансирования для проектов с открытым исходным кодом из экосистемы *FastAPI and friends*. ✨
+
+#### Развертывание у других облачных провайдеров { #deploy-to-other-cloud-providers }
+
+FastAPI — это open source и стандартизированный фреймворк. Вы можете развернуть приложения FastAPI у любого облачного провайдера на ваш выбор.
+
+Следуйте руководствам вашего облачного провайдера по развертыванию приложений FastAPI. 🤓
+
 ## Производительность { #performance }
 
 Независимые бенчмарки TechEmpower показывают приложения **FastAPI**, работающие под управлением Uvicorn, как <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">один из самых быстрых доступных фреймворков Python</a>, уступающий только самим Starlette и Uvicorn (используются внутри FastAPI). (*)
index 8c5681115b895cc9214bc3bec9305fb60b5669a0..dbedf76fe35cc1ea50bc928746227707da98968e 100644 (file)
@@ -13,8 +13,8 @@
     - 🔍 [Pydantic](https://docs.pydantic.dev), используется FastAPI, для валидации данных и управления настройками.
     - 💾 [PostgreSQL](https://www.postgresql.org) в качестве SQL‑базы данных.
 - 🚀 [React](https://react.dev) для фронтенда.
-    - 💃 Используются TypeScript, хуки, [Vite](https://vitejs.dev) и другие части современного фронтенд‑стека.
-    - 🎨 [Chakra UI](https://chakra-ui.com) для компонентов фронтенда.
+    - 💃 Используются TypeScript, хуки, Vite и другие части современного фронтенд‑стека.
+    - 🎨 [Tailwind CSS](https://tailwindcss.com) и [shadcn/ui](https://ui.shadcn.com) для компонентов фронтенда.
     - 🤖 Автоматически сгенерированный фронтенд‑клиент.
     - 🧪 [Playwright](https://playwright.dev) для End‑to‑End тестирования.
     - 🦇 Поддержка тёмной темы.
index 54be4e5fd300524f6c12812112d3c0e8296311b5..faf80f7f495c3e28130a3df35b700d83b10e5f07 100644 (file)
@@ -1,3 +1,3 @@
 # Ресурсы { #resources }
 
-Дополнительные ресурсы, внешние ссылки, статьи и многое другое. ✈️
+Дополнительные ресурсы, внешние ссылки и многое другое. ✈️
index b832383cc9a32ca43db58c478cad066877d6ba79..5e5d6ada94f85b037618918724e2a2b154809dc4 100644 (file)
@@ -85,17 +85,13 @@ from app.routers import items
 
 Точно также, как и в случае с классом `FastAPI`, вам нужно импортировать и создать объект класса `APIRouter`.
 
-```Python hl_lines="1  3" title="app/routers/users.py"
-{!../../docs_src/bigger_applications/app/routers/users.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
 
 ### Создание *эндпоинтов* с помощью `APIRouter` { #path-operations-with-apirouter }
 
 В дальнейшем используйте `APIRouter` для объявления *эндпоинтов*, точно также, как вы используете класс `FastAPI`:
 
-```Python hl_lines="6  11  16" title="app/routers/users.py"
-{!../../docs_src/bigger_applications/app/routers/users.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
 
 Вы можете думать об `APIRouter` как об "уменьшенной версии" класса FastAPI`.
 
@@ -119,35 +115,7 @@ from app.routers import items
 
 Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомизированный `X-Token` из заголовка:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="3  6-8" title="app/dependencies.py"
-{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  5-7" title="app/dependencies.py"
-{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
-```
-
-////
-
-//// tab | Python 3.8+ non-Annotated
-
-/// tip | Подсказка
-
-Мы рекомендуем использовать версию `Annotated`, когда это возможно.
-
-///
-
-```Python hl_lines="1  4-6" title="app/dependencies.py"
-{!> ../../docs_src/bigger_applications/app/dependencies.py!}
-```
-
-////
+{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
 
 /// tip | Подсказка
 
@@ -180,9 +148,7 @@ from app.routers import items
 Таким образом, вместо того чтобы добавлять все эти свойства в функцию каждого отдельного *эндпоинта*,
 мы добавим их в `APIRouter`.
 
-```Python hl_lines="5-10  16  21" title="app/routers/items.py"
-{!../../docs_src/bigger_applications/app/routers/items.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
 
 Так как каждый *эндпоинт* начинается с символа `/`:
 
@@ -241,9 +207,7 @@ async def read_item(item_id: str):
 
 Мы используем операцию относительного импорта `..` для импорта зависимости:
 
-```Python hl_lines="3" title="app/routers/items.py"
-{!../../docs_src/bigger_applications/app/routers/items.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
 
 #### Как работает относительный импорт? { #how-relative-imports-work }
 
@@ -313,9 +277,7 @@ from ...dependencies import get_token_header
 
 Но помимо этого мы можем добавить новые теги для каждого отдельного *эндпоинта*, а также некоторые дополнительные ответы (`responses`), характерные для данного *эндпоинта*:
 
-```Python hl_lines="30-31" title="app/routers/items.py"
-{!../../docs_src/bigger_applications/app/routers/items.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
 
 /// tip | Подсказка
 
@@ -341,17 +303,13 @@ from ...dependencies import get_token_header
 
 Мы даже можем объявить [глобальные зависимости](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого отдельного маршрутизатора:
 
-```Python hl_lines="1  3  7" title="app/main.py"
-{!../../docs_src/bigger_applications/app/main.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
 
 ### Импорт `APIRouter` { #import-the-apirouter }
 
 Теперь мы импортируем другие суб-модули, содержащие `APIRouter`:
 
-```Python hl_lines="4-5" title="app/main.py"
-{!../../docs_src/bigger_applications/app/main.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
 
 Так как файлы `app/routers/users.py` и `app/routers/items.py` являются суб-модулями одного и того же Python-пакета `app`, то мы сможем их импортировать, воспользовавшись операцией относительного импорта `.`.
 
@@ -414,17 +372,13 @@ from .routers.users import router
 
 Поэтому, для того чтобы использовать обе эти переменные в одном файле, мы импортировали соответствующие суб-модули:
 
-```Python hl_lines="5" title="app/main.py"
-{!../../docs_src/bigger_applications/app/main.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
 
 ### Подключение маршрутизаторов (`APIRouter`) для `users` и для `items` { #include-the-apirouters-for-users-and-items }
 
 Давайте подключим маршрутизаторы (`router`) из суб-модулей `users` и `items`:
 
-```Python hl_lines="10-11" title="app/main.py"
-{!../../docs_src/bigger_applications/app/main.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
 
 /// info | Примечание
 
@@ -465,17 +419,13 @@ from .routers.users import router
 В данном примере это сделать очень просто. Но давайте предположим, что поскольку файл используется для нескольких проектов,
 то мы не можем модифицировать его, добавляя префиксы (`prefix`), зависимости (`dependencies`), теги (`tags`), и т.д. непосредственно в `APIRouter`:
 
-```Python hl_lines="3" title="app/internal/admin.py"
-{!../../docs_src/bigger_applications/app/internal/admin.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
 
 Но, несмотря на это, мы хотим использовать кастомный префикс (`prefix`) для подключенного маршрутизатора (`APIRouter`), в результате чего, каждая *операция пути* будет начинаться с `/admin`. Также мы хотим защитить наш маршрутизатор с помощью зависимостей, созданных для нашего проекта. И ещё мы хотим включить теги (`tags`) и ответы (`responses`).
 
 Мы можем применить все вышеперечисленные настройки, не изменяя начальный `APIRouter`. Нам всего лишь нужно передать нужные параметры в `app.include_router()`.
 
-```Python hl_lines="14-17" title="app/main.py"
-{!../../docs_src/bigger_applications/app/main.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
 
 Таким образом, оригинальный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации.
 
@@ -496,9 +446,7 @@ from .routers.users import router
 
 Здесь мы это делаем ... просто, чтобы показать, что это возможно 🤷:
 
-```Python hl_lines="21-23" title="app/main.py"
-{!../../docs_src/bigger_applications/app/main.py!}
-```
+{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
 
 и это будет работать корректно вместе с другими *эндпоинтами*, добавленными с помощью `app.include_router()`.
 
index daac764e3fe74f96f6a9837195be5ceb7b2047b8..182813afdf6ce67b030b7a63d2baa87657dbdffe 100644 (file)
@@ -50,7 +50,7 @@
 
 Вы можете сконфигурировать Pydantic-модель так, чтобы запретить (`forbid`) любые дополнительные (`extra`) поля:
 
-{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
+{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
 
 Если клиент попробует отправить **дополнительные cookies**, то в ответ он получит **ошибку**.
 
index c82118cbe5f15529510ff97af413d135c53c9085..6f59d7205488803a48ba5b463333037056c92033 100644 (file)
@@ -143,6 +143,42 @@ OpenAPI определяет схему API для вашего API. И эта 
 
 Вы также можете использовать её для автоматической генерации кода для клиентов, которые взаимодействуют с вашим API. Например, для фронтенд-, мобильных или IoT-приложений.
 
+### Разверните приложение (необязательно) { #deploy-your-app-optional }
+
+При желании вы можете развернуть своё приложение FastAPI в <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, перейдите и присоединитесь к списку ожидания, если ещё не сделали этого. 🚀
+
+Если у вас уже есть аккаунт **FastAPI Cloud** (мы пригласили вас из списка ожидания 😉), вы можете развернуть приложение одной командой.
+
+Перед развертыванием убедитесь, что вы вошли в систему:
+
+<div class="termy">
+
+```console
+$ fastapi login
+
+You are logged in to FastAPI Cloud 🚀
+```
+
+</div>
+
+Затем разверните приложение:
+
+<div class="termy">
+
+```console
+$ fastapi deploy
+
+Deploying to FastAPI Cloud...
+
+✅ Deployment successful!
+
+🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
+```
+
+</div>
+
+Готово! Теперь вы можете открыть своё приложение по этому URL. ✨
+
 ## Рассмотрим поэтапно { #recap-step-by-step }
 
 ### Шаг 1: импортируйте `FastAPI` { #step-1-import-fastapi }
@@ -314,6 +350,26 @@ https://example.com/items/foo
 
 Многие другие объекты и модели будут автоматически преобразованы в JSON (включая ORM и т. п.). Попробуйте использовать те, что вам привычнее, с высокой вероятностью они уже поддерживаются.
 
+### Шаг 6: разверните приложение { #step-6-deploy-it }
+
+Разверните приложение в **<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** одной командой: `fastapi deploy`. 🎉
+
+#### О FastAPI Cloud { #about-fastapi-cloud }
+
+**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** создан тем же автором и командой, что и **FastAPI**.
+
+Он упрощает процесс **создания образа**, **развертывания** и **доступа** к API с минимальными усилиями.
+
+Он переносит тот же **опыт разработчика** при создании приложений с FastAPI на их **развертывание** в облаке. 🎉
+
+FastAPI Cloud — основной спонсор и источник финансирования для open-source проектов «FastAPI и друзья». ✨
+
+#### Развертывание у других облачных провайдеров { #deploy-to-other-cloud-providers }
+
+FastAPI — open-source и основан на стандартах. Вы можете развернуть приложения FastAPI у любого облачного провайдера по вашему выбору.
+
+Следуйте руководствам вашего облачного провайдера, чтобы развернуть приложения FastAPI у них. 🤓
+
 ## Резюме { #recap }
 
 * Импортируйте `FastAPI`.
@@ -321,3 +377,4 @@ https://example.com/items/foo
 * Напишите **декоратор операции пути**, например `@app.get("/")`.
 * Определите **функцию операции пути**; например, `def root(): ...`.
 * Запустите сервер разработки командой `fastapi dev`.
+* При желании разверните приложение командой `fastapi deploy`.
index 2378c8b04c635d76d2f401cd9826d240ce2d7664..63ca8665efab14e278aced9272c375ff22e772c7 100644 (file)
@@ -81,7 +81,7 @@
 
 ## Установка пользовательских обработчиков исключений { #install-custom-exception-handlers }
 
\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8cÑ\81кие Ð¾Ð±Ñ\80абоÑ\82Ñ\87ики Ð¸Ñ\81клÑ\8eÑ\87ений Ñ\81 Ð¿Ð¾Ð¼Ð¾Ñ\89Ñ\8cÑ\8e <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">Ñ\82о Ð¶Ðµ Ñ\81амое Ð¸Ñ\81клÑ\8eÑ\87ение - Ñ\83Ñ\82илиÑ\82Ñ\8b Ð¾Ñ\82 Starlette</a>.
\92Ñ\8b Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ\82Ñ\8c Ð¿Ð¾Ð»Ñ\8cзоваÑ\82елÑ\8cÑ\81кие Ð¾Ð±Ñ\80абоÑ\82Ñ\87ики Ð¸Ñ\81клÑ\8eÑ\87ений Ñ\81 Ð¿Ð¾Ð¼Ð¾Ñ\89Ñ\8cÑ\8e <a href="https://www.starlette.dev/exceptions/" class="external-link" target="_blank">Ñ\82еÑ\85 Ð¶Ðµ Ñ\83Ñ\82илиÑ\82 Ð¾Ð±Ñ\80абоÑ\82ки Ð¸Ñ\81клÑ\8eÑ\87ений Ð¸Ð· Starlette</a>.
 
 Допустим, у вас есть пользовательское исключение `UnicornException`, которое вы (или используемая вами библиотека) можете `вызвать`.
 
 
 Вы можете переопределить эти обработчики исключений на свои собственные.
 
-### Переопределение исключений проверки запроса { #override-request-validation-exceptions }
+### Ð\9fеÑ\80еопÑ\80еделение Ð¾Ð±Ñ\80абоÑ\82Ñ\87ика Ð¸Ñ\81клÑ\8eÑ\87ений Ð¿Ñ\80овеÑ\80ки Ð·Ð°Ð¿Ñ\80оÑ\81а { #override-request-validation-exceptions }
 
 Когда запрос содержит недопустимые данные, **FastAPI** внутренне вызывает ошибку `RequestValidationError`.
 
 
 Обработчик исключения получит объект `Request` и исключение.
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
+{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *}
 
 Теперь, если перейти к `/items/foo`, то вместо стандартной JSON-ошибки с:
 
 вы получите текстовую версию:
 
 ```
-1 validation error
-path -> item_id
-  value is not a valid integer (type=type_error.integer)
+Validation errors:
+Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to parse string as an integer
 ```
 
-#### `RequestValidationError` или `ValidationError` { #requestvalidationerror-vs-validationerror }
-
-/// warning | Внимание
-
-Это технические детали, которые можно пропустить, если они не важны для вас сейчас.
-
-///
-
-`RequestValidationError` является подклассом Pydantic <a href="https://docs.pydantic.dev/latest/concepts/models/#error-handling" class="external-link" target="_blank">`ValidationError`</a>.
-
-**FastAPI** использует его для того, чтобы, если вы используете Pydantic-модель в `response_model`, и ваши данные содержат ошибку, вы увидели ошибку в журнале.
-
-Но клиент/пользователь этого не увидит. Вместо этого клиент получит сообщение "Internal Server Error" с кодом состояния HTTP `500`.
-
-Так и должно быть, потому что если в вашем *ответе* или где-либо в вашем коде (не в *запросе* клиента) возникает Pydantic `ValidationError`, то это действительно ошибка в вашем коде.
-
-И пока вы не устраните ошибку, ваши клиенты/пользователи не должны иметь доступа к внутренней информации о ней, так как это может привести к уязвимости в системе безопасности.
-
 ### Переопределите обработчик ошибок `HTTPException` { #override-the-httpexception-error-handler }
 
 Аналогичным образом можно переопределить обработчик `HTTPException`.
 
 Например, для этих ошибок можно вернуть обычный текстовый ответ вместо JSON:
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
+{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *}
 
 /// note | Технические детали
 
@@ -188,6 +169,14 @@ path -> item_id
 
 ///
 
+/// warning | Внимание
+
+Имейте в виду, что `RequestValidationError` содержит информацию об имени файла и строке, где произошла ошибка валидации, чтобы вы могли при желании отобразить её в логах с релевантными данными.
+
+Но это означает, что если вы просто преобразуете её в строку и вернёте эту информацию напрямую, вы можете допустить небольшую утечку информации о своей системе, поэтому здесь код извлекает и показывает каждую ошибку отдельно.
+
+///
+
 ### Используйте тело `RequestValidationError` { #use-the-requestvalidationerror-body }
 
 Ошибка `RequestValidationError` содержит полученное `тело` с недопустимыми данными.
index 8fb4bf24f2d33707424a6a73ee3640621499d1c8..ebac013b6c1a5dc656adb6bb497206afb79a8072 100644 (file)
@@ -1,4 +1,4 @@
-# Настройка авторизации
+# Настройка авторизации { #security }
 
 Существует множество способов обеспечения безопасности, аутентификации и авторизации.
 
 
 Но сначала давайте рассмотрим некоторые небольшие концепции.
 
-## Куда-то торопишься?
+## Куда-то торопишься? { #in-a-hurry }
 
 Если вам не нужна информация о каких-либо из следующих терминов и вам просто нужно добавить защиту с аутентификацией на основе логина и пароля *прямо сейчас*, переходите к следующим главам.
 
-## OAuth2
+## OAuth2 { #oauth2 }
 
 OAuth2 - это протокол, который определяет несколько способов обработки аутентификации и авторизации.
 
@@ -24,7 +24,7 @@ OAuth2 включает в себя способы аутентификации
 
 Это то, что используют под собой все кнопки "вход с помощью Facebook, Google, X (Twitter), GitHub" на страницах авторизации.
 
-### OAuth 1
+### OAuth 1 { #oauth-1 }
 
 Ранее использовался протокол OAuth 1, который сильно отличается от OAuth2 и является более сложным, поскольку он включал прямые описания того, как шифровать сообщение.
 
@@ -34,11 +34,11 @@ OAuth2 не указывает, как шифровать сообщение, о
 
 /// tip | Подсказка
 
-В разделе **Развертывание** вы увидите [как настроить протокол HTTPS бесплатно, используя Traefik и Let's Encrypt.](https://fastapi.tiangolo.com/ru/deployment/https/)
+В разделе **Развертывание** вы увидите как настроить протокол HTTPS бесплатно, используя Traefik и Let's Encrypt.
 
 ///
 
-## OpenID Connect
+## OpenID Connect { #openid-connect }
 
 OpenID Connect - это еще один протокол, основанный на **OAuth2**.
 
@@ -48,7 +48,7 @@ OpenID Connect - это еще один протокол, основанный 
 
 Но вход в Facebook не поддерживает OpenID Connect. У него есть собственная вариация OAuth2.
 
-### OpenID (не "OpenID Connect")
+### OpenID (не "OpenID Connect") { #openid-not-openid-connect }
 
 Также ранее использовался стандарт "OpenID", который пытался решить ту же проблему, что и **OpenID Connect**, но не был основан на OAuth2.
 
@@ -56,7 +56,7 @@ OpenID Connect - это еще один протокол, основанный 
 
 В настоящее время не очень популярен и не используется.
 
-## OpenAPI
+## OpenAPI { #openapi }
 
 OpenAPI (ранее известный как Swagger) - это открытая спецификация для создания API (в настоящее время является частью Linux Foundation).
 
@@ -97,7 +97,7 @@ OpenAPI может использовать следующие схемы авт
 
 ///
 
-## Преимущества **FastAPI**
+## Преимущества **FastAPI** { #fastapi-utilities }
 
 Fast API предоставляет несколько инструментов для каждой из этих схем безопасности в модуле `fastapi.security`, которые упрощают использование этих механизмов безопасности.
 
index c44f37b9aee3b86b670b6aad1a3adce6e2eb921e..1d034653377d40b9ea769e0d337f9d940c1f9fdc 100644 (file)
@@ -63,9 +63,9 @@ $ pip install sqlmodel
 
 * `table=True` сообщает SQLModel, что это *модель-таблица*, она должна представлять **таблицу** в SQL базе данных, это не просто *модель данных* (как обычный класс Pydantic).
 
-* `Field(primary_key=True)` сообщает SQLModel, что `id` — это **первичный ключ** в SQL базе данных (подробнее о первичных ключах можно узнать в документации SQLModel).
+* `Field(primary_key=True)` сообщает SQLModel, что `id` — это **первичный ключ** в SQL базе данных (подробнее о первичных ключах SQL можно узнать в документации SQLModel).
 
-    Благодаря типу `int | None`, SQLModel будет знать, что этот столбец должен быть `INTEGER` в SQL базе данных и должен допускать значение `NULL`.
+    **Примечание:** Мы используем `int | None` для поля первичного ключа, чтобы в Python-коде можно было *создать объект без `id`* (`id=None`), предполагая, что база данных *сгенерирует его при сохранении*. SQLModel понимает, что база данных предоставит `id`, и *определяет столбец как `INTEGER` (не `NULL`)* в схеме базы данных. См. <a href="https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/#primary-key-id" class="external-link" target="_blank">документацию SQLModel о первичных ключах</a> для подробностей.
 
 * `Field(index=True)` сообщает SQLModel, что нужно создать **SQL индекс** для этого столбца, что позволит быстрее выполнять выборки при чтении данных, отфильтрованных по этому столбцу.
 
@@ -107,7 +107,7 @@ $ pip install sqlmodel
 
 Здесь мы создаём таблицы в обработчике события запуска приложения.
 
-Для продакшна вы, вероятно, будете использовать скрипт миграций, который выполняется до запуска приложения. 🤓
+Для продакшн вы, вероятно, будете использовать скрипт миграций, который выполняется до запуска приложения. 🤓
 
 /// tip | Подсказка
 
index 0224798b1a556034e52093af3ce69a0835986402..7354ed895fc4ddaedc644a3741e4c3727f56e3c8 100644 (file)
@@ -121,63 +121,13 @@ $ pip install httpx
 
 Обе *операции пути* требуют наличия в запросе заголовка `X-Token`.
 
-//// tab | Python 3.10+
-
-```Python
-{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python
-{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python
-{!> ../../docs_src/app_testing/app_b_an/main.py!}
-```
-
-////
-
-//// tab | Python 3.10+ без Annotated
-
-/// tip | Подсказка
-
-По возможности используйте версию с `Annotated`.
-
-///
-
-```Python
-{!> ../../docs_src/app_testing/app_b_py310/main.py!}
-```
-
-////
-
-//// tab | Python 3.8+ без Annotated
-
-/// tip | Подсказка
-
-По возможности используйте версию с `Annotated`.
-
-///
-
-```Python
-{!> ../../docs_src/app_testing/app_b/main.py!}
-```
-
-////
+{* ../../docs_src/app_testing/app_b_an_py310/main.py *}
 
 ### Расширенный файл тестов { #extended-testing-file }
 
 Теперь обновим файл `test_main.py`, добавив в него тестов:
 
-{* ../../docs_src/app_testing/app_b/test_main.py *}
+{* ../../docs_src/app_testing/app_b_an_py310/test_main.py *}
 
 
 Если Вы не знаете, как передать информацию в запросе, можете воспользоваться поисковиком (погуглить) и задать вопрос: "Как передать информацию в запросе с помощью `httpx`", можно даже спросить: "Как передать информацию в запросе с помощью `requests`", поскольку дизайн HTTPX основан на дизайне Requests.
index 5153cd4864e6b572bfcd2903a676668ea390cea8..43136298a3f0be3a318d9e9b6a63211022b586cd 100644 (file)
@@ -242,6 +242,26 @@ $ python -m pip install --upgrade pip
 
 </div>
 
+/// tip | Подсказка
+
+Иногда при попытке обновить pip вы можете получить ошибку **`No module named pip`**.
+
+Если это произошло, установите и обновите pip с помощью команды ниже:
+
+<div class="termy">
+
+```console
+$ python -m ensurepip --upgrade
+
+---> 100%
+```
+
+</div>
+
+Эта команда установит pip, если он ещё не установлен, а также гарантирует, что установленная версия pip будет не старее, чем версия, доступная в `ensurepip`.
+
+///
+
 ## Добавление `.gitignore` { #add-gitignore }
 
 Если вы используете **Git** (а вам стоит его использовать), добавьте файл `.gitignore`, чтобы исключить из Git всё, что находится в вашей `.venv`.
@@ -834,7 +854,7 @@ I solemnly swear 🐺
 * Управлять **виртуальным окружением** ваших проектов
 * Устанавливать **пакеты**
 * Управлять **зависимостями и версиями** пакетов вашего проекта
-* Обеспечивать наличие **точного** набора пакетов и версий к установке, включая их зависимости, чтобы вы были уверены, что сможете запускать проект в продакшне точно так же, как и на компьютере при разработке — это называется **locking**
+* Обеспечивать наличие **точного** набора пакетов и версий к установке, включая их зависимости, чтобы вы были уверены, что сможете запускать проект в продакшн точно так же, как и на компьютере при разработке — это называется **locking**
 * И многое другое
 
 ## Заключение { #conclusion }