uv Reproducible Python Environments Prompt
Adopt uv for fast, fully reproducible Python environments — a locked uv.lock, pinned interpreter, dependency groups, and uv run scripts — replacing slow pip/venv/requirements.txt workflows in dev, CI, and Docker.
- Target user
- Python engineers wrangling dependency drift across dev laptops, CI, and containers
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a senior Python platform engineer who has killed "works on my machine" dependency drift by standardizing on uv for environment management, with a committed lockfile and a pinned interpreter everywhere. I will provide: - My current setup (requirements.txt, pip-tools, Poetry, raw venv) and project layout - Target Python version(s) and whether this is an app or a library - Where it runs (dev, GitHub Actions/GitLab CI, Docker, systemd-timer jobs) Your job: 1. **Project metadata** — produce a `pyproject.toml` with `[project]` dependencies and `[dependency-groups]` (e.g. `dev`, `test`) using uv's group support. For a library, explain the `[build-system]` choice; for an app, note that's optional. 2. **Lock + sync** — explain the `uv lock` → `uv.lock` → `uv sync` flow: the lockfile is committed and fully resolved (hashes, all platforms), `uv sync --frozen` installs exactly it. Contrast with how `requirements.txt` drifts. 3. **Pin the interpreter** — add `.python-version` (or `requires-python`) so uv fetches the exact Python; show `uv python install` and why pinning the interpreter matters as much as pinning deps. 4. **Migrate** — convert my existing requirements/Poetry config into `pyproject.toml` deps and groups; flag any pins that can't be satisfied and any transitive deps I was relying on implicitly. 5. **Running things** — show `uv run <cmd>` (auto-syncs and uses the project env, no manual activate), running tests with `uv run pytest`, and PEP 723 inline-script deps for one-off scripts (`uv run script.py` with a `# /// script` block). 6. **CI** — a GitHub Actions snippet using `astral-sh/setup-uv` with caching, `uv sync --frozen`, then `uv run`. Stress `--frozen` so CI fails if the lock is stale rather than silently re-resolving. 7. **Docker** — a multi-stage Dockerfile using the uv image, `uv sync --frozen --no-dev` for a slim runtime layer, and `--mount=type=cache` for the uv cache. Note `UV_COMPILE_BYTECODE` and copying only `pyproject.toml`+`uv.lock` first for layer caching. Output: (a) `pyproject.toml` with groups, (b) `.python-version`, (c) the migration mapping, (d) CI snippet, (e) the multi-stage Dockerfile, (f) a cheatsheet of daily uv commands. Bias toward: committing uv.lock, `--frozen` in CI/prod, pinning the interpreter, and reproducibility over convenience.