Підзалежності¶
🌐 Переклад ШІ та людьми
Цей переклад виконано ШІ під керівництвом людей. 🤝
Можливі помилки через неправильне розуміння початкового змісту або неприродні формулювання тощо. 🤖
Ви можете покращити цей переклад, допомігши нам краще спрямовувати AI LLM.
Ви можете створювати залежності, які мають підзалежності.
Вони можуть бути настільки глибокими, наскільки потрібно.
FastAPI подбає про їх розв'язання.
Перша залежність «dependable»¶
Можна створити першу залежність («dependable») так:
from typing import Annotated
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: Annotated[str, Depends(query_extractor)],
last_query: Annotated[str | None, Cookie()] = None,
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(
query_or_default: Annotated[str, Depends(query_or_cookie_extractor)],
):
return {"q_or_cookie": query_or_default}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: str | None = Cookie(default=None)
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
return {"q_or_cookie": query_or_default}
Вона оголошує необов'язковий параметр запиту q типу str, а потім просто повертає його.
Це досить просто (не дуже корисно), але допоможе зосередитися на тому, як працюють підзалежності.
Друга залежність, «dependable» і «dependant»¶
Далі ви можете створити іншу функцію залежності («dependable»), яка водночас оголошує власну залежність (тож вона також є «dependant»):
from typing import Annotated
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: Annotated[str, Depends(query_extractor)],
last_query: Annotated[str | None, Cookie()] = None,
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(
query_or_default: Annotated[str, Depends(query_or_cookie_extractor)],
):
return {"q_or_cookie": query_or_default}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: str | None = Cookie(default=None)
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
return {"q_or_cookie": query_or_default}
Зосередьмося на оголошених параметрах:
- Хоча ця функція сама є залежністю («dependable»), вона також оголошує іншу залежність (вона «залежить» від чогось).
- Вона залежить від
query_extractorі присвоює значення, яке він повертає, параметруq.
- Вона залежить від
- Вона також оголошує необов'язкове кукі
last_queryтипуstr.- Якщо користувач не надав параметр запиту
q, ми використовуємо останній запит, який зберегли раніше в кукі.
- Якщо користувач не надав параметр запиту
Використання залежності¶
Потім ми можемо використати залежність так:
from typing import Annotated
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: Annotated[str, Depends(query_extractor)],
last_query: Annotated[str | None, Cookie()] = None,
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(
query_or_default: Annotated[str, Depends(query_or_cookie_extractor)],
):
return {"q_or_cookie": query_or_default}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: str | None = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: str | None = Cookie(default=None)
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
return {"q_or_cookie": query_or_default}
Інформація
Зверніть увагу, що ми оголошуємо лише одну залежність у функції операції шляху — query_or_cookie_extractor.
Але FastAPI знатиме, що спочатку треба розв'язати query_extractor, щоб передати його результат у query_or_cookie_extractor під час виклику.
graph TB
query_extractor(["query_extractor"])
query_or_cookie_extractor(["query_or_cookie_extractor"])
read_query["/items/"]
query_extractor --> query_or_cookie_extractor --> read_query
Використання тієї ж залежності кілька разів¶
Якщо одна з ваших залежностей оголошена кілька разів для однієї операції шляху, наприклад, кілька залежностей мають спільну підзалежність, FastAPI знатиме, що цю підзалежність потрібно викликати лише один раз на запит.
І він збереже повернуте значення у «кеш» і передасть його всім «dependants», яким воно потрібне в цьому конкретному запиті, замість того щоб викликати залежність кілька разів для одного й того ж запиту.
У просунутому сценарії, коли ви знаєте, що залежність має викликатися на кожному кроці (можливо, кілька разів) у межах того самого запиту замість використання «кешованого» значення, ви можете встановити параметр use_cache=False при використанні Depends:
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
return {"fresh_value": fresh_value}
Порада
Надавайте перевагу версії з Annotated, якщо це можливо.
async def needy_dependency(fresh_value: str = Depends(get_value, use_cache=False)):
return {"fresh_value": fresh_value}
Підсумок¶
Попри всі модні терміни, система впровадження залежностей досить проста.
Це просто функції, які виглядають так само, як функції операцій шляху.
Втім вона дуже потужна і дозволяє оголошувати довільно глибоко вкладені «графи» залежностей (дерева).
Порада
Усе це може здаватися не надто корисним на простих прикладах.
Але ви побачите, наскільки це корисно, у розділах про безпеку.
І також побачите, скільки коду це вам заощадить.