UV: Python’s fast package and project management tool
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.
- It is 10-100x faster than pip.
- It provides comprehensive project management, with a universal lockfile.
- Runs scripts, with support for inline dependency metadata.
There are many more features that it provides. Please read UV Highlights for more details.
If you are interested in watching the video. Here is the YouTube video on the same step by step procedure outlined below.
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..
Leave a Reply
You must be logged in to post a comment.