Browse Source

🌐 Add Russian translation for `docs/ru/docs/tutorial/dependencies/index.md` (#11223)

pull/11268/head
👁Max👁 1 year ago
committed by GitHub
parent
commit
299bf22ad8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 350
      docs/ru/docs/tutorial/dependencies/index.md

350
docs/ru/docs/tutorial/dependencies/index.md

@ -0,0 +1,350 @@
# Зависимости
**FastAPI** имеет очень мощную и интуитивную систему **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>**.
Она проектировалась таким образом, чтобы быть простой в использовании и облегчить любому разработчику интеграцию других компонентов с **FastAPI**.
## Что такое "Dependency Injection" (инъекция зависимости)
**"Dependency Injection"** в программировании означает, что у вашего кода (в данном случае, вашей *функции обработки пути*) есть способы объявить вещи, которые запрашиваются для работы и использования: "зависимости".
И потом эта система (в нашем случае **FastAPI**) организует всё, что требуется, чтобы обеспечить ваш код этой зависимостью (сделать "инъекцию" зависимости).
Это очень полезно, когда вам нужно:
* Обеспечить общую логику (один и тот же алгоритм снова и снова).
* Общее соединение с базой данных.
* Обеспечение безопасности, аутентификации, запроса роли и т.п.
* И многое другое.
Всё это минимизирует повторение кода.
## Первые шаги
Давайте рассмотрим очень простой пример. Он настолько простой, что на данный момент почти бесполезный.
Но таким способом мы можем сфокусироваться на том, как же всё таки работает система **Dependency Injection**.
### Создание зависимости или "зависимого"
Давайте для начала сфокусируемся на зависимостях.
Это просто функция, которая может принимать все те же параметры, что и *функции обработки пути*:
=== "Python 3.10+"
```Python hl_lines="8-9"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="8-11"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="9-12"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Подсказка"
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
```Python hl_lines="6-7"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Подсказка"
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
```Python hl_lines="8-11"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
**И всё.**
**2 строки.**
И теперь она той же формы и структуры, что и все ваши *функции обработки пути*.
Вы можете думать об *функции обработки пути* как о функции без "декоратора" (без `@app.get("/some-path")`).
И она может возвращать всё, что требуется.
В этом случае, эта зависимость ожидает:
* Необязательный query-параметр `q` с типом `str`
* Необязательный query-параметр `skip` с типом `int`, и значением по умолчанию `0`
* Необязательный query-параметр `limit` с типом `int`, и значением по умолчанию `100`
И в конце она возвращает `dict`, содержащий эти значения.
!!! Информация
**FastAPI** добавил поддержку для `Annotated` (и начал её рекомендовать) в версии 0.95.0.
Если у вас более старая версия, будут ошибки при попытке использовать `Annotated`.
Убедитесь, что вы [Обновили FastAPI версию](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} до, как минимум 0.95.1, перед тем как использовать `Annotated`.
### Import `Depends`
=== "Python 3.10+"
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Подсказка"
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
```Python hl_lines="1"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Подсказка"
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
### Объявите зависимость в "зависимом"
Точно так же, как вы использовали `Body`, `Query` и т.д. с вашей *функцией обработки пути* для параметров, используйте `Depends` с новым параметром:
=== "Python 3.10+"
```Python hl_lines="13 18"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="15 20"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="16 21"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Подсказка"
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
```Python hl_lines="11 16"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Подсказка"
Настоятельно рекомендуем использовать `Annotated` версию насколько это возможно.
```Python hl_lines="15 20"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
`Depends` работает немного иначе. Вы передаёте в `Depends` одиночный параметр, который будет похож на функцию.
Вы **не вызываете его** на месте (не добавляете скобочки в конце: 👎 *your_best_func()*👎), просто передаёте как параметр в `Depends()`.
И потом функция берёт параметры так же, как *функция обработки пути*.
!!! tip "Подсказка"
В следующей главе вы увидите, какие другие вещи, помимо функций, можно использовать в качестве зависимостей.
Каждый раз, когда новый запрос приходит, **FastAPI** позаботится о:
* Вызове вашей зависимости ("зависимого") функции с корректными параметрами.
* Получении результата из вашей функции.
* Назначении результата в параметр в вашей *функции обработки пути*.
```mermaid
graph TB
common_parameters(["common_parameters"])
read_items["/items/"]
read_users["/users/"]
common_parameters --> read_items
common_parameters --> read_users
```
Таким образом, вы пишете общий код один раз, и **FastAPI** позаботится о его вызове для ваших *операций с путями*.
!!! check "Проверка"
Обратите внимание, что вы не создаёте специальный класс и не передаёте его куда-то в **FastAPI** для регистрации, или что-то в этом роде.
Вы просто передаёте это в `Depends`, и **FastAPI** знает, что делать дальше.
## Объединяем с `Annotated` зависимостями
В приведенном выше примере есть небольшое **повторение кода**.
Когда вам нужно использовать `common_parameters()` зависимость, вы должны написать весь параметр с аннотацией типов и `Depends()`:
```Python
commons: Annotated[dict, Depends(common_parameters)]
```
Но потому что мы используем `Annotated`, мы можем хранить `Annotated` значение в переменной и использовать его в нескольких местах:
=== "Python 3.10+"
```Python hl_lines="12 16 21"
{!> ../../../docs_src/dependencies/tutorial001_02_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="14 18 23"
{!> ../../../docs_src/dependencies/tutorial001_02_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="15 19 24"
{!> ../../../docs_src/dependencies/tutorial001_02_an.py!}
```
!!! tip "Подсказка"
Это стандартный синтаксис python и называется "type alias", это не особенность **FastAPI**.
Но потому что **FastAPI** базируется на стандартах Python, включая `Annotated`, вы можете использовать этот трюк в вашем коде. 😎
Зависимости продолжат работу как ожидалось, и **лучшая часть** в том, что **информация о типе будет сохранена**. Это означает, что ваш редактор кода будет корректно обрабатывать **автодополнения**, **встроенные ошибки** и так далее. То же самое относится и к инструментам, таким как `mypy`.
Это очень полезно, когда вы интегрируете это в **большую кодовую базу**, используя **одинаковые зависимости** снова и снова во **многих** ***операциях пути***.
## Использовать `async` или не `async`
Для зависимостей, вызванных **FastAPI** (то же самое, что и ваши *функции обработки пути*), те же правила, что приняты для определения ваших функций.
Вы можете использовать `async def` или обычное `def`.
Вы также можете объявить зависимости с `async def` внутри обычной `def` *функции обработки пути*, или `def` зависимости внутри `async def` *функции обработки пути*, и так далее.
Это всё не важно. **FastAPI** знает, что нужно сделать. 😎
!!! note "Информация"
Если вам эта тема не знакома, прочтите [Async: *"In a hurry?"*](../../async.md){.internal-link target=_blank} раздел о `async` и `await` в документации.
## Интеграция с OpenAPI
Все заявления о запросах, валидаторы, требования ваших зависимостей (и подзависимостей) будут интегрированы в соответствующую OpenAPI-схему.
В интерактивной документации будет вся информация по этим зависимостям тоже:
<img src="/img/tutorial/dependencies/image01.png">
## Простое использование
Если вы посмотрите на фото, *функция обработки пути* объявляется каждый раз, когда вычисляется путь, и тогда **FastAPI** позаботится о вызове функции с корректными параметрами, извлекая информацию из запроса.
На самом деле, все (или большинство) веб-фреймворков работают по схожему сценарию.
Вы никогда не вызываете эти функции на месте. Их вызовет ваш фреймворк (в нашем случае, **FastAPI**).
С системой Dependency Injection, вы можете сообщить **FastAPI**, что ваша *функция обработки пути* "зависит" от чего-то ещё, что должно быть извлечено перед вашей *функцией обработки пути*, и **FastAPI** позаботится об извлечении и инъекции результата.
Другие распространённые термины для описания схожей идеи "dependency injection" являются:
- ресурсность
- доставка
- сервисность
- инъекция
- компонентность
## **FastAPI** подключаемые модули
Инъекции и модули могут быть построены с использованием системы **Dependency Injection**. Но на самом деле, **нет необходимости создавать новые модули**, просто используя зависимости, можно объявить бесконечное количество интеграций и взаимодействий, которые доступны вашей *функции обработки пути*.
И зависимости могут быть созданы очень простым и интуитивным способом, что позволяет вам просто импортировать нужные пакеты Python и интегрировать их в API функции за пару строк.
Вы увидите примеры этого в следующих главах о реляционных и NoSQL базах данных, безопасности и т.д.
## Совместимость с **FastAPI**
Простота Dependency Injection делает **FastAPI** совместимым с:
- всеми реляционными базами данных
- NoSQL базами данных
- внешними пакетами
- внешними API
- системами авторизации, аутентификации
- системами мониторинга использования API
- системами ввода данных ответов
- и так далее.
## Просто и сильно
Хотя иерархическая система Dependency Injection очень проста для описания и использования, она по-прежнему очень мощная.
Вы можете описывать зависимости в очередь, и они уже будут вызываться друг за другом.
Когда иерархическое дерево построено, система **Dependency Injection** берет на себя решение всех зависимостей для вас (и их подзависимостей) и обеспечивает (инъектирует) результат на каждом шаге.
Например, у вас есть 4 API-эндпоинта (*операции пути*):
- `/items/public/`
- `/items/private/`
- `/users/{user_id}/activate`
- `/items/pro/`
Тогда вы можете требовать разные права для каждого из них, используя зависимости и подзависимости:
```mermaid
graph TB
current_user(["current_user"])
active_user(["active_user"])
admin_user(["admin_user"])
paying_user(["paying_user"])
public["/items/public/"]
private["/items/private/"]
activate_user["/users/{user_id}/activate"]
pro_items["/items/pro/"]
current_user --> active_user
active_user --> admin_user
active_user --> paying_user
current_user --> public
active_user --> private
admin_user --> activate_user
paying_user --> pro_items
```
## Интегрировано с **OpenAPI**
Все эти зависимости, объявляя свои требования, также добавляют параметры, проверки и т.д. к вашим операциям *path*.
**FastAPI** позаботится о добавлении всего этого в схему открытого API, чтобы это отображалось в системах интерактивной документации.
Loading…
Cancel
Save