FastAPI: Dependencies(13)

FastAPI 提供了简单易用,但功能强大的依赖注入系统,可以让开发人员轻松地把组件集成至 FastAPI

编程中的「依赖注入」是声明代码(本文中为路径操作函数 )运行所需的,或要使用的「依赖」的一种方式。

基本示例

1
2
3
4
5
6
7
8
9
10
def result(start: int = 0, limit: int = 10):
return {'start': start, 'limit': limit}

@app.get('/users/')
def users(res: dict = Depends(result)):
return res

@app.get('/books/')
def books(res: dict = Depends(result)):
return res

这里只能传给 Depends 一个参数。

接收到新的请求时,FastAPI 执行如下操作:

  • 用正确的参数调用依赖项函数(「可依赖项」)
  • 获取函数返回的结果
  • 把函数返回的结果赋值给路径操作函数的参数

Class 依赖注入

也可以用Python Class来实现依赖注入。

1
2
3
4
5
6
7
8
class Result():
def __init__(self, start: int = 0, limit: int = 10):
self.start = start
self.limit = limit

@app.get('/users/')
def users(res: Result = Depends(Result)):
return res

引用时,也可以用下边方式:

res: Result = Depends()

子依赖注入

FastAPI 支持创建含任意深度的子依赖项。类似于函数调用:fun1 -> fun2 -> fun3

1
2
3
4
5
6
7
8
9
10
11
def result1(start: int = 0):
return start

def result2(start: int = Depends(result1), limit: int = 0):
if limit:
return limit
return start

@app.get('/users/')
def users(res: dict = Depends(result2)):
return res

结果

1
http://127.0.0.1:8000/users/?start=2
2

http://127.0.0.1:8000/users/?limit=5
5

多次使用同一个依赖项

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

FastAPI 不会为同一个请求多次调用同一个依赖项,而是把依赖项的返回值进行「缓存」,并把它传递给同一请求中所有需要使用该返回值的「依赖项」。

在高级使用场景中,如果不想使用「缓存」值,而是为需要在同一请求的每一步操作(多次)中都实际调用依赖项,可以把 Depends 的参数 use_cache 的值设置为 False

路径依赖

以在路径操作装饰器中添加一个由 dependencies 组成的 list来注入多个引用。

1
2
3
4
5
6
7
8
9
10
11
def result1(start: int):
if start != 2:
raise HTTPException(status_code=400, detail='start not == 2')

def result2(limit: int):
if limit != 5:
raise HTTPException(status_code=400, detail='limit not == 5')

@app.get('/users/', dependencies=[Depends(result1), Depends(result2)])
def users():
return {'status': 'ok'}

全局依赖

有时,我们要为整个应用添加依赖项。

可以把依赖项添加至整个 FastAPI 应用。后续就可以为所有路径操作应用该依赖项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def result1(start: int):
if start != 2:
raise HTTPException(status_code=400, detail='start not == 2')

def result2(limit: int):
if limit != 5:
raise HTTPException(status_code=400, detail='limit not == 5')

app = FastAPI(dependencies=[Depends(result1), Depends(result2)])

@app.get('/users/')
def users():
return {'status': 'ok'}

@app.get('/books/')
def users():
return {'status': 'ok'}

唐胡璐 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
分享创造价值,您的支持将鼓励我继续前行!