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()
posted @ 2024-02-28 18:07  我在路上回头看  阅读(142)  评论(0编辑  收藏  举报