How to Manage Python Projects with uv
In the Crud-In-The-Cloud monorepo, we use uv by Astral to manage Python environments and dependencies. uv is an extremely fast Python package installer and resolver written in Rust, designed to replace pip, pip-tools, and virtualenv.
Why uv?
- Speed: It resolves and installs dependencies in milliseconds compared to seconds or minutes with traditional tools.
- Simplicity: It combines the features of
pipandvirtualenvinto a single binary. - Determinism: It uses a lockfile system (
uv.lock) similar to Poetry or npm, ensuring everyone on the team has the exact same dependency tree.
Working in a Monorepo
Since we have multiple independent Python applications (django-app, fastapi-app, mkdocs-app) in the same repository, each app maintains its own pyproject.toml, uv.lock, and isolated virtual environment (.venv).
1. Initial Setup (Syncing)
To install or update the dependencies of an app based on its uv.lock file, navigate to the app's directory and run uv sync. This command automatically creates the .venv if it doesn't exist.
Note: You do not need to manually run python -m venv .venv or source .venv/bin/activate. uv handles the environment seamlessly.
2. Adding Packages
To add a new dependency to a specific project, use uv add. This updates the pyproject.toml and regenerates the lockfile.
3. Running Commands
Instead of activating the virtual environment manually, prefix your commands with uv run. This ensures the command executes within the context of the app's isolated .venv.
Troubleshooting
- "uv command not found": Ensure
uvis installed globally on your system (e.g., viabrew install uvon macOS or curl). - Dependency Conflicts: If you encounter resolution errors, you can regenerate the lockfile cleanly by deleting
uv.lockand runninguv lockfollowed byuv sync.