Project 2: Build a Minimal Python Web Framework

Build a tiny Django/Flask-like framework with routing, templating, and request/response abstractions.


Quick Reference

Attribute Value
Difficulty Advanced
Time Estimate 3-4 weeks
Language Python
Prerequisites Project 1, decorators, regex
Key Topics routing, request/response, templating, middleware
Output Mini framework + example app

Learning Objectives

By completing this project, you will:

  1. Build a routing system with decorators and path params.
  2. Implement Request and Response objects on top of WSGI.
  3. Add template rendering with context variables.
  4. Support middleware stacks and error handling.
  5. Provide a simple dev server and example app.
  6. Explain how Django and Flask structure their internals.

The Core Question You’re Answering

“How does a framework turn raw HTTP into a clean developer API?”

Once you can answer that, debugging framework behavior becomes straightforward.


Concepts You Must Understand First

Concept Why It Matters Where to Learn
Decorators Register routes cleanly Python decorators
URL patterns Path params and regex Django routing docs
Template rendering Separate logic from HTML Jinja2 docs
Request lifecycle Where to parse data WSGI + Flask docs
Middleware Cross-cutting behavior Django middleware docs

Key Concepts Deep Dive

  1. Route Registration
    • Decorators store route info (path, methods, handler).
  2. Request/Response Abstractions
    • Request wraps environ and parses once.
    • Response manages headers, status, body.
  3. Templating
    • Render HTML with variables and control flow.
    • Escape unsafe values by default.

Theoretical Foundation

Request Flow

WSGI -> Router -> Handler -> Response -> WSGI

The framework’s job is to standardize and simplify this flow.


Project Specification

What You Will Build

A mini framework with:

  • @route decorator
  • Request/Response objects
  • Template rendering
  • Middleware pipeline

Functional Requirements

  1. Define routes with decorators and path params.
  2. Support GET and POST methods.
  3. Provide Request object with args, form, headers.
  4. Render templates with context variables.
  5. Add at least one middleware.

Non-Functional Requirements

  • Usability: Simple API for devs.
  • Correctness: 404/500 handling.
  • Extensibility: Easy to add new middleware.

Example Usage / Output

app = App()

@app.route("/users/<int:id>")
def user_detail(request, id):
    return render_template("user.html", user_id=id)

Real World Outcome

You can build a demo app with routes, templates, and clean request handling without Django or Flask.


Solution Architecture

High-Level Design

WSGI -> Router -> Handler -> Response
         ^
         |
    Middleware

Key Components

Component Responsibility Key Decisions
Router URL matching Regex vs converters
Request Parse environ Lazy parsing
Response Status/headers/body Immutable vs mutable
Template engine Render HTML Jinja2

Implementation Guide

Development Environment Setup

python -m venv web-env
source web-env/bin/activate
pip install jinja2

Project Structure

project-root/
├── framework/
│   ├── app.py
│   ├── routing.py
│   ├── request.py
│   ├── response.py
│   └── templating.py
├── templates/
└── demo_app.py

The Core Question You’re Answering

“How do frameworks make web development ergonomic?”

Questions to Guide Your Design

  1. How will you match URLs with parameters?
  2. What happens when no route matches?
  3. How will you structure middleware order?
  4. How will you prevent template injection?

Thinking Exercise

Create a route table with 5 paths, including param routes. Decide the matching order.

Interview Questions

  1. How does decorator-based routing work?
  2. Why do frameworks wrap WSGI in Request objects?
  3. How do you handle 404 and 500?
  4. What are template engines for?
  5. What are the pros/cons of middleware?

Hints in Layers

  • Hint 1: Start with static routes.
  • Hint 2: Add parameter extraction later.
  • Hint 3: Build Request parsing once.
  • Hint 4: Add error handling at the outermost layer.

Implementation Phases

Phase 1: Routing (1 week)

  • Decorator registration.
  • Match static paths.

Checkpoint: /hello works.

Phase 2: Request/Response (1 week)

  • Parse query/body.
  • Implement Response class.

Checkpoint: Handlers access request data.

Phase 3: Templates + Middleware (1-2 weeks)

  • Render templates with context.
  • Add logging middleware.

Checkpoint: Demo app renders HTML pages.


Testing Strategy

Category Purpose Examples
Routing Match paths /users/1
Request Parse params query/form
Templates Render context variable substitution

Critical cases:

  • Missing route -> 404.
  • Unsupported method -> 405.
  • Template missing -> 500.

Common Pitfalls and Debugging

Pitfall Symptom Solution
Greedy routes Wrong handler Order by specificity
Re-parsing body Empty data Parse once
Template errors Blank page Surface errors in dev

Extensions and Challenges

  • Named routes and URL reversing.
  • Static file serving.
  • JSON response helper.

Resources

  • Werkzeug: https://werkzeug.palletsprojects.com/
  • Jinja2: https://jinja.palletsprojects.com/
  • Django URL routing: https://docs.djangoproject.com/

Self-Assessment Checklist

  • I can design a router with param matching.
  • I can build Request/Response abstractions.
  • I can render templates with context safely.

Submission / Completion Criteria

Minimum Viable Completion

  • Routing + Request/Response + templates.

Full Completion

  • Middleware and error handling.

Excellence

  • Named routes, static files, and JSON helpers.

This guide was generated from LEARN_DJANGO_WEB_FRAMEWORKS.md. For the complete learning path, see the parent directory LEARN_DJANGO_WEB_FRAMEWORKS/README.md.