Exception raised when hitting Ctrl-C in uvicorn >= 0.29.0 if started programmatically #2368
Replies: 3 comments 8 replies
-
Can you clarify why you consider this an issue? Raising If you want to suppress the exception, you can do so the usual way:
|
Beta Was this translation helpful? Give feedback.
-
See #2383 as a draft for quieter/silent quitting. Feedback is welcome. I'm specifically not sure whether the shorter or silent shutdown should be the default. |
Beta Was this translation helpful? Give feedback.
-
Commenting here, although it's related also to the PRs: When uvicorn is used programmatically, and it's part of a bigger async application, instead of re-raising signals, wouldn't be cleaner and simpler to let the user decide to:
This can be already done by calling the private method In this way, it's still possible to integrate uvicorn into bigger applications without changing the behaviour of Simplified working example: import asyncio
import signal
import uvicorn
from fastapi import FastAPI
HANDLED_SIGNALS = (
signal.SIGINT,
signal.SIGTERM,
)
app = FastAPI(title="test")
class Sleeper:
def __init__(self, sleep: float = 10) -> None:
self.should_exit = False
self.sleep = sleep
async def run_forever(self) -> None:
while not self.should_exit:
print(f"Sleeping for {self.sleep} seconds...")
await asyncio.sleep(self.sleep)
def handle_exit(self, sig, frame):
self.should_exit = True
def _install_signal_handlers(handle_exit) -> None:
loop = asyncio.get_event_loop()
for sig in HANDLED_SIGNALS:
loop.add_signal_handler(sig, handle_exit, sig, None)
async def main() -> None:
def _handle_exit(sig, frame):
server.handle_exit(sig, frame)
sleeper.handle_exit(sig, frame)
sleeper_task.cancel()
server = uvicorn.Server(uvicorn.Config(app))
sleeper = Sleeper()
_install_signal_handlers(_handle_exit)
async with asyncio.TaskGroup() as tg:
tg.create_task(server._serve(), name="uvicorn")
sleeper_task = tg.create_task(sleeper.run_forever(), name="sleeper")
print("DONE")
if __name__ == "__main__":
asyncio.run(main()) |
Beta Was this translation helpful? Give feedback.
-
There is a similar issue #2289, but it's marked as solved so I'm not sure that the problem is the same.
I'm opening the discussion with my example that can be used to reproduce the error.
In a virtualenv on mac with:
I have these files:
app.py:
main.py:
If I start uvicorn with
uvicorn app:app
, and hit ctrl-c, I get what I expect:But if I start uvicorn programmatically with
python -m main
and hit ctrl-c, then an exception is propagated:I verified that the issue wasn't present in uvicorn 0.28.1, and it appeared in 0.29.0, so it's probably caused by #1600
Beta Was this translation helpful? Give feedback.
All reactions