Production Python for AI teams
Tooling, reproducibility, and habits that separate a demo from a dependable system.
Why it matters: Interviewers probe process because that is what breaks in production: pins, seeds, tests, and logged configs.
Basics
The toolchain
Core tools:
- ruff - lint and format
- mypy - type checks
- pytest - tests
- uv or poetry - lockfiles
Add pre-commit so checks run before review. Keep config in pyproject.toml so editor, CLI, and CI agree.
Tiny example
Print a few pinned dependency lines.
pins = ["numpy==2.1.0", "pandas==2.2.3", "pytest==8.3.0"]
for p in pins:
print(p)Basics
Reproducibility
Pin dependencies. Seed Python, NumPy, and the ML framework. Version data (or at least hash it). Log config per run: hyperparams, data version, git commit.
For LLM systems also log prompt version, model version, and temperature.
Tiny example
Seed NumPy and print the same sample twice.
import numpy as np
rng = np.random.default_rng(42)
print(rng.integers(0, 10, size=5))Basics
Measure before you optimize
Profile first. Usual wins: vectorize, batch API/GPU calls, then cache. Concurrency comes after.
Prefer generators over giant lists. Prefer float32 over float64 for model arrays.
Tiny example
Time a tiny loop with perf_counter.
import time
start = time.perf_counter()
total = sum(i * i for i in range(10_000))
print(total, "ms", round((time.perf_counter() - start) * 1000, 3))Then AI / ML
AI / ML examples
Same idea, used in real AI work. Press Try in lab to run it.
AI / ML example
AI / ML: seed for a reproducible run
Same seed, same random draws.
In AI / ML: Training and eval scripts set seeds before shuffling data.
example.py
Python
import os
import random
import numpy as np
def set_seed(seed=42):
os.environ["PYTHONHASHSEED"] = str(seed)
random.seed(seed)
np.random.seed(seed)
set_seed(42)
a = [random.random(), float(np.random.rand())]
set_seed(42)
b = [random.random(), float(np.random.rand())]
print([round(v, 6) for v in a])
print([round(v, 6) for v in b])
print("same:", a == b)AI / ML example 2
AI / ML: experiment manifest
Log config, data fingerprint, and metrics together.
In AI / ML: MLflow and W&B store the same idea at larger scale.
example.py
Python
import json
import hashlib
rows = [{"text": "a", "label": 1}, {"text": "b", "label": 0}]
fp = hashlib.sha256(json.dumps(rows, sort_keys=True).encode()).hexdigest()[:12]
manifest = {
"run_id": "exp-01",
"config": {"model": "bert-base", "lr": 2e-5, "seed": 42},
"data": {"n": len(rows), "fingerprint": fp},
"metrics": {"accuracy": 0.913},
}
print(json.dumps(manifest, indent=2))Takeaways
- 1ruff, mypy, pytest, and a lockfile cover most quality basics.
- 2Reproducibility needs pins, seeds, versioned data, and logged config.
- 3Measure first; vectorize and batch before rewriting for speed.