Starlette

Language: Python

Web

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.

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.

Installation

pip: pip install starlette
conda: conda install -c conda-forge starlette

Usage

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.

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.

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.

Error Handling

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.