Skip to main content

PyWeb

An educational HTTP web server built from scratch in Python.

Every time you visit a website, your browser sends a letter to a server and gets a reply. PyWeb is that server -- built from scratch so you can see exactly how it works. Think of it as a post office: letters arrive, get sorted, and replies are sent back.

Features

  • HTTP request parsing -- read the incoming letter (method, path, headers, body, query params)
  • Response building -- write the reply (status codes, headers, body)
  • URL routing -- the mailroom that sorts letters to the right handler
  • Path parameters -- dynamic URLs like /users/<id>
  • Template engine -- form letters with {{ blanks }} to fill in
  • Static files -- serve CSS, JS, images straight from a folder
  • JSON support -- parse JSON request bodies, return JSON responses
  • Logging -- see every request and response in the terminal
  • 405 handling -- proper "Method Not Allowed" for wrong HTTP verbs

Example

from pyweb.router import Router
from pyweb.response import html_response, json_response
from pyweb.server import Server
from pyweb.template import render

router = Router()

@router.get("/")
def homepage(request):
    return html_response(render(
        "<h1>Hello, {{ name }}!</h1>",
        {"name": "World"}
    ))

@router.get("/users/<id>")
def get_user(request):
    return json_response({"user_id": request.params["id"]})

Server(router).serve_forever()

Quick Start

# Install dependencies
uv sync --all-extras

# Run the example server
uv run python examples/hello_server.py
# Visit http://127.0.0.1:8000

# Run tests
uv run pytest

Concepts

Every concept is explained with real-world analogies:

Concept Doc Analogy
Requests requests.md The incoming letter
Responses responses.md The reply letter
Routing routing.md The mailroom
Templates templates.md Form letters with blanks
Server server.md The post office

Documentation

Full docs (with kid-friendly explanations of every idea): https://robcox2910.github.io/pyweb/

Async PyWeb

PyWeb also has an async framework that runs on PyNet's own event loop: one shopkeeper serving many customers at once, with server-sent events, WebSockets, sessions and roles.

from pynet.loop import run
from pynet.streams import open_connection

from pyweb.app import App
from pyweb.aserver import AsyncServer

app = App()


@app.get("/hello/<name>")
async def hello(request, name):
    return {"greeting": f"Hello, {name}!"}


async def main():
    async with AsyncServer(app, access_log=False) as server:
        reader, writer = await open_connection("127.0.0.1", server.port)
        writer.write(b"GET /hello/Sam HTTP/1.1\r\nConnection: close\r\n\r\n")
        await writer.drain()
        print((await reader.read()).split(b"\r\n\r\n")[1].decode())
        writer.close()


run(main())

Output: {"greeting": "Hello, Sam!"}

Run the live demo (a page, a clock that ticks every second, and a WebSocket echo) and visit http://127.0.0.1:8000, then press Ctrl-C to stop:

uv run pyweb --async

More programs live in examples/: async_hello.py, sse_clock.py, ws_echo_page.py and login_demo.py. The step-by-step lessons start at "Part 2: A Busy Restaurant" in docs/index.md.

Developing alongside a sibling

PyWeb uses PyNet and PyCrypt from PyPI (fromscratch-pynet and fromscratch-pycrypt). To work on a sibling checkout at the same time, install it editable and tell uv not to re-sync over it:

uv pip install -e ../pynet
uv run --no-sync pytest

Releasing

Other projects in the series (PyStack) use a pinned release of this one, not whatever is on main. To publish a change for them:

  1. Merge the change to main.
  2. Tag it: git tag -a vX.Y.Z -m vX.Y.Z && git push origin vX.Y.Z. A change to the public API bumps the minor version (v0.1.0 → v0.2.0); anything else bumps the patch (v0.1.0 → v0.1.1).
  3. In each project that uses it, edit the tag in [tool.uv.sources], run uv lock --upgrade-package <name>, and open a pull request so CI checks the pair together.

This project is one of a series that builds real systems "from scratch in Python" to teach how they work. See the series home for the full story.

Project What it teaches Repository Docs
PyOS Operating systems py-os Docs
Pebble Compilers and programming languages pebble-lang Docs
PyDB Relational databases pydb Docs
PyKV Key-value stores pykv Docs
PyDocDB Document databases pydoc-db Docs
PyGraphDB Graph databases pygraphdb Docs
PyTSDB Time-series databases pytsdb Docs
PyVecDB Vector databases pyvecdb Docs
PyColDB Column-family databases pycoldb Docs
PyCrypt Cryptography pycrypt Docs
PyNet Computer networking pynet Docs
PyWeb HTTP web servers pyweb Docs
PyGit Version control pygit Docs
PySearch Search engines pysearch Docs
PyMQ Message queues pymq Docs
PyLLM Language models (the brain) pyllm Docs
PyScheduler Job scheduling pyscheduler Docs
PyStack Full-stack integration pystack Docs

License

MIT

Metadata

Release files for fromscratch-pyweb 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fromscratch-pyweb 0.4.0
File Size Uploaded Provenance
fromscratch_pyweb-0.4.0.tar.gz 223.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for fromscratch-pyweb 0.4.0
File Interpreter ABI Platform
fromscratch_pyweb-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 292.0 kB

Release files / fromscratch_pyweb-0.4.0.tar.gz

Download URL fromscratch_pyweb-0.4.0.tar.gz
Size 223.8 kB
Tags Source
SHA-256 checksum
How to use checksums
8f03bf08884a5c004442d7c01264b44c82b4f4e9253b0d6b65702388984ee461
BLAKE2b-256 checksum
How to use checksums
26fff2b0c7e33ae6c5cb8f00e8dea2d0786ed2ca9aa4ddc8e3b637318972d830
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / fromscratch_pyweb-0.4.0-py3-none-any.whl

Download URL fromscratch_pyweb-0.4.0-py3-none-any.whl
Size 68.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
16f3b4a61978fe8d5bc778a8a08c7be629e052af803599b7cecc246b9e9e3cc1
BLAKE2b-256 checksum
How to use checksums
c320df06cc31f6ad5df1fa69ce833fbaefea7c57b2c8945ed7f6f319a43fe8c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for fromscratch-pyweb 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for fromscratch_pyweb-0.4.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page