如何在 Jupyter 中运行 FastAPI 应用程序
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
例子.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
我将脚本另存为main.ipynb
在命令行中运行下面这行代码:uvicorn main:app --reload
我收到以下错误:
(venv) PS C:\Users\xxx\Desktop\Python Yamed\SaadAPI> uvicorn main:app --reload INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [21304] using WatchFiles ERROR: Error loadinimport module "main".INFO: Stopping reloader process [21304]
原因是我用的是.ipynb,而不是.py.
如何在使用.ipynb时修复此错误.
非常感谢
推荐答案
如果您try 像往常一样在Jupyter中启动服务器,例如:
import uvicorn
if name == "main": uvicorn.run(app)
您将收到以下错误:
RuntimeError: asyncio.run() cannot be called from a running event loop
这是因为Jupyter已经运行了一个事件循环,一旦Uvicorn在内部调用asyncio.run(),就会引发上述错误.
根据asyncio.run()个文档:
当另一个
asyncio事件循环 在同一线程中运行(请参见引发错误的relevant asyncio implementation).此函数始终创建一个新的事件循环,并在 结束.它应该被用作
asyncio个程序的主要入口点,以及 理想情况下应该只被称为once.
解决方案1
如果您希望从已经运行的async环境中运行uvicorn,请改用uvicorn.Server.serve()(将以下代码添加到您的Jupyter笔记本中的新代码单元格中并执行它):
import asyncio
import uvicorn
if __name__ == "__main__":
config = uvicorn.Config(app)
server = uvicorn.Server(config)
await server.serve()
INFO: Started server process [16632]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [16632]
或者,获取当前事件循环(使用asyncio.get_event_loop()),并调用loop.create_task()在事件循环内为当前线程创建一个任务:
import asyncio
import uvicorn
if __name__ == "__main__":
config = uvicorn.Config(app)
server = uvicorn.Server(config)
loop = asyncio.get_event_loop()
loop.create_task(server.serve())
<Task pending name='Task-8' coro=<Server.serve() running at D:\EMC2\python311\Lib\site-packages\uvicorn\server.py:63>>
INFO: Started server process [16632]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
解决方案2
或者,也可以使用nest_asyncio,这允许嵌套使用asyncio.run()和loop.run_until_complete():
import nest_asyncio
import uvicorn
if __name__ == "__main__":
nest_asyncio.apply()
uvicorn.run(app,
host="127.0.0.1",
port=8001)
INFO: Started server process [16632]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
Exception in callback Task.task_wakeup(<Future finished result=None>)
handle: <Handle Task.task_wakeup(<Future finished result=None>)>
Traceback (most recent call last):
File "D:\EMC2\python311\Lib\asyncio\events.py", line 80, in _run
self._context.run(self._callback, *self._args)
RuntimeError: Cannot enter into task <Task pending name='Task-8' coro=<Server.serve() running at D:\EMC2\python311\Lib\site-packages\uvicorn\server.py:81> wait_for=<Future finished result=None>> while another task <Task pending name='Task-3' coro=<Kernel.dispatch_queue() running at D:\EMC2\python311\Lib\site-packages\ipykernel\kernelbase.py:524> cb=[_wrap_awaitable.<locals>.<lambda>() at D:\EMC2\python311\Lib\site-packages\tornado\gen.py:852, IOLoop.add_future.<locals>.<lambda>() at D:\EMC2\python311\Lib\site-packages\tornado\ioloop.py:699]> is being executed.
INFO: 127.0.0.1:55636 - "GET / HTTP/1.1" 200 OK
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [16632]
INFO: 127.0.0.1:55652 - "GET / HTTP/1.1" 200 OK
jupyter nbconvert --to markdown "Python 如何在 Jupyter 中运行 FastAPI 应用程序.IPYNB"
UPDATE 2024-01-22 BY YULIKE