UV: Python’s fast package and project management tool

UV: Python’s fast package and project management tool

python_uv_package_and_project_manager

Here in this article we will try to understand about UV a modern and fast python package and project management tool.

Test Environment

  • Fedora 41 server
  • Python3

What is UV

UV is extremely fast Python package and project manager, written in Rust.

  1. It is 10-100x faster than pip.
  2. It provides comprehensive project management, with a universal lockfile.
  3. Runs scripts, with support for inline dependency metadata.

There are many more features that it provides. Please read UV Highlights for more details.

Procedure

Step1: Install uv package

As a first step we will install uv available as an rpm package within fedora os.

admin@linuxser:~$ sudo dnf install uv

Verify the uv version that is installed.

admin@linuxser:~$ uv --version
uv 0.9.7

Step2: Verify installed Python version

By default fedora os comes a default python package installed. We can check if uv is able to detect the installed python package listing the available python versions.

admin@linuxser:~$ uv python list
cpython-3.13.9-linux-x86_64-gnu    /usr/bin/python3.13
cpython-3.13.9-linux-x86_64-gnu    /usr/bin/python3 -> python3.13
cpython-3.13.9-linux-x86_64-gnu    /usr/bin/python -> ./python3

Let say you want to install or use a specifiv version of python package, We can do so using the uv package manager tool by installing that specific version of python.

admin@linuxser:~$ uv python install python3.12
Installed Python 3.12.12 in 10.49s
 + cpython-3.12.12-linux-x86_64-gnu (python3.12)

Now if we look at the list of python versions insatlled, you will notice that python3.12 is installed but available locally within userspace rather than globally.

admin@linuxser:~$ uv python list
cpython-3.13.9-linux-x86_64-gnu     /usr/bin/python3.13
cpython-3.13.9-linux-x86_64-gnu     /usr/bin/python3 -> python3.13
cpython-3.13.9-linux-x86_64-gnu     /usr/bin/python -> ./python3
cpython-3.12.12-linux-x86_64-gnu    .local/bin/python3.12 -> .local/share/uv/python/cpython-3.12.12-linux-x86_64-gnu/bin/python3.12
cpython-3.12.12-linux-x86_64-gnu    .local/share/uv/python/cpython-3.12.12-linux-x86_64-gnu/bin/python3.12

If you want your python project to use a specific version of python we can pin that version using uv as shown below. It will create a .python-version file with the project directory.

admin@linuxser:~$ uv python pin python3.12
Pinned `.python-version` to `3.12`

admin@linuxser:~$ ls -ltr .python-version 
-rw-r--r--. 1 admin admin 5 Jul  5 21:51 .python-version
admin@linuxser:~$ cat .python-version 
3.12

Just delete .python-version if you want to unpin that specific version. Also uninstall is fully if its no longer required.

admin@linuxser:~$ rm -f .python-version

admin@linuxser:~$ uv python uninstall python3.12
Searching for Python versions matching: Python 3.12
Uninstalled Python 3.12.12 in 113ms
 - cpython-3.12.12-linux-x86_64-gnu (python3.12)

Step3: Initialize a Python project

Let’s now initialize a python project using “uv init” and switch to the project folder which is created with a default template.

admin@linuxser:~$ uv init uvdemo
Initialized project `uvdemo` at `/home/admin/uvdemo

admin@linuxser:~$ cd uvdemo/
admin@linuxser:~/uvdemo$ ls -ahl
total 16K
drwxr-xr-x. 1 admin admin  118 Jul  5 22:07 .
drwx------. 1 admin admin 1.5K Jul  5 22:07 ..
drwxr-xr-x. 1 admin admin   82 Jul  5 22:07 .git
-rw-r--r--. 1 admin admin  109 Jul  5 22:07 .gitignore
-rw-r--r--. 1 admin admin   84 Jul  5 22:07 main.py
-rw-r--r--. 1 admin admin  152 Jul  5 22:07 pyproject.toml
-rw-r--r--. 1 admin admin    5 Jul  5 22:07 .python-version
-rw-r--r--. 1 admin admin    0 Jul  5 22:07 README.md

Step4: Add Project specific dependency

Here we are going to install “requests” package using “uv add“. This command basically add the package dependency specific to your project by creating a virtual environment and installing it in that environment.

admin@linuxser:~/uvdemo$ uv add requests
Using CPython 3.13.9 interpreter at: /usr/bin/python3.13
Creating virtual environment at: .venv
Resolved 6 packages in 205ms
Prepared 5 packages in 100ms
Installed 5 packages in 5ms
 + certifi==2026.6.17
 + charset-normalizer==3.4.7
 + idna==3.18
 + requests==2.34.2
 + urllib3==2.7.0

Also it updates the dependency that was installed to the pyproject.toml file as shown below.

admin@linuxser:~/uvdemo$ cat pyproject.toml 
[project]
name = "uvdemo"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "requests>=2.34.2",
]

If you now list the files in the current project directory you will also notice a uv.lock.

A uv.lock file is a highly detailed, automatically generated snapshot of all exact dependencies in a Python project. Used by the uv package manager, it records the precise version numbers and cryptographic hashes of every direct and transitive (sub-dependency) package.

Let’s now add another project dependency “ruff” which an extremely fast, open-source code linter and formatter designed specifically for Python ecosystems.

admin@linuxser:~/uvdemo$ uv add ruff
Resolved 7 packages in 232ms
Prepared 1 package in 2.89s
Installed 1 package in 7ms
 + ruff==0.15.20

Step5: Ensure project locked and synced

admin@linuxser:~/uvdemo$ uv lock
Resolved 7 packages in 0.85ms
admin@linuxser:~/uvdemo$ uv sync
Resolved 7 packages in 0.88ms
Audited 6 packages in 0.11ms

Step5: Update script

Here we are going to update the main.py to use requests module to send a http request a web page and print its results.

admin@linuxser:~/uvdemo$ cat main.py 
import requests

def main():
    print("Hello from uvdemo!")
    print(requests.get("https://astral.sh"))'


if __name__ == "__main__":
    main()

Validate our project by running ruff to verify if any errors or issues.

admin@linuxser:~/uvdemo$ uvx ruff check
invalid-syntax: missing closing quote in string literal
 --> main.py:5:45
  |
3 | def main():
4 |     print("Hello from uvdemo!")
5 |     print(requests.get("https://astral.sh"))'
  |                                             ^
  |

Found 1 error.

Correct the script and removing the “‘” on 5th line and revalidate.

admin@linuxser:~/uvdemo$ uvx ruff check
All checks passed!

Step6: Run python project

Now that we have validated the project using ruff, let’s try to run our project as shown below.

admin@linuxser:~/uvdemo$ uv run main.py 
Hello from uvdemo!
<Response [200]>

Step7: Build Python package

Now let’s try to package our project into a distribution that can be published.

admin@linuxser:~/uvdemo$ uv build
...
removing build/bdist.linux-x86_64/wheel
Successfully built dist/uvdemo-0.1.0.tar.gz
Successfully built dist/uvdemo-0.1.0-py3-none-any.whl

Hope you enjoyed reading this article. Thank you..