4.1 Внедрение функций и классов зависимости
5 из 5 шагов пройдено
1 из 1 баллa  получен

Зависимости на основе функций

Внедрение зависимостей — это шаблон, в котором объект — в данном случае функция — получает переменную экземпляра, необходимую для дальнейшего выполнения функции. Созданная зависимость дает нам доступ к ее базовым значениям или методам, избавляя от необходимости создавать эти объекты в наследующих их функциях.

В FastAPI зависимость может быть определена либо как функция, либо как вызываемый класс. В этом шаге мы сосредоточимся на функциях, с которыми вы, вероятно, будете работать большую часть времени. Как мы уже говорили, зависимость - это способ обернуть некоторую логику, которая извлекает некоторые подзначения или подобъекты, делает что-то с ними и, наконец, возвращает значение, которое будет введено в конечную точку, вызывающую его.

Давайте познакомимся с классом Depends в FastAPI, с помощью которого мы будем добавлять зависимости в наши проекты. Для этого в файле main.py изменим код на следующий: 

from fastapi import FastAPI, Depends

app = FastAPI()


async def pagination_func(limit: int = 10, page: int = 1):
    return [{'limit': limit, 'page': page}]


@app.get("/messages")
async def all_messages(pagination: dict = Depends(pagination_func)):
    return {"messages": pagination}


@app.get("/comments")
async def all_comments(pagination: dict = Depends(pagination_func)):
    return {"comments": pagination}

Функция маршрутов здесь зависит от функции pagination_func, которая служит ее зависимостью. Это означает, что для доступа к маршруту должна быть удовлетворена зависимость pagination_func. В которой мы должны получить следующие параметры из запроса: limit и page.

Класс Depends, который импортируется из библиотеки FastAPI, отвечает за прием функции, переданной в качестве аргумента, и выполнение ее при вызове конечной точки, автоматически делая доступными для конечной точки, они возвращают значение переданной ей функции. Запустим сервер и проверим работу:

Как мы видим, при GET запросах мы должны передать параметры, которые были получены из зависимости.

Конечно, мы можем делать более сложные вещи в этих зависимостях, как и в обычной функции операции по пути. В следующем примере мы добавляем валидацию для параметра limit:

from fastapi import FastAPI, Depends, Query


async def pagination_func(limit: int = Query(10, ge=0), page: int = 1):
    return [{'limit': limit, 'page': page}]

Код в наших функциях работы пути не должен меняться: у нас есть четкое разделение проблем между логикой конечной точки и более общей логикой для параметров разбивки на страницы. Давайте посмотрим на другое типичное использование зависимостей: получим объект или вызовем ошибку 404.

from fastapi import FastAPI, Depends, Query, HTTPException
from pydantic import BaseModel
from starlette import status

app = FastAPI()


class Post(BaseModel):
    id: int
    text: str


db = []


async def get_post_or_404(id: int):
    try:
        return db[id]
    except IndexError:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)


@app.get("/message/{id}")
async def get_message(post: Post = Depends(get_post_or_404)):
    return post


@app.post("/message", status_code=status.HTTP_201_CREATED)
def create_message(post: Post) -> str:
    post.id = len(db)
    db.append(post)
    return f"Message created!"

Как вы можете видеть, у метода get_message, нам просто нужно определить аргумент post и использовать Depends с функцией get_post_or_404. В результате, в рамках нашей логики, мы гарантированно имеем под рукой наш Post-объект, и мы можем сосредоточиться на основной логике конечной точки.

По аналогии мы можем использовать зависимости и для других конечных точек нашего проекта:

@app.put("/message/{id}")
async def update_message(post: Post = Depends(get_post_or_404)):
    pass


@app.delete("/message/{id}")
async def delete_message(post: Post = Depends(get_post_or_404)):
    pass

Я думаю мы наглядно разобрали преимущества использования зависимостей, в следующем шаге мы научимся использовать зависимости на основе классов.


Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Нет обсуждений. Начните первое.