基本概念
在 FastAPI 中,依赖可以是:
- 一个函数,它的返回值会被传递给视图函数作为参数。
- 可以被其他依赖函数调用,形成依赖链。
基本用法
from fastapi import Depends, FastAPI
app = FastAPI()
def common_parameters(q: str = None, skip: int = 0, limit: int = 10):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
def read_items(commons: dict = Depends(common_parameters)):
return commons
在这个例子中,common_parameters
函数返回了一个包含常见查询参数的字典,Depends
将这个字典注入到 read_items
函数的 commons
参数中。
复杂场景中的 Depends
数据库会话管理
from sqlalchemy.orm import Session
from fastapi import Depends, FastAPI
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/users/")
def read_users(db: Session = Depends(get_db)):
return db.query(User).all()
在这个例子中,get_db
是一个依赖函数,它返回一个数据库会话对象。通过使用 Depends(get_db)
,read_users
函数在每次请求时会自动获取并使用数据库会话。
处理请求用户
from fastapi import Depends, FastAPI, HTTPException, status
app = FastAPI()
def get_current_user(token: str = Depends(oauth2_scheme)):
user = verify_token(token)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials")
return user
@app.get("/users/me")
def read_users_me(current_user: User = Depends(get_current_user)):
return current_user
在这个例子中,get_current_user
是一个依赖函数,它负责从请求中提取和验证用户的身份。read_users_me
函数通过 Depends(get_current_user)
自动获取当前的用户对象。
嵌套依赖
def get_current_user(token: str = Depends(oauth2_scheme)):
# 验证token并返回用户
return User
def get_active_user(current_user: User = Depends(get_current_user)):
if not current_user.is_active:
raise HTTPException(status_code=400, detail="Inactive user")
return current_user
@app.get("/users/me")
def read_users_me(active_user: User = Depends(get_active_user)):
return active_user
在这个例子中,get_active_user
依赖于 get_current_user
,而 read_users_me
又依赖于 get_active_user
。通过这种方式,FastAPI 会自动解析并注入这些依赖。
全局依赖
app = FastAPI(dependencies=[Depends(verify_token)])
每个请求都会执行 verify_token
函数。
作用域与生命周期
依赖函数的生命周期与请求生命周期相关。比如,依赖函数
get_db
中使用yield
可以管理数据库会话的创建和销毁,FastAPI 会在请求结束后自动执行finally
中的逻辑。
可选依赖
在某些情况下,你可能不希望 FastAPI 缓存依赖的结果,这样每次调用时都会创建一个新的实例。你可以通过将Depends
的 use_cache
参数设置为 False
来实现这一点。
from fastapi import Depends, FastAPI
app = FastAPI()
def get_counter():
# 每次调用时都会返回一个新的值
counter = {"count": 0}
counter["count"] += 1
return counter
@app.get("/counter/")
def read_counter(counter: dict = Depends(get_counter, use_cache=False)):
return counter
在这个示例中,get_counter
函数每次调用都会返回一个新的计数器对象,因为我们将 use_cache
设置为 False
。如果 use_cache
为 True
(默认值),那么在同一请求生命周期内,依赖的结果会被缓存,不会重新调用 get_counter
函数。
类依赖
类依赖允许将依赖逻辑封装到类中,从而更好地管理依赖的状态。你可以定义一个类,并在类的__call__
方法中实现依赖逻辑。
from fastapi import Depends, FastAPI
app = FastAPI()
class CommonQueryParams:
def __init__(self, q: str = None, skip: int = 0, limit: int = 10):
self.q = q
self.skip = skip
self.limit = limit
def __call__(self):
return {"q": self.q, "skip": self.skip, "limit": self.limit}
@app.get("/items/")
def read_items(commons: dict = Depends(CommonQueryParams())):
return commons
在这个示例中,CommonQueryParams
是一个类,封装了常见的查询参数。通过实例化 CommonQueryParams
并将其实例传递给 Depends
,可以在请求处理函数中轻松地获取这些参数。
总结
在 FastAPI 中,Depends
是一个用于依赖注入的强大工具,它简化了参数传递并增强了代码的可读性和可维护性。依赖可以是一个函数,函数的返回值会被自动注入到视图函数的参数中,这使得参数的使用更加简洁,并且支持形成依赖链,即一个依赖函数可以调用其他依赖函数。Depends
的基本用法是在视图函数中通过 Depends
将依赖函数的返回值作为参数注入,这种方式不仅简化了代码,还允许代码的模块化和重用。
在更复杂的场景中,Depends
可以用于管理数据库会话的生命周期,通过 yield
可以确保在每个请求中正确打开和关闭数据库会话。此外,Depends
还可以用于处理请求用户的身份验证,通过依赖注入,可以在每个请求中自动验证用户身份并进行权限检查。FastAPI 还支持嵌套依赖,这意味着一个依赖可以依赖于另一个依赖,形成复杂的依赖关系,这种灵活性使得处理复杂的业务逻辑变得更加容易。
Depends
还支持全局依赖设置,这允许开发者将某些依赖函数应用到所有的请求中,确保每次请求都会执行特定的逻辑。在处理依赖的生命周期时,Depends
与请求的生命周期紧密相关,通过使用 yield
,可以有效管理资源的创建和释放。此外,Depends
还支持可选依赖,通过设置 use_cache=False
,可以在每次请求时生成新的依赖实例,避免依赖结果的缓存。
最后,Depends
还支持类依赖,这允许开发者将依赖逻辑封装在类中,通过类的实例来管理复杂的状态和逻辑。这种方式不仅使代码更加模块化,还提供了对依赖逻辑更好的控制和扩展性。通过这些技巧和方法,开发者可以在 FastAPI 中有效利用 Depends
,提高代码的灵活性和可维护性,尤其在处理复杂业务逻辑时,它是一个不可或缺的工具。