首页 > 其他分享 >FastAPI系列:依赖注入

FastAPI系列:依赖注入

时间:2024-02-28 18:26:13浏览次数:20  
标签:username 依赖 系列 FastAPI Depends user return check def

函数式依赖项

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()

标签:username,依赖,系列,FastAPI,Depends,user,return,check,def
From: https://www.cnblogs.com/weiweivip666/p/18041348

相关文章

  • FastAPI系列:环境配置读取
    依赖包pipinstallpython-dotenv使用#.env文件ADMIN_EMAIL="[email protected]"APP_NAME="ChimichangApp"#config.pyfrompydantic_settingsimportBaseSettingsclassSettings(BaseSettings):app_name:str="AwesomeAPI"......
  • FastAPI系列:后台任务进程
    注:后台任务应附加到响应中,并且仅在发送响应后运行用于将单个后台任务添加到响应中fromfastapiimportFastAPIfromfastapi.responsesimportJSONResponsefromstarlette.backgroundimportBackgroundTaskfrompydanticimportBaseModelapp=FastAPI()classUser(B......
  • FastAPI系列:中间件
    中间件介绍中间件是一个函数,它在每个请求被特定的路径操作处理之前,以及在每个响应返回之前工作装饰器版中间件1.必须使用装饰器@app.middleware("http"),且middleware_type必须为http2.中间件参数:request,call_next,且call_next它将接收request作为参数@app.middleware("h......
  • FastAPI系列:模型用法
    模型基本用法frompydanticimportBaseModelclassItem(BaseModel):#通过继承BaseModelname:strprice:floatis_offer:Union[bool,None]=None常用的模型属性和方法dict()#将数据模型的字段和值封装成字典json()#将数据模型的字段和值封装成json格......
  • FastAPI系列:上传文件File和UploadFile
    上传文件#file仅适用于小文件@app.post("/files/")asyncdefcreate_file(file:bytes|None=File(default=None)):ifnotfile:return{"message":"Nofilesent"}else:return{"file_size":len(file)}......
  • FastAPI系列:路径参数额外校验Path
    路径参数额外校验PathfromfastapiimportPathapp=FastAPI()@app.get('/items/{item_id}')asyncdefread_items(item_id:str=Path(default=None,max_length=3,min_length=1,title='theidofitemtoget')):"""def......
  • FastAPI系列:查询字符串参数
    单个查询字符串@app.get('/index/{username}')defindex(username:str,id:int):#id为查询字符串?id=5return{"message":"success","username":username,"id":id}可选的查询字符串参数@app.get('/items/{item_id}......
  • FastAPI系列:APIRouter实例的路由注册
    APIRouter实例的路由注册API端点路由注册大致分为3种:1.基于app实例对象提供的装饰器或函数进行注册2.基于FastAPI提供的APIRouter类的实例对象提供的装饰器或函数进行注册3.通过直接实例化APIRoute对象且添加的方式进行注册路由注册方式基于APIRouter的实例对象实现路由注册......
  • FastAPI系列:mount应用挂载
    mount应用挂载1.创建主app应用对象实例,注册所属的路由信息fromfastapiimportFastAPIfromfastapi.responseimportJSONResponseapp=FastAPI(title='主应用',description='主应用描述',version='v1.0.0')@app.get('/index',summary='首页')......
  • FastAPI系列:全局routes参数的使用
    全局routes参数的使用fromfastapiimportFastAPI,Requestfromfastapi.responseimportJSONResponsefromfastapi.routingimportAPIRouteasyncdeffastapi_index():returnJSONResponse({'index':'fastapi_index'})asyncdeffastapi_about()......