Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
main.py642 linesDownload Raw Back to uvicorn
1from __future__ import annotations2 3import asyncio4import logging5import os6import platform7import ssl8import sys9import warnings10from collections.abc import Callable11from configparser import RawConfigParser12from typing import IO, Any, get_args13 14import click15 16import uvicorn17from uvicorn._types import ASGIApplication18from uvicorn.config import (19    INTERFACES,20    LIFESPAN,21    LOG_LEVELS,22    LOGGING_CONFIG,23    SSL_PROTOCOL_VERSION,24    Config,25    HTTPProtocolType,26    InterfaceType,27    LifespanType,28    LoopFactoryType,29    WSProtocolType,30)31from uvicorn.server import Server32from uvicorn.supervisors import ChangeReload, Multiprocess33 34LEVEL_CHOICES = click.Choice(list(LOG_LEVELS.keys()))35LIFESPAN_CHOICES = click.Choice(list(LIFESPAN.keys()))36INTERFACE_CHOICES = click.Choice(INTERFACES)37 38 39def _metavar_from_type(_type: Any) -> str:40    return f"[{'|'.join(key for key in get_args(_type) if key != 'none')}]"41 42 43STARTUP_FAILURE = 344 45logger = logging.getLogger("uvicorn.error")46 47 48def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> None:49    if not value or ctx.resilient_parsing:50        return51    click.echo(52        "Running uvicorn {version} with {py_implementation} {py_version} on {system}".format(  # noqa: UP03253            version=uvicorn.__version__,54            py_implementation=platform.python_implementation(),55            py_version=platform.python_version(),56            system=platform.system(),57        )58    )59    ctx.exit()60 61 62@click.command(context_settings={"auto_envvar_prefix": "UVICORN"})63@click.argument("app", envvar="UVICORN_APP")64@click.option(65    "--host",66    type=str,67    default="127.0.0.1",68    help="Bind socket to this host.",69    show_default=True,70)71@click.option(72    "--port",73    type=int,74    default=8000,75    help="Bind socket to this port. If 0, an available port will be picked.",76    show_default=True,77)78@click.option("--uds", type=str, default=None, help="Bind to a UNIX domain socket.")79@click.option("--fd", type=int, default=None, help="Bind to socket from this file descriptor.")80@click.option("--reload", is_flag=True, default=False, help="Enable auto-reload.")81@click.option(82    "--reload-dir",83    "reload_dirs",84    multiple=True,85    help="Set reload directories explicitly, instead of using the current working directory.",86    type=click.Path(exists=True),87)88@click.option(89    "--reload-include",90    "reload_includes",91    multiple=True,92    help="Set glob patterns to include while watching for files. Includes '*.py' "93    "by default; these defaults can be overridden with `--reload-exclude`. "94    "This option has no effect unless watchfiles is installed.",95)96@click.option(97    "--reload-exclude",98    "reload_excludes",99    multiple=True,100    help="Set glob patterns to exclude while watching for files. Includes "101    "'.*, .py[cod], .sw.*, ~*' by default; these defaults can be overridden "102    "with `--reload-include`. This option has no effect unless watchfiles is "103    "installed.",104)105@click.option(106    "--reload-delay",107    type=float,108    default=0.25,109    show_default=True,110    help="Delay between previous and next check if application needs to be. Defaults to 0.25s.",111)112@click.option(113    "--workers",114    default=None,115    type=int,116    help="Number of worker processes. Defaults to the $WEB_CONCURRENCY environment"117    " variable if available, or 1. Not valid with --reload.",118)119@click.option(120    "--loop",121    type=str,122    metavar=_metavar_from_type(LoopFactoryType),123    default="auto",124    help="Event loop factory implementation.",125    show_default=True,126)127@click.option(128    "--http",129    type=str,130    metavar=_metavar_from_type(HTTPProtocolType),131    default="auto",132    help="HTTP protocol implementation.",133    show_default=True,134)135@click.option(136    "--ws",137    type=str,138    metavar=_metavar_from_type(WSProtocolType),139    default="auto",140    help="WebSocket protocol implementation.",141    show_default=True,142)143@click.option(144    "--ws-max-size",145    type=int,146    default=16777216,147    help="WebSocket max size message in bytes",148    show_default=True,149)150@click.option(151    "--ws-max-queue",152    type=int,153    default=32,154    help="The maximum length of the WebSocket message queue.",155    show_default=True,156)157@click.option(158    "--ws-ping-interval",159    type=float,160    default=20.0,161    help="WebSocket ping interval in seconds.",162    show_default=True,163)164@click.option(165    "--ws-ping-timeout",166    type=float,167    default=20.0,168    help="WebSocket ping timeout in seconds.",169    show_default=True,170)171@click.option(172    "--ws-per-message-deflate",173    type=bool,174    default=True,175    help="WebSocket per-message-deflate compression",176    show_default=True,177)178@click.option(179    "--lifespan",180    type=LIFESPAN_CHOICES,181    default="auto",182    help="Lifespan implementation.",183    show_default=True,184)185@click.option(186    "--interface",187    type=INTERFACE_CHOICES,188    default="auto",189    help="Select ASGI3, ASGI2, or WSGI as the application interface.",190    show_default=True,191)192@click.option(193    "--env-file",194    type=click.Path(exists=True),195    default=None,196    help="Environment configuration file.",197    show_default=True,198)199@click.option(200    "--log-config",201    type=click.Path(exists=True),202    default=None,203    help="Logging configuration file. Supported formats: .ini, .json, .yaml.",204    show_default=True,205)206@click.option(207    "--log-level",208    type=LEVEL_CHOICES,209    default=None,210    help="Log level. [default: info]",211    show_default=True,212)213@click.option(214    "--access-log/--no-access-log",215    is_flag=True,216    default=True,217    help="Enable/Disable access log.",218)219@click.option(220    "--use-colors/--no-use-colors",221    is_flag=True,222    default=None,223    help="Enable/Disable colorized logging.",224)225@click.option(226    "--proxy-headers/--no-proxy-headers",227    is_flag=True,228    default=True,229    help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For to populate url scheme and remote address info.",230)231@click.option(232    "--server-header/--no-server-header",233    is_flag=True,234    default=True,235    help="Enable/Disable default Server header.",236)237@click.option(238    "--date-header/--no-date-header",239    is_flag=True,240    default=True,241    help="Enable/Disable default Date header.",242)243@click.option(244    "--forwarded-allow-ips",245    type=str,246    default=None,247    help="Comma separated list of IP Addresses, IP Networks, or literals "248    "(e.g. UNIX Socket path) to trust with proxy headers. Defaults to the "249    "$FORWARDED_ALLOW_IPS environment variable if available, or '127.0.0.1'. "250    "The literal '*' means trust everything.",251)252@click.option(253    "--root-path",254    type=str,255    default="",256    help="Set the ASGI 'root_path' for applications submounted below a given URL path.",257)258@click.option(259    "--limit-concurrency",260    type=int,261    default=None,262    help="Maximum number of concurrent connections or tasks to allow, before issuing HTTP 503 responses.",263)264@click.option(265    "--backlog",266    type=int,267    default=2048,268    help="Maximum number of connections to hold in backlog",269)270@click.option(271    "--limit-max-requests",272    type=int,273    default=None,274    help="Maximum number of requests to service before terminating the process.",275)276@click.option(277    "--limit-max-requests-jitter",278    type=int,279    default=0,280    help="Maximum jitter to add to limit_max_requests."281    " Staggers worker restarts to avoid all workers restarting simultaneously.",282    show_default=True,283)284@click.option(285    "--timeout-keep-alive",286    type=int,287    default=5,288    help="Close Keep-Alive connections if no new data is received within this timeout (in seconds).",289    show_default=True,290)291@click.option(292    "--timeout-graceful-shutdown",293    type=int,294    default=None,295    help="Maximum number of seconds to wait for graceful shutdown.",296)297@click.option(298    "--timeout-worker-healthcheck",299    type=int,300    default=5,301    help="Maximum number of seconds to wait for a worker to respond to a healthcheck.",302    show_default=True,303)304@click.option("--ssl-keyfile", type=str, default=None, help="SSL key file", show_default=True)305@click.option(306    "--ssl-certfile",307    type=str,308    default=None,309    help="SSL certificate file",310    show_default=True,311)312@click.option(313    "--ssl-keyfile-password",314    type=str,315    default=None,316    help="SSL keyfile password",317    show_default=True,318)319@click.option(320    "--ssl-version",321    type=int,322    default=int(SSL_PROTOCOL_VERSION),323    help="SSL version to use (see stdlib ssl module's)",324    show_default=True,325)326@click.option(327    "--ssl-cert-reqs",328    type=int,329    default=int(ssl.CERT_NONE),330    help="Whether client certificate is required (see stdlib ssl module's)",331    show_default=True,332)333@click.option(334    "--ssl-ca-certs",335    type=str,336    default=None,337    help="CA certificates file",338    show_default=True,339)340@click.option(341    "--ssl-ciphers",342    type=str,343    default="TLSv1",344    help="Ciphers to use (see stdlib ssl module's)",345    show_default=True,346)347@click.option(348    "--header",349    "headers",350    multiple=True,351    help="Specify custom default HTTP response headers as a Name:Value pair",352)353@click.option(354    "--version",355    is_flag=True,356    callback=print_version,357    expose_value=False,358    is_eager=True,359    help="Display the uvicorn version and exit.",360)361@click.option(362    "--app-dir",363    default="",364    show_default=True,365    help="Look for APP in the specified directory, by adding this to the PYTHONPATH."366    " Defaults to the current working directory.",367)368@click.option(369    "--h11-max-incomplete-event-size",370    "h11_max_incomplete_event_size",371    type=int,372    default=None,373    help="For h11, the maximum number of bytes to buffer of an incomplete event.",374)375@click.option(376    "--reset-contextvars",377    is_flag=True,378    default=False,379    help="Run each ASGI request in a fresh contextvars.Context. Hides context set in the lifespan.",380    show_default=True,381)382@click.option(383    "--factory",384    is_flag=True,385    default=False,386    help="Treat APP as an application factory, i.e. a () -> <ASGI app> callable.",387    show_default=True,388)389def main(390    app: str,391    host: str,392    port: int,393    uds: str,394    fd: int,395    loop: LoopFactoryType | str,396    http: HTTPProtocolType | str,397    ws: WSProtocolType | str,398    ws_max_size: int,399    ws_max_queue: int,400    ws_ping_interval: float,401    ws_ping_timeout: float,402    ws_per_message_deflate: bool,403    lifespan: LifespanType,404    interface: InterfaceType,405    reload: bool,406    reload_dirs: list[str],407    reload_includes: list[str],408    reload_excludes: list[str],409    reload_delay: float,410    workers: int,411    env_file: str,412    log_config: str,413    log_level: str,414    access_log: bool,415    proxy_headers: bool,416    server_header: bool,417    date_header: bool,418    forwarded_allow_ips: str,419    root_path: str,420    limit_concurrency: int,421    backlog: int,422    limit_max_requests: int,423    limit_max_requests_jitter: int,424    timeout_keep_alive: int,425    timeout_graceful_shutdown: int | None,426    timeout_worker_healthcheck: int,427    ssl_keyfile: str,428    ssl_certfile: str,429    ssl_keyfile_password: str,430    ssl_version: int,431    ssl_cert_reqs: int,432    ssl_ca_certs: str,433    ssl_ciphers: str,434    headers: list[str],435    use_colors: bool,436    app_dir: str,437    h11_max_incomplete_event_size: int | None,438    reset_contextvars: bool,439    factory: bool,440) -> None:441    run(442        app,443        host=host,444        port=port,445        uds=uds,446        fd=fd,447        loop=loop,448        http=http,449        ws=ws,450        ws_max_size=ws_max_size,451        ws_max_queue=ws_max_queue,452        ws_ping_interval=ws_ping_interval,453        ws_ping_timeout=ws_ping_timeout,454        ws_per_message_deflate=ws_per_message_deflate,455        lifespan=lifespan,456        env_file=env_file,457        log_config=LOGGING_CONFIG if log_config is None else log_config,458        log_level=log_level,459        access_log=access_log,460        interface=interface,461        reload=reload,462        reload_dirs=reload_dirs or None,463        reload_includes=reload_includes or None,464        reload_excludes=reload_excludes or None,465        reload_delay=reload_delay,466        workers=workers,467        proxy_headers=proxy_headers,468        server_header=server_header,469        date_header=date_header,470        forwarded_allow_ips=forwarded_allow_ips,471        root_path=root_path,472        limit_concurrency=limit_concurrency,473        backlog=backlog,474        limit_max_requests=limit_max_requests,475        limit_max_requests_jitter=limit_max_requests_jitter,476        timeout_keep_alive=timeout_keep_alive,477        timeout_graceful_shutdown=timeout_graceful_shutdown,478        timeout_worker_healthcheck=timeout_worker_healthcheck,479        ssl_keyfile=ssl_keyfile,480        ssl_certfile=ssl_certfile,481        ssl_keyfile_password=ssl_keyfile_password,482        ssl_version=ssl_version,483        ssl_cert_reqs=ssl_cert_reqs,484        ssl_ca_certs=ssl_ca_certs,485        ssl_ciphers=ssl_ciphers,486        headers=[header.split(":", 1) for header in headers],  # type: ignore[misc]487        use_colors=use_colors,488        factory=factory,489        app_dir=app_dir,490        h11_max_incomplete_event_size=h11_max_incomplete_event_size,491        reset_contextvars=reset_contextvars,492    )493 494 495def run(496    app: ASGIApplication | Callable[..., Any] | str,497    *,498    host: str = "127.0.0.1",499    port: int = 8000,500    uds: str | None = None,501    fd: int | None = None,502    loop: LoopFactoryType | str = "auto",503    http: type[asyncio.Protocol] | HTTPProtocolType | str = "auto",504    ws: type[asyncio.Protocol] | WSProtocolType | str = "auto",505    ws_max_size: int = 16777216,506    ws_max_queue: int = 32,507    ws_ping_interval: float | None = 20.0,508    ws_ping_timeout: float | None = 20.0,509    ws_per_message_deflate: bool = True,510    lifespan: LifespanType = "auto",511    interface: InterfaceType = "auto",512    reload: bool = False,513    reload_dirs: list[str] | str | None = None,514    reload_includes: list[str] | str | None = None,515    reload_excludes: list[str] | str | None = None,516    reload_delay: float = 0.25,517    workers: int | None = None,518    env_file: str | os.PathLike[str] | None = None,519    log_config: dict[str, Any] | str | os.PathLike[str] | RawConfigParser | IO[Any] | None = LOGGING_CONFIG,520    log_level: str | int | None = None,521    access_log: bool = True,522    proxy_headers: bool = True,523    server_header: bool = True,524    date_header: bool = True,525    forwarded_allow_ips: list[str] | str | None = None,526    root_path: str = "",527    limit_concurrency: int | None = None,528    backlog: int = 2048,529    limit_max_requests: int | None = None,530    limit_max_requests_jitter: int = 0,531    timeout_keep_alive: int = 5,532    timeout_graceful_shutdown: int | None = None,533    timeout_worker_healthcheck: int = 5,534    ssl_keyfile: str | os.PathLike[str] | None = None,535    ssl_certfile: str | os.PathLike[str] | None = None,536    ssl_keyfile_password: str | None = None,537    ssl_version: int = SSL_PROTOCOL_VERSION,538    ssl_cert_reqs: int = ssl.CERT_NONE,539    ssl_ca_certs: str | os.PathLike[str] | None = None,540    ssl_ciphers: str = "TLSv1",541    headers: list[tuple[str, str]] | None = None,542    use_colors: bool | None = None,543    app_dir: str | None = None,544    factory: bool = False,545    h11_max_incomplete_event_size: int | None = None,546    reset_contextvars: bool = False,547) -> None:548    if app_dir is not None:549        sys.path.insert(0, app_dir)550 551    config = Config(552        app,553        host=host,554        port=port,555        uds=uds,556        fd=fd,557        loop=loop,558        http=http,559        ws=ws,560        ws_max_size=ws_max_size,561        ws_max_queue=ws_max_queue,562        ws_ping_interval=ws_ping_interval,563        ws_ping_timeout=ws_ping_timeout,564        ws_per_message_deflate=ws_per_message_deflate,565        lifespan=lifespan,566        interface=interface,567        reload=reload,568        reload_dirs=reload_dirs,569        reload_includes=reload_includes,570        reload_excludes=reload_excludes,571        reload_delay=reload_delay,572        workers=workers,573        env_file=env_file,574        log_config=log_config,575        log_level=log_level,576        access_log=access_log,577        proxy_headers=proxy_headers,578        server_header=server_header,579        date_header=date_header,580        forwarded_allow_ips=forwarded_allow_ips,581        root_path=root_path,582        limit_concurrency=limit_concurrency,583        backlog=backlog,584        limit_max_requests=limit_max_requests,585        limit_max_requests_jitter=limit_max_requests_jitter,586        timeout_keep_alive=timeout_keep_alive,587        timeout_graceful_shutdown=timeout_graceful_shutdown,588        timeout_worker_healthcheck=timeout_worker_healthcheck,589        ssl_keyfile=ssl_keyfile,590        ssl_certfile=ssl_certfile,591        ssl_keyfile_password=ssl_keyfile_password,592        ssl_version=ssl_version,593        ssl_cert_reqs=ssl_cert_reqs,594        ssl_ca_certs=ssl_ca_certs,595        ssl_ciphers=ssl_ciphers,596        headers=headers,597        use_colors=use_colors,598        factory=factory,599        h11_max_incomplete_event_size=h11_max_incomplete_event_size,600        reset_contextvars=reset_contextvars,601    )602    server = Server(config=config)603 604    if (config.reload or config.workers > 1) and not isinstance(app, str):605        logger = logging.getLogger("uvicorn.error")606        logger.warning("You must pass the application as an import string to enable 'reload' or 'workers'.")607        sys.exit(1)608 609    try:610        if config.should_reload:611            sock = config.bind_socket()612            ChangeReload(config, target=server.run, sockets=[sock]).run()613        elif config.workers > 1:614            sock = config.bind_socket()615            Multiprocess(config, target=server.run, sockets=[sock]).run()616        else:617            server.run()618    except KeyboardInterrupt:619        pass  # pragma: full coverage620    finally:621        if config.uds and os.path.exists(config.uds):622            os.remove(config.uds)  # pragma: py-win32623 624    if not server.started and not config.should_reload and config.workers == 1:625        sys.exit(STARTUP_FAILURE)626 627 628def __getattr__(name: str) -> Any:629    if name == "ServerState":630        warnings.warn(631            "uvicorn.main.ServerState is deprecated, use uvicorn.server.ServerState instead.",632            DeprecationWarning,633        )634        from uvicorn.server import ServerState635 636        return ServerState637    raise AttributeError(f"module {__name__} has no attribute {name}")638 639 640if __name__ == "__main__":641    main()  # pragma: no cover642 
codekingpro/portable-devtools · Team Ai