Oberoon
Oberoon is a Python web framework written to explore the architecture of modern Python server interfaces. It started as a learning project to understand the low-level WSGI specification (PEP 3333) and evolved into an asynchronous ASGI framework with high-speed JSON serialization.
Here is the story of how Oberoon was built, following the commits, functions, structures, and architectural decisions made throughout the project.
timeline
title Oberoon Development Timeline
v0.1.0 : Synchronous WSGI foundations : WebOb Request/Response, Regex routing, Jinja2 templates, Whitenoise, Middleware
v0.2.0 : ASGI Metamorphosis : Transition to async/await, pre-compiled import-time routing, nested APIRouters
v0.3.0 : Validation & msgspec : msgspec integration, schema modeling, fast query/body validation
Phase 1: WSGI Foundations & Basic Routing (Commits 1c00d0d - c2ddf18)
The framework began by testing the raw WSGI interface using Python’s standard wsgiref library and gunicorn:
- WebOb Abstractions: Raw WSGI environment dictionaries are verbose and hard to parse. Oberoon integrated WebOb to wrap incoming WSGI environments into clean, object-oriented
RequestandResponseobjects (81ca186). - Dynamic Routing: A routing engine mapping paths to handler callables was introduced. Parameterized segments (e.g.
/hello/{name}) were supported by converting path patterns into regular expressions at startup (2925ef0), capturing path parameters, and passing them to route functions. - Class-Based Views: Added support for mapping endpoints to classes with
getandpostmethods representing HTTP verbs. - Test Framework: Implemented a testing suite using
pytestand a custom test client wrapper to simulate requests against endpoints.
Phase 2: Batteries-Included WSGI (Commits 966ffd4 - 0256d71)
With routing and request wrappers active, standard web development tools were integrated:
- Jinja2 Templating: Added direct template rendering support via an
app.template()helper. - Static Assets: Integrated Whitenoise (
1134b28) to serve static assets efficiently without needing an external Nginx proxy for development. - Middleware: Built a middleware pipeline wrapping the WSGI call stack, enabling custom request pre-processing and response formatting.
- Method Restrictions: Introduced the
allowed_methodslist decorator to restrict routes to specific HTTP methods (e.g., rejecting a GET on a POST-only endpoint).
Phase 3: The ASGI Metamorphosis (Commits ad806ad - 55e06d6)
To support high-concurrency connections and asynchronous programming, Oberoon underwent a major rewrite, shifting from WSGI to ASGI (Asynchronous Server Gateway Interface):
- ASGI Skeleton: The framework was adapted to work with async/await handlers and ASGI servers like Uvicorn, handling ASGI connection lifetimes.
- Import-Time Routing Compiler: The routing registry was rebuilt to compile all regex routes at import time (
4ebc43d), reducing the runtime path-matching overhead. - Nested Routers: Introduced support for recursive nested routers (
include_router), allowing developers to split large projects into modular routing sub-systems (similar to Django'sincludeor FastAPI'sAPIRouter).
Phase 4: Type Safety & msgspec Serialization (Commits 3c4caa5 - 6538874)
The latest iteration focuses on request modeling and data validation:
- msgspec Integration: Replaced standard JSON libraries with msgspec for ultra-fast serialization.
- Auto-Validation: Added request body, header, and query parameter type validation, automatically returning structured validation errors when schemas are violated.