532 字
3 分钟
依赖注入
什么是依赖注入
依赖注入是申明代码运行所需的,或要使用的依赖的一种方式,让后有系统负责执行任意需要的逻辑,为代码提供这些依赖,常用与
- 共享业务逻辑
- 共享链接
- 实现安全/角色权限/验证 可以让代码重复最小化
from typing import Union
from fastapi import Depends, FastAPI
app = FastAPI()
async def common_parameters(
q: Union[str, None] = None, skip: int = 0, limit: int = 100
):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return commons
本例中的依赖项预期接收如下参数:
- 类型为
str
的可选查询参数q
- 类型为
int
的可选查询参数skip
,默认值是0
- 类型为
int
的可选查询参数limit
,默认值是100
然后,依赖项函数返回包含这些值的 dict
。
类作为依赖项
fastapi 的依赖项只要是可调用对象就都可以
from fastapi import Depends, FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
response = {}
if commons.q:
response.update({"q": commons.q})
items = fake_items_db[commons.skip : commons.skip + commons.limit]
response.update({"items": items})
return response
commons: CommonQueryParams = Depends()
这样可以快捷的写 ()
子依赖项
Fastapi 支持创建包含子依赖的依赖项
from typing import Union
from fastapi import Cookie, Depends, FastAPI
app = FastAPI()
def query_extractor(q: Union[str, None] = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor),
last_query: Union[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}
路径操作依赖项
有时候我们并不需要在路径操作函数中使用依赖项的放回值,但是依然需要解析或执行该依赖项,我们就可以在路径操作装饰器中添加
from fastapi import Depends, FastAPI, Header, HTTPException
app = FastAPI()
async def verify_token(x_token: str = Header()):
if x_token != "fake-super-secret-token":
raise HTTPException(status_code=400, detail="X-Token header invalid")
async def verify_key(x_key: str = Header()):
if x_key != "fake-super-secret-key":
raise HTTPException(status_code=400, detail="X-Key header invalid")
return x_key
@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
async def read_items():
return [{"item": "Foo"}, {"item": "Bar"}]