当前位置:
首页 > Python基础教程 >
-
FastAPI依赖注入:参数共享与逻辑复用
第一章:依赖注入核心原理
1.1 依赖树构建机制
PYTHON
from fastapi import Depends
def auth_service():
return OAuth2Scheme()
def db_conn(auth: dict = Depends(auth_service)):
return Database(creds=auth)
@app.get("/data")
async def get_data(conn=Depends(db_conn)):
return conn.query()
依赖树可视化:
graph TD
get_data --> db_conn --> auth_service
1.2 作用域控制
PYTHON
from fastapi import Depends, FastAPI
from sqlalchemy.orm import sessionmaker
SessionLocal = sessionmaker(autocommit=False)
# 请求级作用域
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# 应用级单例
cache = LRUCache(size=100)
def get_cache():
return cache
第二章:Pydantic深度集成
2.1 动态模型注入
PYTHON
from pydantic import create_model
def dynamic_model(fields: dict):
return create_model('DynamicModel', **fields)
class FilterFactory:
@classmethod
def create(cls, model: BaseModel):
class QueryParams(model):
limit: int = 100
offset: int = 0
return QueryParams
@app.get("/search")
async def search(params=Depends(FilterFactory.create(User))):
return params.dict()
2.2 校验逻辑复用
PYTHON
from pydantic import validator, root_validator
class GeoValidator:
@classmethod
def lat_validator(cls, v):
if not -90 <= v <= 90:
raise ValueError("纬度范围错误")
return v
class Location(BaseModel):
lat: float
lng: float
_validate_lat = validator('lat', allow_reuse=True)(GeoValidator.lat_validator)
第三章:高级注入模式
3.1 工厂模式注入
PYTHON
class NotificationClient:
def __init__(self, type: str):
self.client = self._create_client(type)
@staticmethod
def _create_client(type):
return {
"sms": SMSClient(),
"email": EmailClient()
}[type]
def get_notifier(type: str):
def _factory():
return NotificationClient(type)
return _factory
@app.post("/alert")
async def send_alert(
notifier: NotificationClient = Depends(get_notifier("sms"))
):
notifier.client.send()
3.2 条件依赖注入
PYTHON
from fastapi import Header
def feature_flag_dep(feature_name: str):
class FeatureChecker:
def __init__(self,
enabled: bool = Depends(check_feature_enabled)
):
if not enabled:
raise HTTPException(403, "功能未启用")
return FeatureChecker
def check_feature_enabled(
feature: str = Header(...),
config: Config = Depends(get_config)
) -> bool:
return config.is_enabled(feature)
@app.get("/beta")
async def beta_feature(
checker=Depends(feature_flag_dep("beta"))
):
return "功能可用"
第四章:错误处理与调试
4.1 依赖链错误传播
PYTHON
class DatabaseError(Exception):
pass
def db_dep():
try:
yield connection
except Exception as e:
raise DatabaseError() from e
@app.exception_handler(DatabaseError)
async def handle_db_error(request, exc):
return JSONResponse(500, {"detail": "数据库异常"})
4.2 依赖图可视化调试
PYTHON
from fastapi.dependencies.utils import solve_dependencies
def print_dependency_tree():
routes = app.routes
for route in routes:
if isinstance(route, APIRoute):
solved = solve_dependencies(route.dependant)
print(f"Route {route.path}:")
for dep in solved.flat_graph():
print(f"└─ {dep.call.__name__}")
第五章:测试与维护
5.1 依赖覆盖测试
PYTHON
from fastapi.testclient import TestClient
def override_dep():
return MockDatabase()
app.dependency_overrides[get_db] = override_dep
client = TestClient(app)
response = client.get("/data")
assert "mock" in response.text
5.2 依赖版本管理
PYTHON
from packaging.version import parse
class VersionedDep:
def __init__(self, api_version: str = Header(...)):
self.version = parse(api_version)
def check_min_version(self, min_version: str):
if self.version < parse(min_version):
raise HTTPException(400, "版本过低")
@app.get("/new-feature")
async def new_feature(
dep: VersionedDep = Depends(),
checker=Depends(dep.check_min_version("2.3"))
):
return "功能可用"
课后Quiz
Q1:如何实现跨路由共享查询参数?
A) 在每个路由重复定义参数
B) 使用全局变量存储参数
C) 通过依赖注入共享参数
Q2:依赖注入的yield语句有什么作用?
实现请求后清理逻辑
提高依赖执行速度
支持异步生成器
Q3:如何测试被覆盖的依赖项?
使用dependency_overrides
直接修改源代码
配置环境变量
错误解决方案速查表
错误类型 | 解决方案 |
---|---|
422 Validation Error | 检查请求参数是否匹配Pydantic模型定义 |
DIResolutionError | 确认依赖树没有循环引用,所有依赖项已正确定义 |
DependencyInstantiationError | 检查yield依赖是否正确处理异常,验证上下文管理器实现 |
架构箴言:优秀的依赖注入设计应遵循SOLID原则,特别是依赖倒置原则(DIP)。建议使用依赖图分析工具保持注入层次不超过5层,对高频依赖实施缓存策略,并定期进行依赖关系审计。
来源:https://blog.cmdragon.cn/posts/3b96477f5460/
栏目列表
最新更新
求1000阶乘的结果末尾有多少个0
详解MyBatis延迟加载是如何实现的
IDEA 控制台中文乱码4种解决方案
SpringBoot中版本兼容性处理的实现示例
Spring的IOC解决程序耦合的实现
详解Spring多数据源如何切换
Java报错:UnsupportedOperationException in Col
使用Spring Batch实现批处理任务的详细教程
java中怎么将多个音频文件拼接合成一个
SpringBoot整合ES多个精确值查询 terms功能实
SQL Server 中的数据类型隐式转换问题
SQL Server中T-SQL 数据类型转换详解
sqlserver 数据类型转换小实验
SQL Server数据类型转换方法
SQL Server 2017无法连接到服务器的问题解决
SQLServer地址搜索性能优化
Sql Server查询性能优化之不可小觑的书签查
SQL Server数据库的高性能优化经验总结
SQL SERVER性能优化综述(很好的总结,不要错
开启SQLSERVER数据库缓存依赖优化网站性能
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比