diff --git a/docs/deployment.md b/docs/deployment.md index 0e8551c14..94a0d130b 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -88,7 +88,7 @@ Options: Enable/Disable default Server header. --date-header / --no-date-header Enable/Disable default Date header. - --forwarded-allow-ips TEXT Comma seperated list of IPs to trust with + --forwarded-allow-ips TEXT Comma separated list of IPs to trust with proxy headers. Defaults to the $FORWARDED_ALLOW_IPS environment variable if available, or '127.0.0.1'. diff --git a/docs/index.md b/docs/index.md index d1ec084f4..472c92ca1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -155,7 +155,7 @@ Options: Enable/Disable default Server header. --date-header / --no-date-header Enable/Disable default Date header. - --forwarded-allow-ips TEXT Comma seperated list of IPs to trust with + --forwarded-allow-ips TEXT Comma separated list of IPs to trust with proxy headers. Defaults to the $FORWARDED_ALLOW_IPS environment variable if available, or '127.0.0.1'. diff --git a/uvicorn/main.py b/uvicorn/main.py index 0db1216c5..bfeeeb584 100644 --- a/uvicorn/main.py +++ b/uvicorn/main.py @@ -19,6 +19,11 @@ SSL_PROTOCOL_VERSION, WS_PROTOCOLS, Config, + HTTPProtocolType, + InterfaceType, + LifespanType, + LoopSetupType, + WSProtocolType, ) from uvicorn.server import Server, ServerState # noqa: F401 # Used to be defined here. from uvicorn.supervisors import ChangeReload, Multiprocess @@ -233,7 +238,7 @@ def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> No "--forwarded-allow-ips", type=str, default=None, - help="Comma seperated list of IPs to trust with proxy headers. Defaults to" + help="Comma separated list of IPs to trust with proxy headers. Defaults to" " the $FORWARDED_ALLOW_IPS environment variable if available, or '127.0.0.1'.", ) @click.option( @@ -347,15 +352,15 @@ def main( port: int, uds: str, fd: int, - loop: str, - http: str, - ws: str, + loop: LoopSetupType, + http: HTTPProtocolType, + ws: WSProtocolType, ws_max_size: int, ws_ping_interval: float, ws_ping_timeout: float, ws_per_message_deflate: bool, - lifespan: str, - interface: str, + lifespan: LifespanType, + interface: InterfaceType, debug: bool, reload: bool, reload_dirs: typing.List[str], @@ -388,61 +393,152 @@ def main( app_dir: str, factory: bool, ) -> None: - kwargs = { - "host": host, - "port": port, - "uds": uds, - "fd": fd, - "loop": loop, - "http": http, - "ws": ws, - "ws_max_size": ws_max_size, - "ws_ping_interval": ws_ping_interval, - "ws_ping_timeout": ws_ping_timeout, - "ws_per_message_deflate": ws_per_message_deflate, - "lifespan": lifespan, - "env_file": env_file, - "log_config": LOGGING_CONFIG if log_config is None else log_config, - "log_level": log_level, - "access_log": access_log, - "interface": interface, - "debug": debug, - "reload": reload, - "reload_dirs": reload_dirs if reload_dirs else None, - "reload_includes": reload_includes if reload_includes else None, - "reload_excludes": reload_excludes if reload_excludes else None, - "reload_delay": reload_delay, - "workers": workers, - "proxy_headers": proxy_headers, - "server_header": server_header, - "date_header": date_header, - "forwarded_allow_ips": forwarded_allow_ips, - "root_path": root_path, - "limit_concurrency": limit_concurrency, - "backlog": backlog, - "limit_max_requests": limit_max_requests, - "timeout_keep_alive": timeout_keep_alive, - "ssl_keyfile": ssl_keyfile, - "ssl_certfile": ssl_certfile, - "ssl_keyfile_password": ssl_keyfile_password, - "ssl_version": ssl_version, - "ssl_cert_reqs": ssl_cert_reqs, - "ssl_ca_certs": ssl_ca_certs, - "ssl_ciphers": ssl_ciphers, - "headers": [header.split(":", 1) for header in headers], - "use_colors": use_colors, - "factory": factory, - "app_dir": app_dir, - } - run(app, **kwargs) + run( + app, + host=host, + port=port, + uds=uds, + fd=fd, + loop=loop, + http=http, + ws=ws, + ws_max_size=ws_max_size, + ws_ping_interval=ws_ping_interval, + ws_ping_timeout=ws_ping_timeout, + ws_per_message_deflate=ws_per_message_deflate, + lifespan=lifespan, + env_file=env_file, + log_config=LOGGING_CONFIG if log_config is None else log_config, + log_level=log_level, + access_log=access_log, + interface=interface, + debug=debug, + reload=reload, + reload_dirs=reload_dirs if reload_dirs else None, + reload_includes=reload_includes if reload_includes else None, + reload_excludes=reload_excludes if reload_excludes else None, + reload_delay=reload_delay, + workers=workers, + proxy_headers=proxy_headers, + server_header=server_header, + date_header=date_header, + forwarded_allow_ips=forwarded_allow_ips, + root_path=root_path, + limit_concurrency=limit_concurrency, + backlog=backlog, + limit_max_requests=limit_max_requests, + timeout_keep_alive=timeout_keep_alive, + ssl_keyfile=ssl_keyfile, + ssl_certfile=ssl_certfile, + ssl_keyfile_password=ssl_keyfile_password, + ssl_version=ssl_version, + ssl_cert_reqs=ssl_cert_reqs, + ssl_ca_certs=ssl_ca_certs, + ssl_ciphers=ssl_ciphers, + headers=[header.split(":", 1) for header in headers], # type: ignore[misc] + use_colors=use_colors, + factory=factory, + app_dir=app_dir, + ) -def run(app: typing.Union[ASGIApplication, str], **kwargs: typing.Any) -> None: - app_dir = kwargs.pop("app_dir", None) +def run( + app: typing.Union[ASGIApplication, str], + *, + host: str = "127.0.0.1", + port: int = 8000, + uds: typing.Optional[str] = None, + fd: typing.Optional[int] = None, + loop: LoopSetupType = "auto", + http: HTTPProtocolType = "auto", + ws: WSProtocolType = "auto", + ws_max_size: int = 16777216, + ws_ping_interval: float = 20.0, + ws_ping_timeout: float = 20.0, + ws_per_message_deflate: bool = True, + lifespan: LifespanType = "auto", + interface: InterfaceType = "auto", + debug: bool = False, + reload: bool = False, + reload_dirs: typing.Optional[typing.List[str]] = None, + reload_includes: typing.Optional[typing.List[str]] = None, + reload_excludes: typing.Optional[typing.List[str]] = None, + reload_delay: float = 0.25, + workers: typing.Optional[int] = None, + env_file: typing.Optional[str] = None, + log_config: typing.Optional[typing.Union[dict, str]] = None, + log_level: typing.Optional[str] = None, + access_log: bool = True, + proxy_headers: bool = True, + server_header: bool = True, + date_header: bool = True, + forwarded_allow_ips: typing.Optional[str] = None, + root_path: str = "", + limit_concurrency: typing.Optional[int] = None, + backlog: int = 2048, + limit_max_requests: typing.Optional[int] = None, + timeout_keep_alive: int = 5, + ssl_keyfile: typing.Optional[str] = None, + ssl_certfile: typing.Optional[str] = None, + ssl_keyfile_password: typing.Optional[str] = None, + ssl_version: int = int(SSL_PROTOCOL_VERSION), + ssl_cert_reqs: int = int(ssl.CERT_NONE), + ssl_ca_certs: typing.Optional[str] = None, + ssl_ciphers: str = "TLSv1", + headers: typing.Optional[typing.List[typing.Tuple[str, str]]] = None, + use_colors: typing.Optional[bool] = None, + app_dir: typing.Optional[str] = None, + factory: bool = False, +) -> None: if app_dir is not None: sys.path.insert(0, app_dir) - config = Config(app, **kwargs) + config = Config( + app, + host=host, + port=port, + uds=uds, + fd=fd, + loop=loop, + http=http, + ws=ws, + ws_max_size=ws_max_size, + ws_ping_interval=ws_ping_interval, + ws_ping_timeout=ws_ping_timeout, + ws_per_message_deflate=ws_per_message_deflate, + lifespan=lifespan, + interface=interface, + debug=debug, + reload=reload, + reload_dirs=reload_dirs, + reload_includes=reload_includes, + reload_excludes=reload_excludes, + reload_delay=reload_delay, + workers=workers, + env_file=env_file, + log_config=log_config, + log_level=log_level, + access_log=access_log, + proxy_headers=proxy_headers, + server_header=server_header, + date_header=date_header, + forwarded_allow_ips=forwarded_allow_ips, + root_path=root_path, + limit_concurrency=limit_concurrency, + backlog=backlog, + limit_max_requests=limit_max_requests, + timeout_keep_alive=timeout_keep_alive, + ssl_keyfile=ssl_keyfile, + ssl_certfile=ssl_certfile, + ssl_keyfile_password=ssl_keyfile_password, + ssl_version=ssl_version, + ssl_cert_reqs=ssl_cert_reqs, + ssl_ca_certs=ssl_ca_certs, + ssl_ciphers=ssl_ciphers, + headers=headers, + use_colors=use_colors, + factory=factory, + ) server = Server(config=config) if (config.reload or config.workers > 1) and not isinstance(app, str):