Issue
I am learning FastAPI and I have this example.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
I saved the script as main.ipynb
The tutorial says to run this line of code in the command line: uvicorn main:app --reload
I am getting this error:
(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]
The reason is because I am using .ipynb
as opposed to .py
.
How can i fix this error while using .ipynb.
Thanks so much
Solution
If you attempted to start the server as usual inside Jupyter, for example:
import uvicorn
if __name__ == "__main__":
uvicorn.run(app)
you would get the following error:
RuntimeError: asyncio.run() cannot be called from a running event loop
This is due to Jupyter already running an event loop, and once Uvicorn calls asyncio.run()
internally, the above error is raised.
As per asyncio.run()
documentation:
This function cannot be called when another
asyncio
event loop is running in the same thread (see relevant asyncio implementation, where the error is raised).[...]
This function always creates a new event loop and closes it at the end. It should be used as a main entry point for
asyncio
programs, and should ideally only be called once.
Solution 1
If you wouldd like to run uvicorn
from an already running async
environment, use uvicorn.Server.serve()
instead (add the below to a new code cell in your Jupyter notebook and execute it):
import asyncio
import uvicorn
if __name__ == "__main__":
config = uvicorn.Config(app)
server = uvicorn.Server(config)
await server.serve()
or, get the current event loop (using asyncio.get_event_loop()
), and call loop.create_task()
to create a task inside the event loop for the current thread:
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())
Solution 2
Alternatively, you can use nest_asyncio
, which allows nested use of asyncio.run()
and loop.run_until_complete()
:
import nest_asyncio
import uvicorn
if __name__ == "__main__":
nest_asyncio.apply()
uvicorn.run(app)
Answered By - Chris
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.