uvicorn.run()

Master programmatic ASGI server control with Python's most powerful web server

Get Started

What is uvicorn.run()?

uvicorn.run() is the programmatic interface to Uvicorn, Python's lightning-fast ASGI web server. Unlike the command-line interface, it allows you to start and configure your server directly from Python code, giving you complete control over server lifecycle and configuration.

Perfect for production deployments, testing environments, and applications that need dynamic server configuration, uvicorn.run() is the go-to choice for modern Python web applications built with FastAPI, Starlette, and other ASGI frameworks.

Quick Start

Get up and running with uvicorn.run() in seconds:

import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"message": "Hello, World!"}

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

That's it! Your ASGI application is now running with automatic reloading enabled for development.

Parameters Reference

Configure every aspect of your server with these comprehensive parameters:

app

str | ASGI App

Your ASGI application. Can be a string in "module:attribute" format or the application object directly.

host

str

Bind socket to this host. Use "0.0.0.0" to make the server available externally. Default: "127.0.0.1"

port

int

Bind socket to this port. Default: 8000

reload

bool

Enable auto-reload for development. Watches for file changes and restarts the server automatically.

log_level

str

Logging level: "critical", "error", "warning", "info", "debug", "trace". Default: "info"

ssl_keyfile

str

SSL key file path for HTTPS support.

ssl_certfile

str

SSL certificate file path for HTTPS support.

workers

int

Number of worker processes. Only available when not using reload.

Real-World Examples

Production Configuration

import uvicorn
import os

if __name__ == "__main__":
    uvicorn.run(
        "app.main:app",
        host="0.0.0.0",
        port=int(os.getenv("PORT", 8000)),
        workers=4,
        log_level="warning",
        access_log=False,
        ssl_keyfile="./ssl/key.pem",
        ssl_certfile="./ssl/cert.pem"
    )

Development with Auto-Reload

import uvicorn

if __name__ == "__main__":
                    uvicorn.run(
        "app.main:app",
        host="127.0.0.1",
        port=8000,
        reload=True,
        reload_dirs=["./app"],
        log_level="debug"
    )

Advanced Configuration with Config Object

import uvicorn
from uvicorn.config import Config
from uvicorn.server import Server

async def run_server():
    config = Config(
        "app.main:app",
        host="0.0.0.0",
        port=8000,
        log_level="info",
        access_log=True,
        use_colors=True
    )
    server = Server(config)
    await server.serve()

if __name__ == "__main__":
    import asyncio
    asyncio.run(run_server())

Testing Environment

import uvicorn
import threading
import time

def start_test_server():
    uvicorn.run(
        "tests.app:app",
        host="127.0.0.1",
        port=8001,
        log_level="critical",
        access_log=False
    )

# Start server in background for testing
server_thread = threading.Thread(target=start_test_server, daemon=True)
server_thread.start()
time.sleep(1)  # Wait for server to start

# Run your tests here

Best Practices

Performance & Security

  • Use multiple workers in production for CPU-bound tasks
  • Disable access logs in production for better performance
  • Use environment variables for configuration
  • Enable SSL/TLS for production deployments
  • Set appropriate log levels for different environments
  • Use reload only in development environments
  • Configure proper host binding (0.0.0.0 for external access)
  • Monitor server performance with proper logging

Development Tips

  • Use reload_dirs to watch specific directories for changes
  • Set debug log level during development
  • Use different ports for different services
  • Keep development and production configs separate

Common Patterns

Environment-Based Configuration

import uvicorn
import os

def get_config():
    if os.getenv("ENVIRONMENT") == "production":
        return {
            "host": "0.0.0.0",
            "port": int(os.getenv("PORT", 8000)),
            "workers": int(os.getenv("WORKERS", 4)),
            "log_level": "warning",
            "access_log": False
        }
    else:
        return {
            "host": "127.0.0.1",
            "port": 8000,
            "reload": True,
            "log_level": "debug"
        }

if __name__ == "__main__":
    config = get_config()
    uvicorn.run("app.main:app", **config)

Graceful Shutdown

import uvicorn
import signal
import asyncio

class GracefulServer:
    def __init__(self):
        self.server = None
        self.should_exit = False
        
    async def run(self):
        config = uvicorn.Config("app.main:app", host="0.0.0.0", port=8000)
        self.server = uvicorn.Server(config)
        
        # Setup signal handlers
        for sig in (signal.SIGTERM, signal.SIGINT):
            signal.signal(sig, self.signal_handler)
            
        await self.server.serve()
    
    def signal_handler(self, signum, frame):
        print(f"Received signal {signum}")
        self.should_exit = True
        if self.server:
            self.server.should_exit = True

if __name__ == "__main__":
    server = GracefulServer()
    asyncio.run(server.run())