Starlette Guide
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
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
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)from starlette.staticfiles import StaticFiles
app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount("/api", api_app)Middleware
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
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
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
from starlette.testclient import TestClient
def test_homepage():
client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"hello": "world"}