Python By Example is a Go By Example-inspired learning site for Python 3.13. It presents small literate examples with prose, source fragments, expected output, official Python documentation links, and an editable runner.
Production: https://www.pythonbyexample.dev (workers.dev remains enabled as a fallback).
- 70 curated Python 3.13 examples in learning order
- Literate source/output cells for each example walkthrough
- Editable complete examples powered by CodeMirror
- Read-only syntax highlighting powered by Shiki
- Example execution in isolated Cloudflare Dynamic Python Workers
- Official Python 3.13 documentation links per example
- Workers Assets for static files
- Fingerprinted CSS/JS assets with immutable cache headers
- Versioned Worker Cache API keys for rendered HTML
- SEO metadata and canonical URLs for home and example pages
Python By Example is inspired by:
- Go by Example for the concise example-per-page teaching format.
- Rust By Example for practical runnable examples and expected output.
- Literate programming, especially the idea that prose and source should explain each other rather than live as separate artifacts.
- Notebook-style tools such as marimo for the source/output adjacency used in the walkthrough cells.
The project uses:
- Cloudflare Workers and Python Workers for deployment and runtime.
- FastAPI for application routing.
- Shiki for read-only syntax highlighting.
- CodeMirror for the editable example editor.
Python documentation links point to the official Python documentation.
src/main.pyis the Cloudflare Worker entrypoint.- FastAPI handles request routing through the Cloudflare ASGI bridge.
src/app.pyrenders pages from simple placeholder templates insrc/templates/.src/example_sources/*.mdcontains the human-editable examples.src/example_loader.pyparses Markdown examples into the runtime catalog.src/examples.pyis a compatibility shim for the loaded catalog.src/example_sources_data.pyis generated embedded source data for Cloudflare Workers.public/contains static assets served by Workers Assets.python_modules/is generated by the Workers tooling and intentionally ignored by Git.
Example runs are executed by Dynamic Workers. The parent Worker creates a Dynamic Worker module from the submitted code, disables outbound network access, and keys Worker Loader reuse by Python version, example slug, and code hash.
This project is developed with red-green-refactor TDD:
- Write or update a failing test.
- Implement the smallest change that makes it pass.
- Refactor while keeping tests green.
Install dependencies with uv, then run:
python3 -m unittest discover -s tests -vRun locally on Workers:
uv run --group workers pywrangler dev --port 9696Open:
http://localhost:9696
Run a local Worker before the full browser-backed verification:
uv run --group workers pywrangler dev --port 9696Then run the main checks before deploying or pushing:
make verify
scripts/check_example_migration_parity.py
scripts/format_examples.py --check
make verify-python-version VERSION=3.13
git diff --checkmake seo-cache-lint verifies that:
- home and all example pages have SEO metadata
- canonical and Open Graph URLs are correct
- HTML references fingerprinted CSS/JS assets
- generated asset hashes match current source assets
HTML_CACHE_VERSIONis fresh- Worker Cache API keys include the HTML version
- prototype layout pages are not cached
make browser-layout-test launches headless Chrome and checks the rendered Shiki code-block layout so generated line markup does not create visual blank rows.
Source assets live at stable paths such as:
public/site.css
public/syntax-highlight.js
public/editor.js
Before tests/deploy, regenerate embedded example data, fingerprinted asset copies, and Python manifests:
make buildThis writes files such as:
public/site.<hash>.css
public/syntax-highlight.<hash>.js
public/editor.<hash>.js
src/asset_manifest.py
Rendered HTML uses only fingerprinted asset URLs. public/_headers gives these immutable cache headers:
Cache-Control: public, max-age=31536000, immutable
Rendered HTML pages are cached separately with a generated HTML_CACHE_VERSION in the Worker Cache API key. When templates, examples, app code, or asset fingerprints change, the generated HTML cache key changes too.
Prototype layout routes under /layout-options/* bypass the Worker Cache API and return Cache-Control: no-store.
Run checks, then deploy:
make verify
scripts/check_example_migration_parity.py
scripts/format_examples.py --check
make deploymake deploy runs make build first, so embedded example data and cache fingerprints are regenerated before Wrangler deploys.
See CONTRIBUTING.md for pull request workflow, example editing rules, and verification commands.
Edit Markdown files under src/example_sources/.
Each example has:
- TOML frontmatter with
slug,title,section,summary, anddoc_path - exactly one
:::programblock for the full editable source - one or more
:::cellblocks for verified prose/source/output teaching cells - optional
:::noteblocks
After editing examples, run:
make build
make verify-examples
scripts/format_examples.py --check
scripts/check_example_migration_parity.py
make check-generatedsrc/example_sources_data.py is generated and committed so Cloudflare Workers can load examples in production. Do not edit it by hand.
For a Python version migration, update python_version and docs_base_url in src/example_sources/manifest.toml, then run:
make verify-python-version VERSION=3.13Use the active Cloudflare-supported Python version.
wrangler.jsoncenablespython_workersandpython_dedicated_snapshot.- The parent Worker uses a
LOADERWorker Loader binding. - Dynamic Worker IDs include Python version, example slug, and submitted code hash.
- Dynamic Workers run with
globalOutbound: nulland tight CPU/subrequest limits. - POST example runs are never cached.