learn from https://fastapi.tiangolo.com/zh/tutorial/dependencies/
from typing import Optional
from fastapi import FastAPI, Depends
app = FastAPI()
# 依赖项函数,没有@app.xxx
async def common_params(q: Optional[str]=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_params)): # 传入依赖项
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_params)):
return commons
普通的 def
路径操作函数中,可以声明异步的 async def 依赖项
async def
路径操作函数中声明普通的 def 依赖项
交互式文档里也会显示 依赖的参数
callable
FastAPI 调用 类,创建了一个实例,传给参数 commonsfrom typing import Optional
from fastapi import FastAPI, Depends
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
class CommonQueryParams:
def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
# async def read_items(commons: CommonQueryParams = Depends()): # 也可以
# async def read_items(commons = 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
from typing import Optional
from fastapi import FastAPI, Depends, Cookie
app = FastAPI()
def query_extractor(q: Optional[str] = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: Optional[str] = Cookie(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}
两级嵌套
Depends
的参数 use_cache
的值设置为 False
from typing import Optional
from fastapi import FastAPI, Depends, Cookie
app = FastAPI()
def query_extractor(q: Optional[str] = None):
print("run one time!")
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: Optional[str] = Cookie(None)
):
print("run flag!")
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor),
another_query: str = Depends(query_extractor)):
return {"q_or_cookie": query_or_default}
输出:
run one time!
run flag!
更改,不缓存
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor),
another_query: str = Depends(query_extractor, use_cache=False)):
return {"q_or_cookie": query_or_default}
则输出:
run one time!
run flag!
run one time!
路径操作
装饰器中添加一个由 可选参数 dependencies
组成的 Depends() 的 listfrom 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"}]
FastAPI(dependencies=[Depends(xxx), Depends(xx)])
,所有的路径操作都依赖 dependencies
的内容from fastapi import Depends, FastAPI, Header, HTTPException
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 = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])
@app.get("/items/")
async def read_items():
return [{"item": "Portal Gun"}, {"item": "Plumbus"}]
@app.get("/users/")
async def read_users():
return [{"username": "Rick"}, {"username": "Morty"}]
async def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
可以自己实现一个类,带 __enter__() , __exit__()
函数的,可以作为上下文管理器
class MySuperContextManager:
def __init__(self):
self.db = DBSession()
def __enter__(self):
return self.db
def __exit__(self, exc_type, exc_value, traceback):
self.db.close()
async def get_db():
with MySuperContextManager() as db:
yield db
注意: https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager
@contextlib.contextmanager
or @contextlib.asynccontextmanager
装饰 带一个yield
的函数,也可以创建上下文管理