我正在尝试做一些简单的事情--从fastAPI路由内执行jupyter notebook内核中的代码。
这是我所知道:
from fastapi import FastAPI, HTTPException, Body
from jupyter_client import KernelManager
from jupyter_client.blocking.client import BlockingKernelClient
app = FastAPI()
km = KernelManager(kernel_name="python3")
client = km.client()
def execute_code():
msg_id = client.execute("time.sleep(10)")
print(msg_id)
while True:
try:
reply = client.get_shell_msg(timeout=1)
if reply['parent_header']['msg_id'] == msg_id:
if reply['content']['status'] == 'error':
return {"error_type": "failed_to_execute", 'error': '\n'.join(reply['content']['traceback'])}
break
except Empty:
pass
try:
iopub_msg = client.get_iopub_msg(timeout=1)
print(iopub_msg)
break
except Empty:
pass
return {"result": "success"}
@app.post("/execute_cell")
async def execute_cell() -> dict:
try:
execute_code()
except Exception as e:
print(e)
raise HTTPException(status_code=500, detail={"error_type": "failed_to_execute_internal", "error": str(e)})
字符串
这给了我一个错误:
Traceback (most recent call last):
File "/home/vedantroy/miniconda3/lib/python3.10/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
RuntimeError: Cannot enter into task <Task pending name='Task-1' coro=<Server.serve() running at /home/vedantroy/miniconda3/lib/python3.10/site-packages/uvicorn/server.py:81> wait_for=<Future finished result=None> cb=[_run_until_complete_cb() at /home/vedantroy/miniconda3/lib/python3.10/asyncio/base_events.py:184]> while another task <Task pending name='Task-5' coro=<RequestResponseCycle.run_asgi() running at /home/vedantroy/miniconda3/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py:428> cb=[set.discard()]> is being executed.
型
这看起来像是Task-1试图被调度到事件循环中,而另一个任务正在执行。
如何修复此错误?
1条答案
按热度按时间esyap4oy1#
您遇到的错误与尝试在异步上下文中执行阻塞操作有关。您正在使用的execute_code()函数包含了对client.execute()和client.get_shell_msg()的阻塞调用,这与FastAPI的异步特性不兼容。
若要修复此问题,可以使用后台任务异步执行代码。FastAPI为此提供了BackgroundTasks类。
字符串