1. Defining Python dependencies at the top of the file

Essentially, we can now put a special comment block at the top of the file, before our import statements like this:

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "flickrapi",
# ]
# ///

The Python version is optional and we could specify a specific version constraint on each package should we wish to.

Now, when we run with uv, uv will ensure that the flickrapi package is installed for us.

$ uv run sync-flickr-dates.py
Reading inline script metadata from: sync-flickr-dates.py
Installed 10 packages in 13ms
usage: sync-flickr-dates.py [-h] photo_ids

In this case, uv will create a Python 3.12 venv for us. For me this is in ~/.cache/uv (which you can find via uv cache dir).

2. uv shebang for those files

As ~/bin is on my path, I want to run the script by calling it directly on the command line. To do this, I use this shebang:

#!/usr/bin/env -S uv run --script

The command line will now run uv run --script and pass the file as the argument. uv ignores the shebang and then runs the rest of the file as a normal Python file.

Once I’ve ensured that that script has executable permissions via chmod a+x {filname}, I’m now good to go with simple command line scripts written in Python that automatically handle their dependencies!