FastAPI系列:依赖注入
函数式依赖项
from fastapi import FastAPI
from fastapi import Query, Depends
from fastapi.exceptions import HTTPException
app = FastAPI()
def username_check(username:str=Query(...)):
if username != 'zhong':
raise HTTPException(status_code=403, detail='没有权限访问')
return username
@app.get('/user/login/')
def user_login(username:str=Depends(username_check)):
return username
@app.get('/user/info')
def user_info(username:str=Depends(username_check)):
return username
类方式依赖项
# depencies.py
class UserInfo:
def __init__(self, id: int, username: str):
self.id = id
self.username = username
# user.py
@router.get('/dep/class')
def user_class(user_account=Depends(UserInfo)): # 类形式 # UserInfo捕获查询参数
logger.info(f"【Depends】{user_account}")
account_dict = jsonable_encoder(user_account)
user_info = User(**account_dict)
return user_info
# 如果可以确定依赖的类型,那么可以简写如下
def user_class(user_account: UserInfo = Depends()):
pass
多个依赖项注入和依赖项传参
from fastapi import FastAPI,Request,Body
from fastapi import Query, Depends
from fastapi.exceptions import HTTPException
app = FastAPI()
class UsernameCheck:
def __init__(self,password:str):
self.password = password
def username_form_query(self,username:str=Query(...)):
if username != 'zhong':
raise HTTPException(status_code=403,detail='没有权限访问')
self.username = username
def username_form_post(self, username:str=Body(...)):
if username != 'zhong':
raise HTTPException(status_code=403,detail='没有权限访问')
self.username = username
upw = UsernameCheck(password='123456')
@app.get('/user/login/')
def user_login(username:UsernameCheck=Depends(upw.username_form_query)):
return username
@app.post('/user/info')
def user_info(username:UsernameCheck=Depends(upw.username_form_post)):
return username
依赖项具有缓存机制
默认情况下,依赖项会自动缓存,如果不需要缓存,需要每次都重新计算的话,则使用use_cache=false
Depends(username_check, use_cache=false)
不同位置上的依赖项
全局依赖项
FastAPI类提供了一个dependencies参数,该参数是实现全局依赖项注入的关键
from fastapi import FastAPI
from fastapi import Query, Depends
from fastapi.exceptions import HTTPException
def username_check(username:str=Query(...)):
if username != 'zhong':
raise HTTPException(status_code=403, detail='用户名错误!没有权限访问')
return username
def age_check(age:int=Query(...)):
if age < 18:
raise HTTPException(status_code=403, detail='用户未满18岁!禁止吸烟')
return age
# 实例化时,将上面两个函数依赖项注入app对象中,这种方式可实现全局依赖项的注入,这种注入方式会作用到所有app的路由上。
app = FastAPI(dependencies=[Depends(username_check),Depends(age_check)])
@app.get('/user/login')
def user_login():
return {
'code': 'ok'
}
@app.get('/user/info/')
def user_info():
return {
'code': 'ok'
}
路径操作依赖项
路径操作依赖项的注入和路径操作函数依赖项的注入方式基本一样,只不过他们注入的位置和依赖项的返回值是否接收处理不一样。
如果依赖项时通过路径操作函数进行依赖注入的,那么依赖项 里面 的返回值是可以被接收处理的,
也就是视图函数内部可以接收对于依赖项的返回值,反之,路径操作的依赖项返回值是不会被处理的。
@app.get('/user/login/',dependencies=[Depends(username_check),Depends(age_check)]) # 如果依赖项有返回值,则不会被接收处理
def user_login():
return {
'code': 'ok'
}
路由分组依赖项
可以通过FastAPI提供的APIRouter类进行路由分组。通过路由分组可以更好的规划项目中的api模块结构,且在特定路由分组上就可以进行依赖项的注入
# 路由分组对象注入依赖项
from fastapi import FastAPI
from fastapi import Query, Depends
from fastapi.exceptions import HTTPException
from fastapi import APIRouter
def username_check(username:str=Query(...)):
if username != 'zhong':
raise HTTPException(status_code=403, detail='用户名错误!没有权限访问')
return username
def age_check(age:int=Query(...)):
if age < 18:
raise HTTPException(status_code=403, detail='用户未满18岁!禁止吸烟')
return age
app = FastAPI()
# 这边可以拆分为user模块
user_group_router = APIRouter(prefix='/user', dependencies=[Depends(username_check)])
@user_group_router.get('/login')
def user_login():
return {
'code': 'ok'
}
# 这边可以拆分为order模块
order_group_router = APIRouter(prefix='/order', dependencies=[Depends(username_check), Depends(age_check)])
@order_group_router.get('/pay')
def order_pay():
return {
'code': 'pay_ok'
}
app.include_router(user_group_router)
app.include_router(order_group_router)
# 也可以在include_router函数中添加依赖项
app = FastAPI()
# 这边可以拆分为user模块
user_group_router = APIRouter(prefix='/user')
@user_group_router.get('/login')
def user_login():
return {
'code': 'ok'
}
order_group_router = APIRouter(prefix='/order')
@order_group_router.get('/pay')
def order_pay():
return {
'code': 'pay_ok'
}
app.include_router(user_group_router, dependencies=[Depends(username_check)])
app.include_router(order_group_router, dependencies=[Depends(username_check), Depends(age_check)])
路径函数依赖项
def username_check(username:str=Query(...)):
if username != 'zhong':
raise HTTPException(status_code=403, detail='没有权限访问')
return username
@app.get('/user/info')
def user_info(username:str=Depends(username_check)): # 依赖项中有返回值,会被接收处理
return username
使用yield的依赖项
可以用于数据库的session会话获取
async def get_db():
db = DBSession()
try:
yield db
finally:
db.close()
-------------------------------------------
个性签名:代码过万,键盘敲烂!!!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!