We use cookies to understand how the site is used and to display ads. Analytics and advertising only run after you accept. You can change your choice anytime. Privacy policy

Skip to content
devvkit
$devvkit learn --librarie starlette-guide

Starlette Guide

[python][async][asgi][api]
Python
Install
pip install starlette
# or: uv add starlette
# or: poetry add starlette

Starlette is the foundation for many Python async frameworks (FastAPI builds on it). It provides ASGI support, WebSocket handling, background tasks, streaming responses, and middleware in a minimal package.

The routing system supports path parameters, method-based dispatching, and sub-app mounting. Starlette handles both HTTP and WebSocket connections on the same port. Middleware wraps the ASGI app chain.

Starlette's test client uses httpx for async integration testing. It includes a Server-Sent Events (SSE) streaming response and integrates with Jinja2 for templating when needed.

Setup

Basic app· ASGI Starlette app.
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

async def homepage(request):
    return JSONResponse({"hello": "world"})

async def about(request):
    return JSONResponse({"message": "About us"})

app = Starlette(routes=[
    Route("/", homepage),
    Route("/about", about),
])

Routing

Path parameters· URL parameters.
async def user_detail(request):
    user_id = request.path_params["user_id"]
    return JSONResponse({"user_id": user_id})

Route("/users/{user_id:int}", user_detail)
Route("/users/{username:str}", user_detail)
Route("/files/{path:path}", file_download)
Mount sub-app· Mount other ASGI apps.
from starlette.staticfiles import StaticFiles

app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount("/api", api_app)

Middleware

Custom middleware· Wrap request/response.
from starlette.middleware.base import BaseHTTPMiddleware

class TimingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        start = time.time()
        response = await call_next(request)
        elapsed = time.time() - start
        response.headers["X-Elapsed"] = str(elapsed)
        return response

app.add_middleware(TimingMiddleware)

WebSockets

WebSocket· Handle WS connections.
from starlette.websockets import WebSocket

async def ws_endpoint(websocket: WebSocket):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"Echo: {data}")

Route("/ws", endpoint=ws_endpoint)

Background Tasks

Background task· Run after response.
from starlette.background import BackgroundTask

async def send_email(email: str):
    ...  # send email

async def create_user(request):
    data = await request.json()
    task = BackgroundTask(send_email, email=data["email"])
    return JSONResponse({"ok": True}, background=task)

Testing

Test client· Async test client.
from starlette.testclient import TestClient

def test_homepage():
    client = TestClient(app)
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"hello": "world"}