Skip to content
5-YEAR PROGRAM · YEAR 1 · PHASE 4
UPCOMING

Python: Fluency + ship rxp

Fourth phase. Python at fluency — enough to ship a real CLI, write small services, do data work. Not “Python expert in 5 weeks.” Mastery comes when you operate something complex written in it. ~5 weeks, ~60 hrs.

The first three phases of Year 1 treated systems as something you observe — strace this, tcpdump that, EXPLAIN ANALYZE the other. Phase 4 is the first time you write something the platform will use. The bar isn’t “Python expert” — it’s “I can ship a small, tested, packaged CLI that someone could install today.” That’s enough to graduate from observer to author.

The Year 1 overview is explicit on this point: fluency, not mastery. The same principle applies to Phase 5 (Go). Mastery is what happens in Years 3-5 when you operate complex systems written in these languages — Spark, Kubeflow, platform-ctl, services/llm-gateway/. Year 1 is buying you the right to learn those without language friction.


Prerequisites

  • Phase 3 complete — Postgres + Redis fluent
  • You accept: fluency, not mastery. Ship rxp (and konfig if you have time). Don’t try to learn every Python idiom — pick the patterns most useful for ROOT (CLI, IO, validation, async basics) and move on.

Why this phase exists

Years 3-5 lean on Python heavily — Spark/PySpark, Airflow DAGs, Ray, Kubeflow Pipelines, ML training scripts, FastAPI services, RAG glue code. You don’t need Python mastery to operate those — you need fluency + the operational patterns. The goal here is “I can read any Python codebase and ship a small CLI.”

rxp is the proof-of-fluency artifact. konfig is the stretch artifact for the same phase budget.


1. PROBLEM

You want to write small tools and small services that solve real problems in your platform. Python is the highest-leverage choice because it’s the lingua franca of ops/data/ML. The risk is over-investing in Python idioms that don’t compound.

This phase ships utility code that you’ll actually userxp for log-pattern extraction (gets called by Year 5 services/aiops/), konfig for validating your own basecamp YAML (Year 2+ uses it in CI).

Both projects have a real integration role — they’re not orphan demos. That’s the whole reason they exist as Year 1 artifacts: shipping habits + actual platform value.


2. PRINCIPLES (lean: fluency phase)

2.1 Text processing as a first-class primitive

Logs, configs, exceptions — most ops work is reading text. Regex + structured parsers are the tools.

Investigate:

  • Build a regex that extracts (timestamp, level, message) from a Linux journald line
  • When does regex fail? (Nested structure, escaping hell.) When do you reach for lark / parsy / a real parser?

2.2 Schema validation as a discipline

Configs lie. Validating at the boundary catches bugs early.

Investigate:

  • Pydantic v2 validators on a small config object
  • JSON Schema validation with jsonschema; round-trip a YAML through it

This is the principle konfig embodies, and the reason it earns its place in basecamp CI in Year 2 — Helm values lie all the time (typos, missing keys, wrong types), and validating them at PR time is dramatically cheaper than discovering the lie at helm install time inside a cluster.

2.3 IO + concurrency basics

Python has multiple concurrency models — threads, asyncio, multiprocessing. Pick the right one per workload.

Investigate:

  • When does asyncio win? When does multiprocessing win? When do threads suffice?
  • Build a small concurrent fetcher (5 URLs in parallel) three ways: threads, asyncio, sync

This investigation is deliberately a warm-up for Phase 5 — you’ll re-implement the same concurrent-fetcher problem in Go with goroutines and observe how much Go’s runtime takes off your shoulders. Comparing the three Python implementations now makes the contrast meaningful then.

2.4 CLI ergonomics

Good CLIs have: --help that’s actually helpful, predictable exit codes, --json for machine consumption, color when interactive, no color when piped.

Investigate:

  • typer vs click — pick one
  • rich for terminal rendering
  • Exit codes 0/1/2 conventions

Every CLI in the program — rxp, konfig, pulse, eventually platform-ctl and mlship — needs to behave well in pipes and well under --help. The habit you build here in Phase 4 is the same habit Year 5’s mlship is judged on.

2.5 Packaging + distribution (just enough)

Modern Python packaging is pyproject.toml + a build backend (hatch, pdm, poetry). PyPI vs TestPyPI for first ships.

Investigate:

  • pyproject.toml minimum for a publishable package
  • Why TestPyPI before PyPI?

3. TRADE-OFFS (small)

DecisionOption AOption BCost
CLI frameworktyper (modern, type-hinted)click (mature, widely-used)Either fine; typer is friendlier
Schema validationpydantic v2jsonschemaboth
Async styleasynciotriostructured concurrency (anyio)
Packaginghatchpdmpoetry

4. TOOLS (as of 2025-10)

  • Python 3.12+
  • uv — fast package manager (replaces pip + venv for most things)
  • ruff — linter + formatter (replaces black + flake8 + isort)
  • pytest — test runner
  • hypothesis — property-based testing
  • typer + rich — CLI
  • pydantic v2 — validation
  • httpx — HTTP client (sync + async)

5. MASTERY

5.1 Reading list

RequiredWhy
”Fluent Python” (Ramalho, 2nd ed.) Ch. 1-9 (data model, functions)The book
pydantic v2 docs (Models + Validators)Validation depth
RecommendedWhy
Real Python’s asyncio guideWhen you reach the concurrency check

5.2 Operational depth checklist

[ ] Set up uv + a fresh project (pyproject.toml + src layout)
[ ] Write a tiny CLI with typer + rich; install in editable mode
[ ] Add pytest; aim for 70%+ coverage on rxp
[ ] Use ruff + format-check in CI
[ ] Publish to TestPyPI; verify install on a clean machine
[ ] Build a small async URL fetcher; benchmark vs sync
[ ] Add hypothesis tests for one core function (property-based)
[ ] Configure GitHub Actions: ruff + pytest on PR
[ ] Tag a v0.1.0 release; verify changelog + installable
[ ] Read one well-known small Python project (httpx, typer source) for 1 hour; note 3 patterns

The “read someone else’s source for 1 hour” item is the one that compounds across the rest of the program. Year 3 you’ll read PySpark’s executor code. Year 4 you’ll read Ray’s autoscaler. Year 5 you’ll read LangGraph’s state machine. The habit of reading production Python without flinching is the actual fluency outcome.

5.3 Project: rxp

A regex CLI: build, test, debug regular expressions. Doubles as a real log-parsing tool.

Terminal window
rxp test '\b[A-Z][a-z]+\b' "Hello World, Foo Bar"
# → highlights matches, shows positions, capture groups
rxp explain '\b\d{3}-\d{4}\b'
# → English description: "matches phone-number-like XXX-XXXX at word boundaries"
rxp stream # read stdin, highlight matches inline

rxp deliverables:

  • typer CLI (test, explain, stream)
  • 70%+ pytest coverage
  • README + 10 examples
  • TestPyPI publish
  • GitHub Actions CI on PR
  • Tagged release
  • Quiet ship. Push to GitHub + TestPyPI. No blog post, no LinkedIn announcement. The discipline is shipping; launch energy is reserved for mlship in Year 5.

rxp reappears in Year 5 as a dependency of services/aiops/, where the agent uses it to extract structured data from log lines. That integration is the reason the explain command exists — humans use test, agents use explain to reason about a regex they didn’t write themselves.

See projects/rxp/plan for the full spec.

5.4 Stretch project: konfig

If you have time after rxp ships:

Terminal window
konfig validate config.yaml --schema schema.json
konfig generate-schema example.yaml > schema.json

Same shape: typer + pydantic + jsonschema. Same quiet-ship discipline. Used in Year 2+ to validate basecamp Helm values in CI.

See projects/konfig/plan.


6. COMPARE: Python vs Bash for a small ops tool

You could write a regex-CLI as a bash one-liner with grep -P. When would Bash win? When does Python earn its weight?

300 words, in ops-handbook/.

The honest cutoff is roughly: if it’s one pipe and you’ll throw it away by tomorrow, Bash wins. If it has subcommands, types, tests, or will be installed elsewhere, Python earns its weight. Articulating the threshold in your own words is the actual exercise — knowing when not to reach for Python is as much fluency as knowing when to reach for it.


7. OPERATE

  • 1-2 small runbooks (Python venv troubleshooting, “my package won’t install”)
  • Weekly log

8. CONTRIBUTE

Approachable: typer docs, pydantic docs, ruff false-positive reports, any small Python tool you use.


Validation criteria

[ ] All 10 operational depth checks
[ ] `rxp` shipped to TestPyPI + GitHub
[ ] (Stretch) `konfig` shipped to TestPyPI + GitHub
[ ] Python vs Bash comparison written up
[ ] 1-2 runbooks; 5+ weekly log entries
[ ] Patterns touched (not necessarily deepened):
- text processing as a primitive (referenced by Year 5 aiops)
- schema validation as discipline (referenced by Year 2 basecamp CI)
[ ] Exit Test passed

Exit Test

Time: 2 hours.

  1. Build (60 min) — write a small Python CLI from scratch: lograg that takes a log file + a regex, prints matches with line numbers, exits 0 if matches found, 1 if not. With tests + types + ruff clean.
  2. Articulate (60 min) — 600 words: “When would I reach for rxp vs grep -P vs awk? What’s the cost of each?”

Anti-patterns

Anti-patternWhy
Trying to learn every Python idiom in 5 weeksFluency, not mastery. You’ll deepen as you operate ML/data tools in Years 3-5
Using requirements.txt instead of pyproject.tomlModern Python is pyproject.toml; old patterns are tech debt
Skipping typesTypes catch bugs you’d otherwise pay for at 3am
Loud-launching rxp (blog, LinkedIn)Year 1 is quiet ship; loud launch is for mlship

Patterns touched this phase

  • Text processing — light touch (deepens via Year 5 aiops)
  • Schema validation — light touch (used in Year 2 basecamp CI)

→ Next: Phase 5: Go + Concurrency