Skip to content

What it is

Starlette is a lightweight ASGI framework/toolkit for building high-performance asynchronous web services in Python. It provides routing, middleware, sessions, background tasks, WebSockets, and testing utilities.

Starlette allows you to define routes, mount applications, add middleware, handle background tasks, manage sessions, and work with WebSockets. Its asynchronous design ensures high performance for I/O-bound applications.

Installation

pip install starlette

Getting started

The smallest useful thing you can do with it, and what each part means.

Simple Starlette app
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

async def homepage(request):
    return JSONResponse({'message': 'Hello, Starlette!'})

routes = [
    Route('/', homepage)
]

app = Starlette(debug=True, routes=routes)
Defines a basic Starlette application with one GET route returning JSON.
Running the app with Uvicorn
# Terminal command:
uvicorn main:app --reload
Starts the Starlette app using Uvicorn as the ASGI server with automatic reload on code changes.

Advanced usage

Where the library earns its place over a simpler alternative.

Middleware example
from starlette.middleware.base import BaseHTTPMiddleware

class SimpleMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        response = await call_next(request)
        response.headers['X-Custom-Header'] = 'Value'
        return response

app.add_middleware(SimpleMiddleware)
Adds middleware to process requests and responses, such as adding custom headers.
Background task
from starlette.background import BackgroundTask

async def write_log():
    with open('log.txt', 'a') as f:
        f.write('Task executed\n')

async def homepage(request):
    return JSONResponse({'message': 'Hello!'}, background=BackgroundTask(write_log))
Runs a background task after sending the response to the client.
WebSocket example
from starlette.endpoints import WebSocketEndpoint
from starlette.websockets import WebSocket

class Echo(WebSocketEndpoint):
    async def on_connect(self, websocket: WebSocket):
        await websocket.accept()

    async def on_receive(self, websocket: WebSocket, data):
        await websocket.send_text(f'Received: {data}')

    async def on_disconnect(self, websocket: WebSocket, close_code):
        pass

app.add_websocket_route('/ws', Echo)
Creates a WebSocket endpoint that echoes messages back to the client.
Mounting sub-applications
from starlette.routing import Mount
from starlette.staticfiles import StaticFiles
app.mount('/static', StaticFiles(directory='static'), name='static')
Mounts a static file directory to serve assets under the `/static` path.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

404 Not Found
Ensure that the requested route is defined. Use exception handlers for custom responses.
500 Internal Server Error
Check asynchronous function exceptions and middleware to catch unhandled errors.

Best practices

  • Use async endpoints for I/O-bound operations to maximize performance.
  • Leverage middleware for cross-cutting concerns like logging, authentication, and CORS.
  • Use Starlette’s BackgroundTask for non-blocking background operations.
  • Combine with Uvicorn or Hypercorn for production-ready ASGI deployment.
  • Test routes using Starlette’s built-in TestClient for automated testing.

Background

Why it exists, and what it was reacting to.

Starlette was created by Tom Christie, the author of Django REST Framework, to provide a minimal, fast, and flexible ASGI framework. It serves as the foundation for FastAPI and is widely used for building modern asynchronous web applications and APIs.