-
-
Save tenuki/ff67f87cba5c4c04fd08d9c800437477 to your computer and use it in GitHub Desktop.
## | |
## How to run multiple uvicorn server apps in the same process | |
## | |
import asyncio | |
from uvicorn import Server, Config | |
class MyServer(Server): | |
async def run(self, sockets=None): | |
self.config.setup_event_loop() | |
return await self.serve(sockets=sockets) | |
async def run(): | |
apps = [] | |
for cfg in configList: | |
config = Config("srcs.myapp:app", host="0.0.0.0", | |
port=cfg["port"]) | |
server = MyServer(config=config) | |
apps.append(server.run()) | |
return await asyncio.gather(*apps) | |
if __name__ == '__main__': | |
loop = asyncio.get_event_loop() | |
loop.run_until_complete(run()) |
this cannot by interrupt by keyboard :(
this cannot by interrupt by keyboard :(
I started out with this solution earlier, but also encounter the same issue, which was problematic because I could have an API running in my local dev environment. I ended up using a FastAPI routing approach for multiple modules instead of having a uvicorn
Server.
This is what I did in my main module:
https://github.com/UAL-ODIS/ReDATA_README_Tool/blob/61aed9b92ecfdd983fd1d05d01bb95c5b5532286/main.py#L21-L23
And in each API module, I imported fastapi.APIRouter
https://github.com/UAL-ODIS/ReDATA_README_Tool/blob/61aed9b92ecfdd983fd1d05d01bb95c5b5532286/readme_tool/figshare.py#L4-L6
Hope that helps.
Hi @hideuk @astrochun, I'm planning to implement this solution for running multiple uvicorn
servers. The use-case is we want to have multiple domains in the same project, so routing approach might not work. Can you guide me please what problems you actually faced wrt keyboard interruption?
Hi @hideuk @astrochun, I'm planning to implement this solution for running multiple
uvicorn
servers. The use-case is we want to have multiple domains in the same project, so routing approach might not work. Can you guide me please what problems you actually faced wrt keyboard interruption?
@Prachi1429 It looks to me like this will ignore KeyboardInterrupt exception when you press Ctrl-c while process is running. It would be expected that the exception be generated and that trigger the KeyboardInterrupt exception which should stop the process.
This did it for me, and its interruptible:
import asyncio
import sys
...some fast api app...
async def create_webserver(port):
server_config = uvicorn.Config("uvicorn_asgi:fast_api_app", port=port, log_level="info")
server = uvicorn.Server(server_config)
await server.serve()
async def main():
done, pending = await asyncio.wait(
[
create_webserver(8000),
create_webserver(8001),
],
return_when=asyncio.FIRST_COMPLETED,
)
print("done")
print(done)
print("pending")
print(pending)
for pending_task in pending:
pending_task.cancel("Another service died, server is shutting down")
if __name__ == "__main__":
try:
asyncio.run(main())
except Exception as e:
print(e)
sys.exit(0)
Thanks, this did the trick!