Python Environments & Dependencies
Making every run reproducible
Environment and dependency management is the most common source of 'it worked on my machine'. venv, pip pinning and lockfiles make AI services reproducible end to end.
What you will learn
- Create and activate isolated Python environments
- Pin dependencies with lockfiles and audit them for known vulnerabilities
- Reproduce a service environment from scratch deterministically
What is this?
A Python environment is the combination of interpreter, packages and versions your code runs under. `venv` isolates an interpreter per project so versions can't conflict. Production AI work adds lockfiles that pin the transitive dependency graph, so a fresh checkout runs byte-for-byte the same pipeline as CI.
Why do you need it?
- Unpinned dependencies mean your Monday morning code runs a different library than your Friday code.
- Model SDKs release frequently; a background 'pip install --upgrade' can silently change tokenization or API behavior.
- Security: lockfiles + audits catch vulnerable versions of transitive deps before they ship.
- Reproducibility is required for evals — a changed dependency can make a golden test pass or fail without touching your code.
Mental model
An airline's loaded manifest
A pinned dependency environment
A plane doesn't take off without a manifest of exactly what's on board, checked before every flight. Your AI service shouldn't either: an exact list of what versions exist and why.
How it works
- `python -m venv .venv` creates an isolated folder with its own interpreter and pip.
- `pip install -r requirements.txt` installs direct requirements; a lockfile also pins every transitive dependency.
- Tools like uv or poetry generate and maintain the lockfile deterministically.
- The lockfile is committed; deploy and CI install from it, not from a loose spec.
- `pip-audit` or `pip install --dry-run` surfaces known-vulnerable versions periodically.
From loose requirements to reproducible environment.
In production
- A RAG pipeline pins the embedding SDK, the vector client and the eval framework in one lockfile so offline evals replicate production behavior.
- A deploy pipeline runs `pip install -r requirements.lock` inside a container, then `pip-audit` fails the build on a known CVE in a transitive dependency.
- A team keeps a requirements.in of seven top-level deps while the lockfile manages hundreds of pinned transitive packages.
Best practices
- Commit the lockfile and install from it everywhere, including local dev.
- Review dependency upgrades explicitly; never `pip install --upgrade` blindly.
- Use separate environments for dev vs CI to catch 'not installed in prod' bugs early.
- Audit dependencies for CVEs in CI, at least on every tagged release.
Common mistakes
- Freezing packages with `pip freeze > requirements.txt` which includes environment-specific junk and misses hashes.
- Forgetting to activate the venv before running a script, so import resolves to the global site-packages.
- Two requirements files that drift apart (dev vs prod) until a bug lands only in prod.
- Pinning model SDK versions in docs but not in code.
Common issues
pip install fails with a dependency conflictTwo packages require incompatible versions of a shared dependency
Use a resolver (uv/poetry/pip-tools) that can pick compatible versions, or bump one top-level dep.
Code works locally but the API returns a 400 from the model provider in prodProd installed an older/newer SDK than local; request format differs
Install from the same lockfile everywhere and pin the exact SDK version.
pip-audit fails CI on a transitive packageA vulnerable numpy/urllib3 pulled in by an indirect dependency
Upgrade the top-level dependency that pulls it in, or pin a fixed transitively-resolved version.
Debugging tips
- 'Works locally, fails in prod' — diff the lockfiles and the interpreter versions first.
- When a model call changes behavior, check the SDK changelog and installed version.
- Print `pip list` in CI to prove what actually installed, then compare to your pinned set.
- If imports resolve to the wrong package, check for a same-named local file shadowing site-packages.
Interview checkpoint
Hands-on lab
- Create a venv and install pinned dependencies
- Generate a lockfile from a small requirements.in
- Rebuild the environment from scratch and prove it works
Reproduce an Environment from a Lockfile
20 min · beginner
Quick quiz
What is the main purpose of a lockfile?
A pinned environment is optional for production AI services.