python uv - ghdrako/doc_snipets GitHub Wiki
- https://docs.astral.sh/uv/
- https://emily.space/posts/251023-uv
- https://news.ycombinator.com/item?id=45751400
- https://github.com/astral-sh/uv
Install
# On macOS and Linux.
curl -LsSf https://astral.sh/uv/install.sh | sh
# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Update
$ uv self update
Initializing a new project
$ uv init explore-uv
$ cd explore-uv
$ tree -a
.
├── .gitignore
├── .python-version
├── README.md
├── hello.py
└── pyproject.toml
Git is automatically initialized and main git-related files like .gitignore and an empty README.md are generated. .python-version file contains the Python version used for the project, while pyproject.toml serves as the main configuration file for project metadata and dependencies.
Using uv in existing project
navigate to the project directory and run the following command
$ uv init
This command will create the uv project structure for you. It won’t overwrite the main.py file if you have one, but it’ll create the file if it’s missing. It neither modifies your Git repository nor your README.md file.
However, this command won’t work if you already have a pyproject.toml file in place.
Adding initial dependencies to the project
$ uv add scikit-learn xgboost
The first time you run the add command, UV creates a new virtual environment in the current working directory and installs the specified dependencies. On subsequent runs, UV will reuse the existing virtual environment and only install or update the newly requested packages, ensuring efficient dependency management.
UV uses a modern dependency resolver that analyzes the entire dependency graph to find a compatible set of package versions that satisfy all requirements. The resolver considers factors like version constraints, Python version compatibility, and platform-specific requirements to determine the optimal set of packages to install.
UV also updates the pyproject.toml and uv.lock files after each add command.
$ cat pyproject.toml
[project]
name = "explore-uv"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
"scikit-learn>=1.5.2",
"xgboost>=2.0.3",
]
upgrade a dependency
$ uv add --upgrade requests
remove a dependency
$ uv remove scikit-learn
remove a dependency from the environment and the pyproject.toml file
development dependency
If project doesn’t need library to run, you can install it as a development dependency
$ uv add --dev pytest
list dependency
$ uv pip list
$ uv lock
$ uv sync
Running Python scripts with UV
$ uv run hello.py
The run command ensures that the script is executed inside the virtual environment UV created for the project.
Managing Python Versions in UV
Listing existing Python versions
$ uv python list --only-installed
UV can discover existing installations by default.
Changing Python versions for the current project
$vi .python-version
...
requires-python = ">=3.9"
$ uv sync
The command first checks against existing Python installations. If the requested version isn't found, UV downloads and installs it inside the /Users/username/.local/share/uv/python path. UV also creates a new virtual environment inside the project directory, replacing the old one.
This new environment doesn't have the dependencies listed in your pyproject.toml file, so you have to install them with the following command:
$ uv pip install -e .
UV tools
Some Python packages are exposed as command-line tools. UV provides two special interfaces to manage these packages:
- Using uv tool run:
$ uv tool run black hello.py
- Using the shorter and more convenient uvx command:
$ uvx black hello.py
When these commands are run, UV creates a temporary virtual environment in its cache. The requested tool is installed and run from there. In other words, you can use command-line tools without installing them in the project's virtual environment, resulting in faster execution and cleaner project dependencies.
Perfect for occasional use of development tools.
Lock Files in UV
ock files (uv.lock) are an essential part of dependency management in UV.The lock file should be committed to version control to ensure all developers use the same dependency versions.
You can maintain both files by using UV's lock file for development while generating a requirements.txt for deployment. To generate a requirements.txt from a UV lock file, use the following command:
$ uv export -o requirements.txt
Dependency Management With UV
- Installing the latest version of a package:
$ uv add requests
- Installing a specific version:
$ uv add requests=2.1.2
- Change the bounds of a package's constraints:
$ uv add 'requests<3.0.0'
- Make a dependency platform-specific:
$ uv add 'requests; sys_platform="linux"'
Adding optional dependencies
Optional dependencies are packages that are not required for the core functionality of your project but may be needed for specific features. For example, Pandas has an excel extra and a plot extra to avoid the installation of Excel parsers and matplotlib unless someone explicitly requires them. Optionals are usually installed with the pip install pandas[plot, excel] syntax.
$ uv add pandas # install core package
$ uv add pandas --optional plot excel
Dependency groups
Dependency groups allow you to organize your dependencies into logical groups, such as development dependencies, test dependencies, or documentation dependencies. This is useful for keeping your production dependencies separate from your development dependencies.
To add a dependency to a specific group, use the --group flag:
$ uv add --group group_name package_name
Then, users will be able to control which groups to install using the --group, --only-group, and --no-group tags.
| pip/virtualenv command | UV equivalent |
|---|---|
| python -m venv .venv | uv venv |
| pip install package | uv add package |
| pip install -r requirements.txt | uv pip install -r requirements.txt |
| pip uninstall package | uv remove package |
| pip freeze | uv pip freeze |
| pip list | uv pip list |
Building and Publishing Packages
Configuring the Project
[project]
name = "rpcats"
version = "0.1.0"
description = "Display cat information for the specified breed."
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"requests>=2.32.3",
]
[dependency-groups]
dev = [
"pytest>=8.3.5",
]
[project.scripts]
rpcats = "main:main"
With these two additional last lines, you ensure that when someone installs your app, they can run the rpcats command from their terminal to execute the code from the main() function, which is stored in the main.py file.
define a build system
...
[project.scripts]
rpcats = "main:main"
[build-system]
requires = ["setuptools>=78.1.0", "wheel>=0.45.1"]
build-backend = "setuptools.build_meta"
Building a Distribution
$ uv build
You also have the following build options:
uv build --sdistuv build --wheel
The first command builds a source distribution only, while the second command builds a binary distribution. Note that using uv build without any flags will build both the source and binary distributions.
Publishing a Distribution
...
[build-system]
requires = ["setuptools>=78.1.0", "wheel>=0.45.1"]
build-backend = "setuptools.build_meta"
[tool.uv.index](/ghdrako/doc_snipets/wiki/tool.uv.index)
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true
you can use uv publish with the --index option to upload your app to TestPyPI:
$ uv publish --index testpypi --token your_token_here
To run this command, you’ll need to add your personal API token for TestPyPI following the --token option. Once you’ve entered all the information, press Enter to upload the app to TestPyPI.