@@ -55,8 +55,11 @@ class BackgroundServer:
5555 ... # server is shut down when the block exits
5656 """
5757
58- def __init__ (self , server : uvicorn .Server , * , host : str , port : int ) -> None :
58+ def __init__ (
59+ self , server : uvicorn .Server , thread : threading .Thread , * , host : str , port : int
60+ ) -> None :
5961 self ._server = server
62+ self ._thread = thread
6063 self .host = host
6164 self .port = port
6265
@@ -66,8 +69,9 @@ def url(self) -> str:
6669 return f"http://{ self .host } :{ self .port } "
6770
6871 def shutdown (self ) -> None :
69- """Signal the server to shut down."""
72+ """Signal the server to shut down and wait for it to stop ."""
7073 self ._server .should_exit = True
74+ self ._thread .join ()
7175
7276 def __enter__ (self ) -> Self :
7377 return self
@@ -215,6 +219,11 @@ def _start_server(
215219 server .run ()
216220 return None
217221
222+ # Signal handlers can only be installed on the main thread, so
223+ # disable them when running in a background thread.
224+ # See https://github.com/encode/uvicorn/issues/742
225+ server .install_signal_handlers = lambda : None
226+
218227 thread = threading .Thread (target = server .run , daemon = True )
219228 thread .start ()
220229
@@ -224,7 +233,7 @@ def _start_server(
224233 raise RuntimeError ("Server failed to start within 5 seconds" )
225234 time .sleep (0.01 )
226235
227- return BackgroundServer (server , host = host , port = port )
236+ return BackgroundServer (server , thread , host = host , port = port )
228237
229238
230239def store_app (
0 commit comments