Skip to content

Justice-Through-Code/aise26-w33d2-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

W33D2 Demo Repo: Preparing for Scale

Companion code for the W33D2 lesson — runnable examples of caching, bottleneck identification, and background tasks, designed to support the teaching block and give fellows patterns they can adapt for their capstone work.

The lesson's central frame: scaling is about not wasting work. Everything in this repo demonstrates one of three moves — cache the result, find the slowest step, or move work off the hot path.

What's here

w33d2-demo-repo/
├── README.md
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
├── app.py                  # Baseline FastAPI app — slow, no patterns applied
├── benchmark.py            # Repeated query test tool — same query × 10
├── snippets/               # Standalone code examples for each pattern
│   ├── caching_dict.py
│   ├── caching_lru.py
│   ├── timing_bottleneck.py
│   └── background_tasks.py
└── solutions/              # The same app with each pattern applied
    ├── app_with_cache.py
    ├── app_with_timing.py
    └── app_with_async.py

Quick start (Docker Compose)

Each app variant is a separate profile. Only one runs at a time — they all bind to port 8000, which is the point: spin up one, benchmark it, then swap.

# Terminal 1 — start the baseline
docker compose --profile baseline up

# Terminal 2 — run the benchmark
python benchmark.py

You should see ten consecutive calls of roughly the same length (~1.9 seconds each). The app repeats expensive work — retrieval, model call, logging — on every request, even when the query is identical. That's the experience the opening activity is designed to surface.

Stop the baseline with Ctrl+C, then run a variant the same way:

docker compose --profile cache up      # with caching applied
docker compose --profile timing up     # with timing logs
docker compose --profile async up      # logging moved off the hot path

The benchmark always runs against localhost:8000, so the command in Terminal 2 doesn't change.

Quick start (native Python — no Docker)

If you don't have Docker, the same flow works directly:

pip install -r requirements.txt

# Terminal 1 — start the baseline
uvicorn app:app --reload

# Or a variant
uvicorn solutions.app_with_cache:app --reload

# Terminal 2 — run the benchmark
python benchmark.py

Running the standalone snippets

Each snippet in snippets/ is a self-contained Python file demonstrating one pattern.

With Docker (no Python required on host):

docker compose run --rm baseline python snippets/caching_dict.py
docker compose run --rm baseline python snippets/caching_lru.py
docker compose run --rm baseline python snippets/timing_bottleneck.py

(--profile isn't needed for one-shot run commands.)

Native:

python snippets/caching_dict.py
python snippets/caching_lru.py
python snippets/timing_bottleneck.py

snippets/background_tasks.py is a FastAPI app on its own — run it with uvicorn or add it as another compose profile.

Comparing baseline to solutions

The solutions/ folder shows the same baseline app with each pattern applied. Useful for diff-based teaching:

diff app.py solutions/app_with_cache.py
diff app.py solutions/app_with_timing.py
diff app.py solutions/app_with_async.py

Suggested teaching arc

  1. Show baseline. docker compose --profile baseline up + python benchmark.py. The system repeats work on every call. Expected: ~1.9s per call, no improvement across calls.
  2. Apply caching. Stop baseline, run docker compose --profile cache up. Re-run the benchmark. Expected: first call ~1.9s, subsequent calls near-instant.
  3. Show the timing log variant. docker compose --profile timing up. Discuss why instrumenting suspects beats instrumenting everywhere.
  4. Move logging async. docker compose --profile async up. Note: for the W33D2 capstone deliverable, fellows only need to name an async candidate, not implement one. This profile is illustrative.

Adapting for fellows' capstones

Fellows have heterogeneous stacks (Python, JavaScript, varying frameworks). The patterns transfer:

  • Caching: every language has a hash map. functools.lru_cache in Python; a Map or plain object in JS; equivalents elsewhere.
  • Timing: time.time() deltas in Python; console.time / console.timeEnd or performance.now() in JS.
  • Background work: BackgroundTasks in FastAPI; setImmediate or a worker queue in Node; the conceptual move is the same — return to the user before the side effect finishes.

License

Use freely for AISE 2026 instruction.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors