我正在使用FastAPI和uvloop以高效的方式为RESTAPI提供服务
我有很多异步代码可以调用远程资源,如数据库、存储器等,这些函数如下所示:
async def _get_remote_resource(key: str) -> Resource:
# do some async work
return resource
我正在实现一个现有抽象基类的接口,我需要在同步方法中使用上面的异步函数。我做过类似的事情:
class Resource:
def __str__(self):
resource = asyncio.run_until_complete(_get_remote_resource(self.key))
return f"{resource.pk}"
太好了!现在,我在fastapi中创建了一个端点,以使这项工作可访问:
@app.get("")
async def get(key):
return str(Resource(key))
问题是FastAPI已经使用uvloop获取并运行事件循环,然后异步代码失败,因为循环已经在运行
有没有办法从类中的同步方法调用异步方法?还是我必须重新思考代码的结构
运行时错误的设计正是为了阻止您尝试执行的操作
run_until_complete
是一个阻塞调用,在异步def中使用它将停止外部事件循环简单的解决方法是通过实际的异步方法公开所需的功能,例如:
然后在fastapi中,您将以本机方式访问API:
您还可以定义
__str__(self)
来返回self.name()
,但最好避免这样做,因为像str()
这样的基本内容也应该可以从asyncio内部调用(由于在日志记录、调试等中使用)我想补充@user4815162342的答案
FastAPI
是一个不同步的框架。我建议坚持几个原则:asyncio
(def
端点,run_in_executor
与ThreadPoolExecutor
或def
后台任务异步等待该结果)李>ProcessPoolExecutor
或任何任务队列执行run_in_executor
)李>相关问题 更多 >
编程相关推荐