def run( self,host: str='127.0.0.1',port: int=5000,ssl: Optional[SSLContext]=None,debug: Optional[bool]=None, access_log_format: str="%(h)s %(r)s %(s)s %(b)s %(D)s",keep_alive_timeout: int=5,use_reloader: bool=False, loop: Optional[asyncio.AbstractEventLoop]=None,**kwargs: Any, ) -> None: """ Arguments: host: 監聽地址 ssl: 可選的SSL上下文 access_log_format: 日誌格式化 keep_alive_timeout: 超時秒數,在關閉以前保持的不活動鏈接數 use_reloader: 自動從新加載代碼更改 loop: 建立服務器asyncio循環,若是沒有則採用默認的 """ config = HyperConfig() # 是hypercorn(一個基於ASGIweb服務器)的配置 config.access_log_format = access_log_format config.access_logger = create_serving_logger() if debug is not None: config.debug = debug config.error_logger = config.access_logger config.host = host config.keep_alive_timeout = keep_alive_timeout config.port = port config.ssl = ssl config.use_reloader = use_reloader scheme = 'http' if config.ssl is None else 'https' print("Running on {}://{}:{} (CTRL + C to quit)".format(scheme, config.host, config.port)) # noqa: T001, E501 if loop is None: # 若是沒有指定時間循環,建立一個事件循環 loop = asyncio.get_event_loop() try: run_single(self, config, loop=loop) # finally: # 重置第一個請求,以便從新使用 self._got_first_request = False
def run_single( app: Type[ASGIFramework],config: Config,*,loop: asyncio.AbstractEventLoop,sock: Optional[socket]=None,is_child: bool=False, ) -> None: """建立一個服務器,在給定的選項配置的狀況下運行應用程序。 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)