Python Package Management with uv
Introduction
Yesterday (a bunch of updates to uv, their Python package/project manager, written in Rust. I've been using uv for the past month or two, mostly as a very fast drop-in replacement for venv and pip.
), Astral releasedThe new release expands uv into "an end-to-end solution for managing Python projects, command-line tools, single-file scripts, and even Python itself."
This post will very briefly explore the workflow I am most interested in—setting up an environment, installing packages, and specifying requirements.
Projects
I've been exploring FastHTML over the past few days. Let's use uv to set up a project which I can use for my FastHTML experiments. I'll start by navigating to the directory I've already been working from.
cd ~/projects/fhtml_ex/
and then we'll initialize the project:
uv init
This created a pyproject.toml
:
cat pyproject.toml
[project] name = "fhtml-ex" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.12" dependencies = [] [build-system] requires = ["hatchling"] build-backend = "hatchling.build"
Now let's add FastHTML to the project.
uv add python-fasthtml
Using Python 3.12.4 interpreter at: /opt/homebrew/opt/python@3.12/bin/python3.12 Creating virtualenv at: .venv Resolved 30 packages in 408ms Prepared 29 packages in 1.03s Installed 29 packages in 25ms + anyio==4.4.0 + beautifulsoup4==4.12.3 + certifi==2024.7.4 + click==8.1.7 + fastcore==1.7.1 + fastlite==0.0.9 + fhtml-ex==0.1.0 (from file:///Users/dliden/projects/fhtml_ex) + h11==0.14.0 + httpcore==1.0.5 + httptools==0.6.1 + httpx==0.27.0 + idna==3.7 + itsdangerous==2.2.0 + oauthlib==3.2.2 + packaging==24.1 + python-dateutil==2.9.0.post0 + python-dotenv==1.0.1 + python-fasthtml==0.4.4 + python-multipart==0.0.9 + pyyaml==6.0.2 + six==1.16.0 + sniffio==1.3.1 + soupsieve==2.6 + sqlite-minutils==3.37.0.post1 + starlette==0.38.2 + uvicorn==0.30.6 + uvloop==0.20.0 + watchfiles==0.23.0 + websockets==13.0
Now the project has a virtual environment and a lockfile.
We can use uv to run a command in the project's environment without explicitly activating the environment. It will very quickly lock and sync the project, making sure it is up to date. For example, without explicitly activating the environment, we can do:
uv run ./todo/app.py
and get:
Link: http://localhost:5001 INFO: Will watch for changes in these directories: ['/Users/dliden/projects/fhtml_ex/todo'] INFO: Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit) INFO: Started reloader process [7719] using WatchFiles INFO: Started server process [7721] INFO: Waiting for application startup. INFO: Application startup complete.
See the documentation for more details.