你可以有一个Background Task https://fastapi.tiangolo.com/tutorial/background-tasks/为了这个目的。后台任务“仅在发送响应后运行”(请参阅星光文档 https://www.starlette.io/background/)。 “这对于需要在请求之后发生的操作很有用,但客户端在收到响应之前实际上不必等待操作完成”(请参阅FastAPI文档 https://fastapi.tiangolo.com/tutorial/background-tasks/).
您可以定义一个任务函数在后台运行以写入日志数据,如下所示:
def write_log_data():
logger.write_data()
然后,导入BackgroundTasks
并在端点中定义一个参数,其类型声明为BackgroundTasks
。在端点内部,传递您的任务函数(即write_log_data
,如上所定义)到background_tasks
对象与方法.add_task()
, 如下所示。有关如何使用的更多详细信息BackgroundTasks
可以找到这个答案 https://stackoverflow.com/a/76280152/17865804.
from fastapi import BackgroundTasks
@app.post('/get_data/')
def get_data(input_json: dict, request: Request, background_tasks: BackgroundTasks):
result = crunch_numbers(input_json)
background_tasks.add_task(write_log_data)
return result
如果使用中间件来捕获和记录响应数据,则可以应用相同的原理,如中所述这个答案 https://stackoverflow.com/a/70899261/17865804,或自定义APIRoute
类,如所示这个答案 https://stackoverflow.com/a/73464007/17865804.
供将来参考,如果您(或任何人)需要使用async/await
语法,并遇到并发问题(例如event loop https://docs.python.org/3/library/asyncio-eventloop.html被阻止)在执行一些繁重的后台计算时,请看看这个答案 https://stackoverflow.com/a/71517830/17865804,这解释了定义端点或后台任务函数之间的区别async def
and def
(简要地,async def
端点/后台任务将在event loop
, 然而def
函数将在外部线程池中运行,然后await
ed),并提供了在此类函数中运行阻塞 I/O 密集型或 CPU 密集型操作时的解决方案。