def run_single( app: Type[ASGIFramework], config: Config, *, loop: asyncio.AbstractEventLoop, sock: Optional[socket] = None, is_child: bool = False, ) -> None: """Create a server to run the app on given the options. Arguments: app: The ASGI Framework to run. config: The configuration that defines the server. loop: Asyncio loop to create the server in, if None, take default one. """ if loop is None: warnings.warn( 'Event loop is not specified, this can cause unexpected errors') loop = asyncio.get_event_loop() if config.pid_path is not None and not is_child: _write_pid_file(config.pid_path) loop.set_debug(config.debug) if hasattr(app, 'startup'): loop.run_until_complete(app.startup()) # type: ignore if sock is not None: create_server = loop.create_server( lambda: Server(app, loop, config), ssl=config.ssl, sock=sock, reuse_port=is_child, ) elif config.file_descriptor is not None: sock = socket_fromfd(config.file_descriptor, AF_UNIX, SOCK_STREAM) create_server = loop.create_server( lambda: Server(app, loop, config), ssl=config.ssl, sock=sock, ) elif config.unix_domain is not None: create_server = loop.create_unix_server( lambda: Server(app, loop, config), config.unix_domain, ssl=config.ssl, ) else: create_server = loop.create_server( lambda: Server(app, loop, config), host=config.host, port=config.port, ssl=config.ssl, reuse_port=is_child, ) server = loop.run_until_complete(create_server) if platform.system() == 'Windows': loop.create_task(_windows_signal_support()) try: loop.add_signal_handler(signal.SIGINT, _raise_shutdown) loop.add_signal_handler(signal.SIGTERM, _raise_shutdown) except NotImplementedError: pass # Unix only reload_ = False try: if config.use_reloader: loop.run_until_complete(_observe_changes()) reload_ = True else: loop.run_forever() except (SystemExit, KeyboardInterrupt): pass finally: server.close() loop.run_until_complete(server.wait_closed()) loop.run_until_complete(loop.shutdown_asyncgens()) try: loop.remove_signal_handler(signal.SIGINT) loop.remove_signal_handler(signal.SIGTERM) except NotImplementedError: pass # Unix only if hasattr(app, 'cleanup'): loop.run_until_complete(app.cleanup()) # type: ignore loop.close() if reload_: # Restart this process (only safe for dev/debug) os.execv(sys.executable, [sys.executable] + sys.argv)