diff --git a/docs/ru/docs/advanced/advanced-dependencies.md b/docs/ru/docs/advanced/advanced-dependencies.md index e971763b1..75a6f0d1f 100644 --- a/docs/ru/docs/advanced/advanced-dependencies.md +++ b/docs/ru/docs/advanced/advanced-dependencies.md @@ -58,8 +58,96 @@ checker(q="somequery") Эти примеры намеренно простые, но они показывают, как всё устроено. -В главах про безопасность есть утилитные функции, реализованные тем же способом. +В главах про безопасность есть вспомогательные функции, реализованные тем же способом. Если вы поняли всё выше, вы уже знаете, как «под капотом» работают эти утилиты для безопасности. /// + +## Зависимости с `yield`, `HTTPException`, `except` и фоновыми задачами { #dependencies-with-yield-httpexception-except-and-background-tasks } + +/// warning | Предупреждение + +Скорее всего, вам не понадобятся эти технические детали. + +Они полезны главным образом, если у вас было приложение FastAPI версии ниже 0.118.0 и вы столкнулись с проблемами зависимостей с `yield`. + +/// + +Зависимости с `yield` со временем изменялись, чтобы учитывать разные случаи применения и исправлять проблемы. Ниже — краткое резюме изменений. + +### Зависимости с `yield` и `StreamingResponse`, технические детали { #dependencies-with-yield-and-streamingresponse-technical-details } + +До FastAPI 0.118.0, если вы использовали зависимость с `yield`, код после `yield` выполнялся после возврата из *функции-обработчика пути*, но прямо перед отправкой ответа. + +Идея состояла в том, чтобы не удерживать ресурсы дольше необходимого, пока ответ «путешествует» по сети. + +Это изменение также означало, что если вы возвращали `StreamingResponse`, код после `yield` в зависимости уже успевал выполниться. + +Например, если у вас была сессия базы данных в зависимости с `yield`, `StreamingResponse` не смог бы использовать эту сессию во время стриминга данных, потому что сессия уже была закрыта в коде после `yield`. + +В версии 0.118.0 это поведение было возвращено к тому, что код после `yield` выполняется после отправки ответа. + +/// info | Информация + +Как вы увидите ниже, это очень похоже на поведение до версии 0.106.0, но с несколькими улучшениями и исправлениями краевых случаев. + +/// + +#### Сценарии с ранним выполнением кода после `yield` { #use-cases-with-early-exit-code } + +Есть некоторые сценарии со специфическими условиями, которым могло бы помочь старое поведение — выполнение кода после `yield` перед отправкой ответа. + +Например, представьте, что вы используете сессию базы данных в зависимости с `yield` только для проверки пользователя, а в самой *функции-обработчике пути* эта сессия больше не используется, и при этом ответ отправляется долго, например, это `StreamingResponse`, который медленно отправляет данные и по какой-то причине не использует базу данных. + +В таком случае сессия базы данных будет удерживаться до завершения отправки ответа, хотя если вы её не используете, удерживать её не требуется. + +Это могло бы выглядеть так: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py *} + +Код после `yield`, автоматическое закрытие `Session` в: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *} + +…будет выполнен после того, как ответ закончит отправку медленных данных: + +{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *} + +Но поскольку `generate_stream()` не использует сессию базы данных, нет реальной необходимости держать сессию открытой во время отправки ответа. + +Если у вас именно такой сценарий с SQLModel (или SQLAlchemy), вы можете явно закрыть сессию, когда она больше не нужна: + +{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *} + +Так сессия освободит подключение к базе данных, и другие запросы смогут его использовать. + +Если у вас есть другой сценарий, где нужно раннее завершение зависимости с `yield`, пожалуйста, создайте вопрос в GitHub Discussions с описанием конкретного кейса и почему вам было бы полезно иметь раннее закрытие для зависимостей с `yield`. + +Если появятся веские причины для раннего закрытия в зависимостях с `yield`, я рассмотрю добавление нового способа опционально включать раннее закрытие. + +### Зависимости с `yield` и `except`, технические детали { #dependencies-with-yield-and-except-technical-details } + +До FastAPI 0.110.0, если вы использовали зависимость с `yield`, затем перехватывали исключение с `except` в этой зависимости и не пробрасывали исключение снова, исключение автоматически пробрасывалось дальше к обработчикам исключений или к обработчику внутренней ошибки сервера. + +В версии 0.110.0 это было изменено, чтобы исправить неконтролируемое потребление памяти из‑за проброшенных исключений без обработчика (внутренние ошибки сервера) и привести поведение в соответствие с обычным поведением Python-кода. + +### Фоновые задачи и зависимости с `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} к тому моменту уже отработали. + +Так было сделано в основном для того, чтобы можно было использовать те же объекты, «отданные» зависимостями через `yield`, внутри фоновых задач, потому что код после `yield` выполнялся после завершения фоновых задач. + +В FastAPI 0.106.0 это изменили, чтобы не удерживать ресурсы, пока ответ передаётся по сети. + +/// tip | Совет + +Кроме того, фоновая задача обычно — это самостоятельный фрагмент логики, который следует обрабатывать отдельно, со своими ресурсами (например, со своим подключением к базе данных). + +Так код, скорее всего, будет чище. + +/// + +Если вы полагались на прежнее поведение, теперь ресурсы для фоновых задач следует создавать внутри самой фоновой задачи и использовать внутри неё только данные, которые не зависят от ресурсов зависимостей с `yield`. + +Например, вместо использования той же сессии базы данных, создайте новую сессию в фоновой задаче и получите объекты из базы данных с помощью этой новой сессии. И затем, вместо передачи объекта из базы данных параметром в функцию фоновой задачи, передавайте идентификатор этого объекта и заново получайте объект внутри функции фоновой задачи. diff --git a/docs/ru/docs/how-to/conditional-openapi.md b/docs/ru/docs/how-to/conditional-openapi.md index 43daa7d4b..dc987ae26 100644 --- a/docs/ru/docs/how-to/conditional-openapi.md +++ b/docs/ru/docs/how-to/conditional-openapi.md @@ -17,7 +17,7 @@ * Убедитесь, что у вас чётко определены Pydantic-модели для тел запросов и ответов. * Настройте необходимые разрешения и роли с помощью зависимостей. * Никогда не храните пароли в открытом виде, только хэши паролей. -* Реализуйте и используйте известные криптографические инструменты, например Passlib и JWT-токены, и т.д. +* Реализуйте и используйте известные криптографические инструменты, например pwdlib и JWT-токены, и т.д. * Добавьте более тонкое управление доступом с помощью OAuth2 scopes (областей) там, где это необходимо. * ...и т.п.