# Server Configuration

Comprehensive configuration system for uvicorn server settings. The `Config` class holds all server parameters, protocol selections, and runtime settings, providing properties and methods for configuration loading and validation.

## Imports

```python
from uvicorn import Config
from uvicorn.config import (
    create_ssl_context,
    HTTPProtocolType,
    WSProtocolType,
    LifespanType,
    LoopFactoryType,
    InterfaceType,
)
```

## Capabilities

### Configuration Class

Central configuration object that holds all server settings and provides methods for loading and validation.

```python { .api }
class Config:
    """
    Server configuration for uvicorn.

    Holds all server settings including network binding, protocol selection,
    worker configuration, SSL/TLS, logging, timeouts, and runtime behavior.
    """

    def __init__(
        self,
        app: ASGIApplication | Callable | str,
        host: str = "127.0.0.1",
        port: int = 8000,
        uds: str | None = None,
        fd: int | None = None,
        loop: LoopFactoryType | str = "auto",
        http: HTTPProtocolType | str | type[asyncio.Protocol] = "auto",
        ws: WSProtocolType | str | type[asyncio.Protocol] = "auto",
        ws_max_size: int = 16777216,
        ws_max_queue: int = 32,
        ws_ping_interval: float | None = 20.0,
        ws_ping_timeout: float | None = 20.0,
        ws_per_message_deflate: bool = True,
        lifespan: LifespanType = "auto",
        interface: InterfaceType = "auto",
        reload: bool = False,
        reload_dirs: list[str] | str | None = None,
        reload_includes: list[str] | str | None = None,
        reload_excludes: list[str] | str | None = None,
        reload_delay: float = 0.25,
        workers: int | None = None,
        env_file: str | os.PathLike | None = None,
        log_config: dict | str | configparser.RawConfigParser | typing.IO | None = None,
        log_level: str | int | None = None,
        access_log: bool = True,
        proxy_headers: bool = True,
        server_header: bool = True,
        date_header: bool = True,
        forwarded_allow_ips: list[str] | str | None = None,
        root_path: str = "",
        limit_concurrency: int | None = None,
        backlog: int = 2048,
        limit_max_requests: int | None = None,
        timeout_keep_alive: int = 5,
        timeout_notify: int = 30,
        timeout_graceful_shutdown: int | None = None,
        timeout_worker_healthcheck: int = 5,
        callback_notify: Callable[..., Awaitable[None]] | None = None,
        ssl_keyfile: str | os.PathLike | None = None,
        ssl_certfile: str | os.PathLike | None = None,
        ssl_keyfile_password: str | None = None,
        ssl_version: int = ssl.PROTOCOL_TLS_SERVER,
        ssl_cert_reqs: int = ssl.CERT_NONE,
        ssl_ca_certs: str | os.PathLike | None = None,
        ssl_ciphers: str = "TLSv1",
        headers: list[tuple[str, str]] | None = None,
        use_colors: bool | None = None,
        factory: bool = False,
        h11_max_incomplete_event_size: int | None = None,
    ) -> None:
        """
        Initialize server configuration.

        Args:
            app: ASGI application instance, factory function, or import string (e.g., "myapp:app")
            host: Bind socket to this host address (default: "127.0.0.1")
            port: Bind socket to this port (default: 8000)
            uds: Bind to Unix domain socket at this path (alternative to host/port)
            fd: Use file descriptor for socket (alternative to host/port)
            loop: Event loop implementation ("none", "auto", "asyncio", "uvloop")
            http: HTTP protocol implementation ("auto", "h11", "httptools") or protocol class
            ws: WebSocket protocol implementation ("auto", "none", "websockets", "websockets-sansio", "wsproto") or protocol class
            ws_max_size: Maximum WebSocket message size in bytes (default: 16777216)
            ws_max_queue: Maximum WebSocket message queue length (default: 32)
            ws_ping_interval: WebSocket ping interval in seconds (default: 20.0, None to disable)
            ws_ping_timeout: WebSocket ping timeout in seconds (default: 20.0, None to disable)
            ws_per_message_deflate: Enable WebSocket per-message deflate compression (default: True)
            lifespan: Lifespan event handling mode ("auto", "on", "off")
            interface: Application interface type ("auto", "asgi3", "asgi2", "wsgi")
            reload: Enable auto-reload on file changes (default: False)
            reload_dirs: Directories to watch for changes (defaults to current directory)
            reload_includes: Glob patterns to include for reload watching
            reload_excludes: Glob patterns to exclude from reload watching
            reload_delay: Delay between checking for file changes in seconds (default: 0.25)
            workers: Number of worker processes (None for single process)
            env_file: Path to environment file to load (.env file)
            log_config: Logging configuration as dict, file path (.json, .yaml, .ini), or file object
            log_level: Logging level as string ("critical", "error", "warning", "info", "debug", "trace") or int
            access_log: Enable HTTP access logging (default: True)
            proxy_headers: Enable parsing of X-Forwarded-* proxy headers (default: True)
            server_header: Include Server header in HTTP responses (default: True)
            date_header: Include Date header in HTTP responses (default: True)
            forwarded_allow_ips: Comma-separated string or list of IPs to trust for proxy headers
            root_path: ASGI root_path for applications mounted at a path (default: "")
            limit_concurrency: Maximum number of concurrent connections (None for unlimited)
            backlog: Socket listen backlog size (default: 2048)
            limit_max_requests: Maximum requests before worker restart (None for unlimited)
            timeout_keep_alive: HTTP keep-alive connection timeout in seconds (default: 5)
            timeout_notify: Maximum time to wait for graceful shutdown notification in seconds (default: 30)
            timeout_graceful_shutdown: Graceful shutdown timeout in seconds (None for unlimited)
            timeout_worker_healthcheck: Worker health check timeout in seconds (default: 5)
            callback_notify: Async callback function to invoke during graceful shutdown
            ssl_keyfile: Path to SSL/TLS private key file
            ssl_certfile: Path to SSL/TLS certificate file
            ssl_keyfile_password: Password for encrypted SSL/TLS private key
            ssl_version: SSL/TLS protocol version (default: ssl.PROTOCOL_TLS_SERVER)
            ssl_cert_reqs: SSL/TLS certificate requirements (default: ssl.CERT_NONE)
            ssl_ca_certs: Path to SSL/TLS CA certificates file for client verification
            ssl_ciphers: SSL/TLS cipher configuration string (default: "TLSv1")
            headers: List of custom default headers to include in all responses as (name, value) tuples
            use_colors: Enable colored log output (None for auto-detection based on TTY)
            factory: Treat app as a factory function that returns ASGI application (default: False)
            h11_max_incomplete_event_size: Maximum buffer size for h11 incomplete events in bytes (None for unlimited)
        """

    @property
    def asgi_version(self) -> Literal["2.0", "3.0"]:
        """
        Get ASGI version based on interface configuration.

        **NOTE**: If interface is "auto", this property requires load() to have been called
        first to auto-detect the interface type. Otherwise it will use the configured
        interface value.

        Returns:
            "2.0" for ASGI2 interface, "3.0" for ASGI3/WSGI/auto interfaces
        """

    @property
    def is_ssl(self) -> bool:
        """
        Check if SSL/TLS is configured.

        Returns:
            True if SSL key and certificate files are provided
        """

    @property
    def use_subprocess(self) -> bool:
        """
        Check if subprocess mode should be used.

        Returns:
            True if workers > 1 or reload is enabled with workers specified
        """

    @property
    def should_reload(self) -> bool:
        """
        Check if auto-reload should be enabled.

        Returns:
            True if reload is enabled AND app is a string (import path).
            Auto-reload requires a string import path to re-import the app on changes.
        """

    def configure_logging(self) -> None:
        """
        Configure Python logging system with uvicorn's logging configuration.

        Sets up log levels, handlers, formatters, and colored output based on
        log_config, log_level, access_log, and use_colors settings.
        """

    def load(self) -> None:
        """
        Load application and configure all settings.

        **CRITICAL**: This method must be called before using Config with Server.startup().
        The load() method initializes internal state required by the Server class.

        **NOTE**: load() is automatically called by uvicorn.run() and Server.serve(),
        so you only need to call it manually when using Server.startup() directly.

        This method:
        - Creates SSL context if SSL is configured (sets self.ssl)
        - Encodes headers to bytes (sets self.encoded_headers)
        - Imports and instantiates protocol classes (sets self.http_protocol_class, self.ws_protocol_class)
        - Imports lifespan class (sets self.lifespan_class)
        - Imports the application from string if needed (sets self.loaded_app)
        - Applies WSGI/ASGI2/proxy headers middleware if configured
        - Auto-detects interface type (asgi2/asgi3) if set to "auto"
        - Sets self.loaded = True to indicate configuration is ready

        After calling load():
        - self.loaded: True
        - self.loaded_app: The loaded ASGI application (possibly wrapped in middleware)
        - self.http_protocol_class: HTTP protocol class
        - self.ws_protocol_class: WebSocket protocol class (or None)
        - self.lifespan_class: Lifespan handler class
        - self.ssl: SSL context (or None)
        - self.encoded_headers: List of byte-encoded headers

        Raises:
            SystemExit: If application import fails or factory loading fails
            AssertionError: If called when already loaded
        """

    def get_loop_factory(self) -> Callable[[], asyncio.AbstractEventLoop] | None:
        """
        Get the event loop factory based on loop configuration.

        Returns:
            Event loop factory function, or None if loop is "none"

        The loop factory is resolved from:
        - Built-in loop types: "auto", "asyncio", "uvloop"
        - Custom loop factory import string
        - None for "none" (no event loop setup)

        This method is used internally by uvicorn to set up the event loop.
        For "auto" mode, uvloop is used if available, otherwise asyncio.
        """

    def bind_socket(self) -> socket.socket:
        """
        Create and bind a socket based on configuration.

        Returns:
            Bound socket ready for listening

        The socket is bound using:
        - Unix domain socket if uds is configured
        - File descriptor if fd is configured
        - TCP socket on host:port otherwise

        Socket options are set for reuse and configured with backlog size.
        """
```

### Configuration Type Aliases

Type definitions for configuration string literals.

```python { .api }
# HTTP protocol implementation type
HTTPProtocolType = Literal["auto", "h11", "httptools"]

# WebSocket protocol implementation type
WSProtocolType = Literal["auto", "none", "websockets", "websockets-sansio", "wsproto"]

# Lifespan event handling type
LifespanType = Literal["auto", "on", "off"]

# Event loop implementation type
LoopFactoryType = Literal["none", "auto", "asyncio", "uvloop"]

# ASGI interface type
InterfaceType = Literal["auto", "asgi3", "asgi2", "wsgi"]
```

### SSL Context Creation

Helper function for creating SSL contexts.

```python { .api }
def create_ssl_context(
    certfile: str | os.PathLike[str],
    keyfile: str | os.PathLike[str] | None,
    password: str | None,
    ssl_version: int,
    cert_reqs: int,
    ca_certs: str | os.PathLike[str] | None,
    ciphers: str | None,
) -> ssl.SSLContext:
    """
    Create and configure an SSL context for HTTPS/WSS connections.

    Args:
        certfile: Path to SSL/TLS certificate file
        keyfile: Path to SSL/TLS private key file (None to use certfile)
        password: Password for encrypted private key (None if not encrypted)
        ssl_version: SSL/TLS protocol version
        cert_reqs: Certificate requirements for client verification
        ca_certs: Path to CA certificates file for verifying client certificates (None if not needed)
        ciphers: Cipher suite configuration string (None to use defaults)

    Returns:
        Configured SSLContext ready for use with server sockets
    """
```

### Configuration Attributes

After calling `load()`, the Config instance has additional attributes set:

```python { .api }
class Config:
    # Attributes set after load() is called
    loaded: bool
    """Whether load() has been called."""

    encoded_headers: list[tuple[bytes, bytes]]
    """HTTP headers encoded as bytes."""

    ssl: ssl.SSLContext | None
    """SSL context if SSL is configured."""

    http_protocol_class: type[asyncio.Protocol]
    """Resolved HTTP protocol implementation class."""

    ws_protocol_class: type[asyncio.Protocol] | None
    """Resolved WebSocket protocol implementation class (None if ws="none")."""

    lifespan_class: type
    """Resolved lifespan handler class."""

    loaded_app: ASGIApplication
    """Loaded ASGI application instance."""
```

## Configuration Constants

```python { .api }
# Default log levels mapping
LOG_LEVELS: dict[str, int] = {
    "critical": logging.CRITICAL,  # 50
    "error": logging.ERROR,        # 40
    "warning": logging.WARNING,    # 30
    "info": logging.INFO,          # 20
    "debug": logging.DEBUG,        # 10
    "trace": 5,                    # Custom trace level
}

# HTTP protocol implementation mappings
HTTP_PROTOCOLS: dict[str, str] = {
    "auto": "uvicorn.protocols.http.auto:AutoHTTPProtocol",
    "h11": "uvicorn.protocols.http.h11_impl:H11Protocol",
    "httptools": "uvicorn.protocols.http.httptools_impl:HttpToolsProtocol",
}

# WebSocket protocol implementation mappings
WS_PROTOCOLS: dict[str, str | None] = {
    "auto": "uvicorn.protocols.websockets.auto:AutoWebSocketsProtocol",
    "none": None,
    "websockets": "uvicorn.protocols.websockets.websockets_impl:WebSocketProtocol",
    "websockets-sansio": "uvicorn.protocols.websockets.websockets_sansio_impl:WebSocketsSansIOProtocol",
    "wsproto": "uvicorn.protocols.websockets.wsproto_impl:WSProtocol",
}

# Lifespan handler mappings
LIFESPAN: dict[str, str] = {
    "auto": "uvicorn.lifespan.on:LifespanOn",
    "on": "uvicorn.lifespan.on:LifespanOn",
    "off": "uvicorn.lifespan.off:LifespanOff",
}

# Event loop factory mappings
LOOP_FACTORIES: dict[str, str | None] = {
    "none": None,
    "auto": "uvicorn.loops.auto:auto_loop_factory",
    "asyncio": "uvicorn.loops.asyncio:asyncio_loop_factory",
    "uvloop": "uvicorn.loops.uvloop:uvloop_loop_factory",
}

# Available ASGI interfaces
INTERFACES: list[InterfaceType] = ["auto", "asgi3", "asgi2", "wsgi"]

# Default SSL protocol version
SSL_PROTOCOL_VERSION: int = ssl.PROTOCOL_TLS_SERVER

# Default logging configuration dictionary
LOGGING_CONFIG: dict[str, Any]
"""
Default logging configuration used when log_config is not specified.
Configures formatters, handlers, and loggers for uvicorn and access logs.
"""
```

## Usage Examples

### Basic Configuration

```python
from uvicorn import Config, Server

# Create configuration
config = Config(
    app="myapp:app",
    host="0.0.0.0",
    port=8000,
    log_level="info",
)

# Load configuration
config.load()

# Use with server
server = Server(config)
server.run()
```

### SSL/TLS Configuration

```python
from uvicorn import Config
import ssl

config = Config(
    app="myapp:app",
    host="0.0.0.0",
    port=443,
    ssl_keyfile="/path/to/key.pem",
    ssl_certfile="/path/to/cert.pem",
    ssl_version=ssl.PROTOCOL_TLS_SERVER,
    ssl_cert_reqs=ssl.CERT_NONE,
)
config.load()
```

### Development with Auto-Reload

```python
from uvicorn import Config

config = Config(
    app="myapp:app",
    reload=True,
    reload_dirs=["./src", "./lib"],
    reload_includes=["*.py", "*.yaml"],
    reload_excludes=["*.pyc", "__pycache__/*"],
    reload_delay=0.5,
)
config.load()
```

### Production with Multiple Workers

```python
from uvicorn import Config

config = Config(
    app="myapp:app",
    host="0.0.0.0",
    port=8000,
    workers=4,
    limit_concurrency=1000,
    limit_max_requests=10000,
    timeout_keep_alive=5,
    timeout_graceful_shutdown=30,
    access_log=True,
)
config.load()
```

### Custom Logging Configuration

```python
from uvicorn import Config

logging_config = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "default": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
        },
    },
    "handlers": {
        "default": {
            "formatter": "default",
            "class": "logging.StreamHandler",
            "stream": "ext://sys.stdout",
        },
    },
    "loggers": {
        "uvicorn": {"handlers": ["default"], "level": "INFO"},
        "uvicorn.access": {"handlers": ["default"], "level": "INFO"},
    },
}

config = Config(
    app="myapp:app",
    log_config=logging_config,
)
config.load()
```

### Protocol Selection

```python
from uvicorn import Config

# Use specific HTTP protocol
config = Config(
    app="myapp:app",
    http="h11",  # or "httptools"
    ws="websockets",  # or "wsproto", "none"
)
config.load()

# Use custom protocol class
from uvicorn.protocols.http.h11_impl import H11Protocol

config = Config(
    app="myapp:app",
    http=H11Protocol,
)
config.load()
```

### Proxy Configuration

```python
from uvicorn import Config

config = Config(
    app="myapp:app",
    proxy_headers=True,
    forwarded_allow_ips="127.0.0.1,10.0.0.0/8",
    root_path="/api/v1",
)
config.load()
```

### WebSocket Configuration

```python
from uvicorn import Config

config = Config(
    app="myapp:app",
    ws="websockets",
    ws_max_size=16 * 1024 * 1024,  # 16 MB
    ws_max_queue=32,
    ws_ping_interval=20.0,
    ws_ping_timeout=20.0,
    ws_per_message_deflate=True,
)
config.load()
```
