fastapi 路径依赖项Depends / 装饰器依赖dependencies / 全局依赖 / 带 yield 的依赖

简介: fastapi 路径依赖项Depends / 装饰器依赖dependencies / 全局依赖 / 带 yield 的依赖

文章目录


1. 依赖项

2. 类作为依赖

3. 子依赖项

3.1 多次使用同一个依赖项

4. 路径操作装饰器依赖项

5. 全局依赖项

6. 带 yield 的依赖项

7. 使用带 yield 上下文管理器作为依赖项



1. 依赖项


只能传给 Depends 一个参数。且该参数必须是可调用对象,比如函数

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 依赖项
  • image.png


交互式文档里也会显示 依赖的参数2. 类作为依赖只要可调用,就可以作为依赖项 callableFastAPI 调用 类,创建了一个实例,传给参数 commons

from 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

image.png


3. 子依赖项


  • 可以按需声明任意深度的子依赖项嵌套层级
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}

image.png


3.1 多次使用同一个依赖项


在同一个路径操作 多次声明了同一个依赖项,例如,多个依赖项共用一个子依赖项,FastAPI 在处理同一请求时,只调用一次该子依赖项,使用了缓存

如果不想使用「缓存」值,而是为需要在同一请求的每一步操作(多次)中都实际调用依赖项,可以把 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}

image.png


4. 路径操作装饰器依赖项


有时候,不需要依赖项的返回值,或者 有的依赖项 不返回值,但仍要指向或解析该依赖项

可以在路径操作装饰器中添加一个由 可选参数 dependencies 组成的 Depends() 的 list

就算这些依赖项会返回值,它们的值也不会传递给路径操作函数

可以触发异常

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"}]

image.png


5. 全局依赖项

  • 整个应用 添加依赖项,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"}]

image.png


6. 带 yield 的依赖项


  • 在依赖项结束的时候,做一些操作
  • 如果需要,请在 yield 之前 raise 异常
async def get_db():
    db = DBSession()
    try:
        yield db
    finally:
        db.close()


7. 使用带 yield 上下文管理器作为依赖项


可以自己实现一个类,带 __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

注意:

  • 使用 @contextlib.contextmanager or @contextlib.asynccontextmanager 装饰 带一个yield 的函数,也可以创建上下文管理
  • 但是你不能写 @xxx, FastAPI 内置默认会去处理。
相关文章
|
7月前
|
Python
Fastapi进阶用法,路径参数,路由分发,查询参数等详解
Fastapi进阶用法,路径参数,路由分发,查询参数等详解
423 1
|
Python
FastAPI(35)- 依赖项中使用 yield + Context Manager 上下文管理器
FastAPI(35)- 依赖项中使用 yield + Context Manager 上下文管理器
342 0
|
网络安全 Windows
基于fastapi实现6个接口(token拦截, 2个业务流程,接口参数依赖校验)已经通过postman测试,记录部署服务器和windows,用于pytest接口自动化框架的接口测试对象
基于fastapi实现6个接口(token拦截, 2个业务流程,接口参数依赖校验)已经通过postman测试,记录部署服务器和windows,用于pytest接口自动化框架的接口测试对象
|
关系型数据库 MySQL 数据库连接
FastAPI(34)- Dependencies with yield 依赖项中使用 yield
FastAPI(34)- Dependencies with yield 依赖项中使用 yield
250 0
FastAPI(34)- Dependencies with yield 依赖项中使用 yield
FastAPI(33)- Global Dependencies 全局依赖
FastAPI(33)- Global Dependencies 全局依赖
357 0
FastAPI(33)- Global Dependencies 全局依赖
FastAPI(32)- Dependencies in path operation 通过路径操作装饰器的 dependencies 参数声明依赖
FastAPI(32)- Dependencies in path operation 通过路径操作装饰器的 dependencies 参数声明依赖
171 0
FastAPI(32)- Dependencies in path operation 通过路径操作装饰器的 dependencies 参数声明依赖
|
NoSQL 测试技术 Redis
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
|
存储 测试技术 数据安全/隐私保护
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试