Python Pack
ASW-styled error pages and directory listings for Python web servers — drop-in support for http.server, Flask, and FastAPI.
Two tools, one pattern
The Python pack provides styled error responses for two different scenarios:
| Tool | Use case |
|---|---|
asw_server.py |
Local dev server replacing python -m http.server |
asw_errors.py |
Production error handlers for Flask and FastAPI apps |
Both inline ASW styles by default — no external dependencies.
Dev server
packs/python/asw_server.py replaces
python -m http.server with styled error pages and directory
listings.
# Copy to your project
cp path/to/packs/python/asw_server.py .
# Run
python asw_server.py # port 8000
python asw_server.py 3000 # custom port
python asw_server.py 3000 /dir # custom port + directoryThe server tries consecutive ports if the requested one is busy — useful for running multiple services in development.
What changes
- Error pages — 403, 404, 500 and all other HTTP errors show styled cards instead of the browser default
- Directory listings — a clean table replaces the raw
<pre>autoindex - Auto port fallback — if 8000 is busy, tries 8001, 8002, … up to 10 attempts
- No config required — drop the file in, run it
Flask/FastAPI error handlers
packs/flask/asw_errors.py registers error handlers on
Flask or FastAPI applications with a single call.
Flask
from flask import Flask
from asw_errors import register_asw_errors
app = Flask(__name__)
register_asw_errors(app)FastAPI
from fastapi import FastAPI
from asw_errors import register_asw_errors
app = FastAPI()
register_asw_errors(app)register_asw_errors() auto-detects the framework from
the app type. No conditional imports in your code.
Error codes covered
| Code | Status |
|---|---|
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 405 | Method Not Allowed |
| 408 | Request Timeout |
| 409 | Conflict |
| 410 | Gone |
| 415 | Unsupported Media Type |
| 422 | Unprocessable Entity |
| 429 | Too Many Requests |
| 500 | Internal Server Error |
| 502 | Bad Gateway |
| 503 | Service Unavailable |
| 504 | Gateway Timeout |
For FastAPI, RequestValidationError (the 422 raised by
Pydantic) is registered separately in addition to
HTTPException.
Linking agentic.css
By default, all styles are inlined — the page works with no external
requests. If your app already serves agentic.css, link it
instead to get custom fonts and the full theme:
register_asw_errors(app, css_url="/static/agentic.css")Custom app name
The nav bar shows the app name. Flask auto-reads
app.name; FastAPI reads app.title. Override
either:
register_asw_errors(app, app_name="Mission Control")Standalone HTML generation
The error_html() function is exported if you need to
generate pages without registering handlers:
from asw_errors import error_html
# In a custom exception handler
body = error_html(404, path=request.path)
body = error_html(503, css_url="/static/agentic.css", app_name="My API")Lazy imports
Flask and FastAPI are imported inside
register_asw_errors(), not at module level. A project can
import asw_errors.py with either framework installed — you
won't get an ImportError for the other one.
Files
packs/python/
├── asw_server.py http.server replacement with styled errors + directory listings
└── README.md Dev server reference
packs/flask/
├── asw_errors.py Flask + FastAPI error handler registration
└── README.md Error pack reference
Note
The pack directories are named by deployment context, not by
framework. packs/python/ is the dev server because it's
used in pure Python environments with no web framework.
packs/flask/ is the error pack because Flask is the most
common target — but the same file handles FastAPI.