Python Development Workflow with uv#

uv is the newest tool taking the Python world by storm — it helps simplify the management of multiple Python versions, virtual environments, and package installation.

If you’re new to Python, we recommend following our “normal” Python Development Workflow first.

Step 1: Install uv#

Open a terminal and run the following command to download and install:

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

Alternatively, download and unzip the binary from: https://github.com/astral-sh/uv/releases.

Additional installation methods are documented here: https://docs.astral.sh/uv/.

Step 2: Create a project directory#

Creating a dedicated directory (commonly called a folder) is a good starting point. This is often called your project folder, project directory, project dir, or project root.

We recommend storing all of your code in central directory, called “Source”, within your home directory. In this guide, we’ll refer to ~/Source/. We’ll also refer to your project as myproject.

If you’re working on a project with a git repo, start by cloning that repo:

% cd ~/Source
% git clone <myproject-url>

If you’re starting a new project, create a new directory and initialize an empty git repo.

% cd ~/Source
% mkdir myproject
% cd myproject
% git init .

Step 3: Create a virtual environment#

Python projects require installing additional 3rd-party packages, such as Django. However, this creates a problem — what if two different projects need two different versions of a package? You’d then have to uninstall and reinstall every time you switched between the projects, which could cause a lot of problems.

Python includes a solution: “virtual environments”, referred to as venv. A venv is simply a folder which contains a separate copy of Python and all the installed packages. This way, each project won’t interfere with any others on your machine.

uv completely handles virtual environments for you behind the scenes. Simply specify the version of Python you want, and uv will download and install it.

% cd ~/Source/myproject
% uv venv --python 3.13

Step 4: Running Python commands with uv#

Since uv manages the Python environment for you, you’ll need to always invoke any Python commands by using uv run <command>. For example, to run the Python interpreter:

% cd ~/Source/myproject
% uv run python
>>> exit()

Step 5: Manage pip packages#

To install packages, it is necessary to keep a list of all the packages required by this project. The file containing this list is named requirements.txt. If you’re working on a new project, go ahead and create or edit the requirements.txt file in your project directory. In this example, let’s install Django version 5.1.

# Inside the requirements.txt file.
django==5.1.*

Here’s an explanation of what the special syntax means:

  • django is the name of the package.

  • == means to install a version equal to…

  • 5.1.* means any version matching 5.1. Django frequently releases security patches, such as 5.1.1, 5.1.2, 5.1.3, etc. These patches are guaranteed to be backwards compatible, so you usually want the latest to automatically be installed, hence the *.

Follow this same process for every package you need.

Now that you have a requirements.txt, install it using uv as so:

% uv pip install -r requirements.txt

Step 6: Improve quality with developer tools#

“Linters”, which are tools that check your code for errors, can drastically help improve the quality of your code, and are essential for producing professional software.

Since these tools are only used by humans writing code, and are not used in the production web server, we will separate them into a requirements-dev.txt file, as so:

# Inside requirements-dev.txt file.

# First, install project requirements.
-r requirements.txt

# Now, install developer tools.
ruff

In this file, we are first installing everything from the main requirements.txt, then installing one additional tool: ruff. Ruff can format your Python code and also check for errors.

Now, let’s install, then run ruff:

% uv pip install -r requirements-dev.txt
% uv run ruff check --fix
% uv run ruff format

You might see that ruff reformatted your code, or is telling you to fix some errors. Run this every time you make changes to your code.

Step 7: Django & Wagtail specific instructions#

At this point, your Python environment is all set up and working. However, Django & Wagtail projects usually need a MySQL or PostgreSQL database. To get that working in your development environment, need to follow one of these guides:

Finally, every time you make a change to a model in your Django or Wagtail project, you should be sure to create and run migrations. Migrations synchronize those changes in your Django models with your database.

% uv manage.py makemigrations
% uv python manage.py migrate

Step 8: Git commit#

If you’re using git, you’ll want to follow our Git Workflow. However, this is your reminder to commit and push any changes before logging off for the day!

Note

Never commit your .venv folder to git. This is because it is specific to your machine, and won’t work on other people’s machines. It is also very large and will slow down your git repository.

If running git status shows files from the .venv folder, then you’ll want to create or edit a file named .gitignore in your project directory. Copy the contents of this file into your .gitignore: https://www.toptal.com/developers/gitignore/api/django.