# Зависимости { #dependencies }
**FastAPI** имеет очень мощную, но интуитивную систему **Инъекция зависимостей**.
Она спроектирована так, чтобы быть очень простой в использовании и облегчать любому разработчику интеграцию других компонентов с **FastAPI**.
## Что такое инъекция зависимостей («Dependency Injection») { #what-is-dependency-injection }
В программировании **«Dependency Injection»** означает, что у вашего кода (в данном случае у ваших *функций обработки пути*) есть способ объявить вещи, которые требуются для его работы и использования: «зависимости».
И затем эта система (в нашем случае **FastAPI**) позаботится о том, чтобы сделать всё необходимое для предоставления вашему коду этих зависимостей (сделать «инъекцию» зависимостей).
Это очень полезно, когда вам нужно:
* Обеспечить общую логику (один и тот же алгоритм снова и снова).
* Разделять соединения с базой данных.
* Обеспечить безопасность, аутентификацию, требования к ролям и т. п.
* И многое другое...
Всё это при минимизации повторения кода.
## Первые шаги { #first-steps }
Давайте рассмотрим очень простой пример. Он настолько простой, что пока не очень полезен.
Но так мы сможем сосредоточиться на том, как работает система **Dependency Injection**.
### Создайте зависимость, или «dependable» (от чего что-то зависит) { #create-a-dependency-or-dependable }
Сначала сосредоточимся на зависимости.
Это просто функция, которая может принимать те же параметры, что и *функция обработки пути*:
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8:9] *}
И всё.
**2 строки.**
И она имеет ту же форму и структуру, что и все ваши *функции обработки пути*.
Можно думать о ней как о *функции обработки пути* без «декоратора» (без `@app.get("/some-path")`).
И она может возвращать что угодно.
В этом случае эта зависимость ожидает:
* Необязательный query-параметр `q` типа `str`.
* Необязательный query-параметр `skip` типа `int`, по умолчанию `0`.
* Необязательный query-параметр `limit` типа `int`, по умолчанию `100`.
А затем просто возвращает `dict`, содержащий эти значения.
/// info | Информация
FastAPI добавил поддержку `Annotated` (и начал рекомендовать его использование) в версии 0.95.0.
Если у вас более старая версия, вы получите ошибки при попытке использовать `Annotated`.
Убедитесь, что вы [обновили версию FastAPI](../../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} как минимум до 0.95.1, прежде чем использовать `Annotated`.
///
### Импорт `Depends` { #import-depends }
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[3] *}
### Объявите зависимость в «зависимом» { #declare-the-dependency-in-the-dependant }
Точно так же, как вы используете `Body`, `Query` и т. д. с параметрами вашей *функции обработки пути*, используйте `Depends` с новым параметром:
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
Хотя вы используете `Depends` в параметрах вашей функции так же, как `Body`, `Query` и т. д., `Depends` работает немного иначе.
В `Depends` вы передаёте только один параметр.
Этот параметр должен быть чем-то вроде функции.
Вы **не вызываете её** напрямую (не добавляйте круглые скобки в конце), просто передаёте её как параметр в `Depends()`.
И эта функция принимает параметры так же, как *функции обработки пути*.
/// tip | Подсказка
В следующей главе вы увидите, какие ещё «вещи», помимо функций, можно использовать в качестве зависимостей.
///
Каждый раз, когда приходит новый запрос, **FastAPI** позаботится о:
* Вызове вашей зависимости («dependable») с корректными параметрами.
* Получении результата из вашей функции.
* Присваивании этого результата параметру в вашей *функции обработки пути*.
```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` в нескольких местах { #share-annotated-dependencies }
В приведённых выше примерах есть небольшое **повторение кода**.
Когда вам нужно использовать зависимость `common_parameters()`, вы должны написать весь параметр с аннотацией типа и `Depends()`:
```Python
commons: Annotated[dict, Depends(common_parameters)]
```
Но поскольку мы используем `Annotated`, мы можем сохранить это значение `Annotated` в переменную и использовать его в нескольких местах:
{* ../../docs_src/dependencies/tutorial001_02_an_py310.py hl[12,16,21] *}
/// tip | Подсказка
Это стандартный Python, это называется «type alias», и это не особенность **FastAPI**.
Но поскольку **FastAPI** основан на стандартах Python, включая `Annotated`, вы можете использовать этот трюк в своём коде. 😎
///
Зависимости продолжат работать как ожидалось, и **лучшая часть** в том, что **информация о типах будет сохранена**, а значит, ваш редактор кода продолжит предоставлять **автозавершение**, **встроенные ошибки** и т.д. То же относится и к другим инструментам, таким как `mypy`.
Это особенно полезно, когда вы используете это в **большой кодовой базе**, где вы используете **одни и те же зависимости** снова и снова во **многих *операциях пути***.
## Использовать `async` или не `async` { #to-async-or-not-to-async }
Поскольку зависимости также вызываются **FastAPI** (как и ваши *функции обработки пути*), применяются те же правила при определении ваших функций.
Вы можете использовать `async def` или обычное `def`.
И вы можете объявлять зависимости с `async def` внутри обычных *функций обработки пути* `def`, или зависимости `def` внутри *функций обработки пути* `async def` и т. д.
Это не важно. **FastAPI** знает, что делать.
/// note | Примечание
Если вы не уверены, посмотрите раздел [Async: *"In a hurry?"*](../../async.md#in-a-hurry){.internal-link target=_blank} о `async` и `await` в документации.
///
## Интеграция с OpenAPI { #integrated-with-openapi }
Все объявления запросов, проверки и требования ваших зависимостей (и подзависимостей) будут интегрированы в ту же схему OpenAPI.
Поэтому в интерактивной документации будет вся информация и из этих зависимостей:
## Простое использование { #simple-usage }
Если посмотреть, *функции обработки пути* объявляются для использования всякий раз, когда *путь* и *операция* совпадают, и тогда **FastAPI** заботится о вызове функции с корректными параметрами, извлекая данные из запроса.
На самом деле все (или большинство) веб-фреймворков работают таким же образом.
Вы никогда не вызываете эти функции напрямую. Их вызывает ваш фреймворк (в нашем случае **FastAPI**).
С системой **Dependency Injection** вы также можете сообщить **FastAPI**, что ваша *функция обработки пути* «зависит» от чего-то, что должно быть выполнено перед вашей *функцией обработки пути*, и **FastAPI** позаботится о его выполнении и «инъекции» результатов.
Другие распространённые термины для описания той же идеи «dependency injection»:
* ресурсы
* провайдеры
* сервисы
* внедряемые зависимости
* компоненты
## Плагины **FastAPI** { #fastapi-plug-ins }
Интеграции и «плагины» могут быть построены с использованием системы **Dependency Injection**. Но на самом деле **нет необходимости создавать «плагины»**, так как, используя зависимости, можно объявить бесконечное количество интеграций и взаимодействий, которые становятся доступными вашим *функциям обработки пути*.
И зависимости можно создавать очень простым и интуитивным способом, который позволяет просто импортировать нужные пакеты Python и интегрировать их с вашими API-функциями в пару строк кода, *буквально*.
Вы увидите примеры этого в следующих главах о реляционных и NoSQL базах данных, безопасности и т.д.
## Совместимость с **FastAPI** { #fastapi-compatibility }
Простота системы **Dependency Injection** делает **FastAPI** совместимым с:
* всеми реляционными базами данных
* NoSQL базами данных
* внешними пакетами
* внешними API
* системами аутентификации и авторизации
* системами мониторинга использования API
* системами инъекции данных в ответы
* и т.д.
## Просто и мощно { #simple-and-powerful }
Хотя иерархическая система 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** { #integrated-with-openapi_1 }
Все эти зависимости, объявляя свои требования, также добавляют параметры, проверки и т.д. к вашим *операциям пути*.
**FastAPI** позаботится о добавлении всего этого в схему OpenAPI, чтобы это отображалось в системах интерактивной документации.