How to Create a Python Virtual Environment with uv

15 minute read     Updated:

Furqan Butt %
Furqan Butt

Imagine you have a Python 3.10 backend application with packages a2.1, b2.2, and c2.3 installed system-wide. Everything works fine until you start a new project that also uses Python 3.10 but needs a1.2, b2.2, and c2.1. Installing these new packages causes dependency issues with your first project because a2.1 and c2.3 are no longer available. If you start a third project requiring Python 3.8, you would need to downgrade Python, causing further conflicts.

Virtual environments solve these problems by isolating dependencies for each project, allowing you to maintain different packages and Python versions without conflict. A virtual environment is an independent environment created on top of an existing Python installation. It has its own independent set of Python packages installed in its site directories and only contains packages from its base environment (the system-wide Python installation) if explicitly specified. The environment is disposable and can be easily deleted and recreated as required.

In this tutorial, you’ll learn how to set up and use virtual environments using uv, a package installer that’s easy to use and performs 10 to 100 times better than pip.

Installing uv

To create a virtual environment with uv, you need to start by installing it. There are multiple ways to do so, depending on your device. If you’re using Linux or Mac, you can run the following command to install uv:

curl -LsSf https://astral.sh/uv/install.sh | sh 

On Mac, you also have the option to install uv via Homebrew:

brew install uv

On Windows, you can run the following:

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Or you can install uv with pip:

pip install uv

After installation, verify uv on your device by running the following command:

uv --version

You will get an output like this:

uv 0.1.44

The rest of this tutorial assumes you’re operating on a Linux or Mac operating system.

Creating a Project and a Virtual Environment Using uv

Once uv is installed, you need to create a project and install the necessary dependencies:

mkdir my_uv_project

Then, change into this directory via cd my_uv_project.

Creating a virtual environment for your project is fairly simple. Run the following command:

uv venv my_env

You should get a similar output to this:


user@guest-MacBook-Air my_uv_project % uv venv my_env
Using Python 3.9.6 interpreter at: /Library/Developer/CommandLineTools/usr/bin/python3
Creating virtualenv at: my_env
Activate with: source my_env/bin/activate

You can see that a Python 3.9 environment has been created.

Activating Your Environment

Once you’ve created your virtual environment, you need to activate it by running the following command:

source my_env/bin/activate

To verify that the environment you created doesn’t contain any packages, run the following command:

uv pip list

Your output will not list anything, and any packages or dependencies you install in this environment will be isolated from the rest of the system.

Note: If you’re using a different shell than Bash, such as cmd, you’ll have different activate scripts, such as my_envScriptsactivate.bat.

Installing Packages in Your Environment

Once you’ve activated your environment, it’s time to install some packages. First, install pandas with the following command:

uv pip install pandas

You’ll get an output similar to this:


(my_env) user@guest-MacBook-Air my_uv_project % uv pip install pandas
Resolved 6 packages in 143ms
Installed 6 packages in 76ms
 + numpy==1.26.4
 + pandas==2.2.2
 + python-dateutil==2.9.0.post0
 + pytz==2024.1
 + six==1.16.0

As you can see, pandas version 2.2.2 has been installed. When you install pandas, other supporting packages are also installed.

Verify your package installation by running the following command:

uv pip list

You’ll get an output similar to this:


(my_env) user@guest-MacBook-Air my_uv_project % uv pip list
Package         Version
--------------- -----------
numpy           1.26.4
pandas          2.2.2
python-dateutil 2.9.0.post0
pytz            2024.1
six             1.16.0
tzdata          2024.1

Creating a Second Virtual Environment

To test the isolation of environments, you’ll create a second environment and install a different version of pandas with another package. To do so, perform the same steps as above to create a virtual environment named my_second_env:


user@guest-MacBook-Air my_uv_project % uv venv my_second_env     
Using Python 3.9.6 interpreter at: /Library/Developer/CommandLineTools/usr/bin/python3
Creating virtualenv at: my_second_env
Activate with: source my_second_env/bin/activate

Next, install Flask and pandas version 2.1.0 by running this command:

my_uv_project % uv pip install pandas==2.1.0 flask

Upon installation, you’ll get an output similar to this:


(my_second_env) user@guest-MacBook-Air my_uv_project % uv pip install pandas==2.1.0 flask
Resolved 15 packages in 195ms
Downloaded 2 packages in 4.48s
Installed 15 packages in 93ms
 + blinker==1.8.2
 + click==8.1.7
 + flask==3.0.3
 + importlib-metadata==7.1.0
 + itsdangerous==2.2.0
 + jinja2==3.1.4
 + markupsafe==2.1.5
 + numpy==1.26.4
 + pandas==2.1.0
 + python-dateutil==2.9.0.post0
 + pytz==2024.1
 + six==1.16.0
 + tzdata==2024.1
 + werkzeug==3.0.3
 + zipp==3.19.1

As you can see, it does not contain the pandas package version 2.2.2 that you installed in the my_env virtual environment.

Creating a Virtual Environment with a Different Python Version

You can also create a virtual environment with a different Python version. The earlier environments you created had Python 3.9. Let’s now create one that has Python 3.11. To do so, execute the following command:

uv venv 3rd_env --python 3.11

You’ll get a similar output to this:


Using Python 3.11.5 interpreter at: /Library/Developer/CommandLineTools/usr/bin/python3.11
Creating virtualenv at: 3rd_env
Activate with: source 3rd_env/bin/activate

You can once again install pandas here:


user@guest-MacBook-Air my_uv_project % source 3rd_env/bin/activate
(3rd_env) user@guest-MacBook-Air my_uv_project % uv pip install pandas            
Resolved 6 packages in 215ms
Downloaded 2 packages in 2.59s
Installed 6 packages in 72ms
 + numpy==1.26.4
 + pandas==2.2.2
 + python-dateutil==2.9.0.post0
 + pytz==2024.1
 + six==1.16.0
 + tzdata==2024.1

Switching between Virtual Environments and Removing a Virtual Environment

To switch between different virtual environments, you can deactivate the first one by running this command:

deactivate

Follow it by running this command:

source my_second_env/bin/activate

If you now run the ls command in your project directory, you’ll see all the environments listed:

user@guest-MacBook-Air my_uv_project % ls 
3rd_env        my_env        my_second_env

As you can see, these environments are created like regular directories under your project. If you want to remove one, you can delete the environment folder like this:

rm -rf my_second_env

This will delete the second environment you created.

Overcoming the Limitations of uv

Limitations

While uv can act as a great replacement for pip, it only manages dependencies related to Python.

Let’s say your projects involve installing packages system-wide, meaning they affect all users and applications on the system. For instance, you may want to install the libpq-dev package for your PostgreSQL backend server. uv is not designed to manage such system-wide package installations.

Another limitation of uv is that it lacks containerization capabilities. It has no caching mechanism to help speed up the build process by reusing identical dependencies in different virtual environments. If you use multiple virtual environments for a single project (for example, to test the project in different Python versions), uv will install every dependency in each virtual environment, even if some of them are identical. This can be inefficient and take up a lot of space and time for a large project.

These limitations make it cumbersome for larger Python projects or those with many dependencies.

Earthly helps address these issues by simplifying the dependency management process, ensuring consistency across different environments, and streamlining the build and deployment process.

For instance, you can use Earthly to install your Python-related dependencies (like pandas) as usual. If you also need to install system-wide dependencies like libpq-dev, you can do so within the same environment.

Earthly is designed to work like a Docker container. It uses an Earthfile, which is very similar to a Dockerfile. You can add and install all your Python and system-wide dependencies in a single Earthfile, and your project is good to go.

It also offers fast build speed and supports caching, which reuses intermediate build steps when dependencies or code haven’t changed. Other notable features include dependency management, maintaining virtual environments, managing language-agnostic builds, and multiplatform deployments and CI/CD integrations.

Conclusion

In this article, you saw how to use virtual environments to help isolate development environments to avoid package-related issues and conflicts in Python with uv.

Even though uv works well for this use case, it has limitations. It only works for Python environments, so you can’t use it to install system-wide dependencies. It also doesn’t offer containerization capabilities.

If you need these features, consider Earthly, a simple build tool that helps you manage dependencies and maintain virtual environments. Similar to Docker containers, it offers many familiar features like containerization, caching and reusing builds, and installing dependencies that can span system-wide. It can easily manage large projects involving many dependencies and provides a great development experience.

Earthly Cloud: Consistent, Fast Builds, Any CI
Consistent, repeatable builds across all environments. Advanced caching for faster builds. Easy integration with any CI. 6,000 build minutes per month included.

Get Started Free

Furqan Butt %
Furqan Butt
Furqan is a software developer with more than three years of experience in the computer software industry. He's completed the AWS Certified Solutions Architect and Certified Cloud Practitioner certifications, writes on Medium for publications including Towards Data Science, and is part of the AWS Community Builders Program for data and analytics. His core expertise is in data engineering, big data, cloud technologies, and backend development.

Published:

Get notified about new articles!
We won't send you spam. Unsubscribe at any time.