Python FastApi结合异步执行方式
作者:郝少
这篇文章主要介绍了Python FastApi结合异步执行方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
Python FastApi结合异步执行
需求说明
在使用fastApi框架的时候,往往程序会卡到uvicorn.run方法的执行步骤,从而其下面同步执行的动作不能被执行,此时需要使用异步思维进行其他动作的执行;
代码
- Web.py
from fastapi import FastAPI app = FastAPI() @app.get("/info") async def info(): return {"key": "HelloWorld"}
- WebMain.py
import uvicorn from threading import Thread from time import sleep def my_async(f): def wrapper(*args, **kwargs): thr = Thread(target=f, args=args, kwargs=kwargs) thr.start() return wrapper @my_async def print_info(): sleep(5) print("############test") if __name__ == '__main__': # 放在uvicorn.run前面,不然走不到此方法; print_info() uvicorn.run(app='Web:app', host='127.0.0.1', port=8000, reload=True, debug=True)
在FastApi中实现异步问题
在FastAPI应用中使用异步特性可以提高并发性能,但如果您要调用的模型是同步的,可能会导致阻塞。
为了实现异步处理,您可以将阻塞的操作委托给线程池或进程池,以便异步执行。
以下是一种基本方法来实现异步处理图片识别任务:
from fastapi import FastAPI from concurrent.futures import ThreadPoolExecutor import asyncio app = FastAPI() executor = ThreadPoolExecutor(max_workers=10) # 创建线程池,可以根据需求调整线程数 # 模拟一个阻塞的图片识别函数 def blocking_image_recognition(image_data): # 模拟耗时操作,实际中会调用模型进行识别 asyncio.sleep(5) return f"Recognized: {image_data}" @app.post("/recognize-image") async def recognize_image(image_data: str): # 使用线程池异步执行阻塞操作 loop = asyncio.get_event_loop() result = await loop.run_in_executor(executor, blocking_image_recognition, image_data) # 此处可以将结果保存到数据库或进行其他操作 # 使用异步方式进行数据库操作 # ... return {"result": result}
在上述示例中,我们使用ThreadPoolExecutor创建了一个线程池,用于异步执行阻塞操作。blocking_image_recognition函数模拟了一个耗时的识别操作,实际中会根据模型来实现。在recognize_image路由中,我们使用loop.run_in_executor将阻塞操作交给线程池来异步执行。
在处理识别结果时,您可以使用异步框架(例如Tortoise-ORM)来保存数据到数据库,确保数据库操作也是非阻塞的。这样,您就可以同时处理多个图片识别任务,提高并发性能。
如果需要更高级的并发控制,您还可以考虑使用异步任务队列(例如Celery)来进一步分布式处理图片识别任务。 Celery允许您在多个远程机器上并行执行任务。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。