uv & PEP 723 Scripts

PEP 723 defines inline script metadata, allowing Python scripts to declare their dependencies directly in the file. Combined with uv, this enables zero-setup script execution.

Why PEP 723 + uv?

  • No virtual environment setup - Dependencies resolved and cached automatically

  • Single-file distribution - Share scripts without requirements.txt

  • Reproducible execution - Pinned Python version and dependencies

  • Instant execution - uv caches dependencies globally

Script Template

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
#     "requests>=2.28",
#     "click>=8.0",
# ]
# ///
"""
tool-name - Brief description of what this tool does

Usage:
    tool-name [options] <args>

Examples:
    tool-name --verbose input.txt
    tool-name --format json data.csv
"""

import sys
import click

@click.command()
@click.argument('input_file')
@click.option('--verbose', '-v', is_flag=True)
def main(input_file, verbose):
    """Process input file."""
    if verbose:
        click.echo(f"Processing: {input_file}")
    # ... implementation ...

if __name__ == "__main__":
    main()

Shebang Explained

#!/usr/bin/env -S uv run --script
  • #!/usr/bin/env - Portable interpreter lookup

  • -S - Pass the rest as arguments to the found program

  • uv run --script - Execute with uv, reading inline metadata

Metadata Block

The metadata block must appear at the top of the file (after shebang/encoding):

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

Supported Fields

Field Description

requires-python

Python version constraint (e.g., >=3.11, >=3.10,<3.13)

dependencies

List of package specifications with optional version constraints

Running Scripts

Direct Execution (with shebang)

chmod +x script.py
./script.py args

Explicit uv Invocation

uv run --script script.py args

Installation

Global Availability

Symlink to a directory in your PATH:

ln -s /path/to/domus-python/bin/tool ~/.local/bin/tool

PATH Setup

Ensure ~/.local/bin is in your PATH (add to ~/.zshrc or ~/.bashrc):

export PATH="$HOME/.local/bin:$PATH"

Dependencies

Install uv if not already available:

  • Arch

  • pip

  • Standalone

sudo pacman -S uv
pip install uv
curl -LsSf https://astral.sh/uv/install.sh | sh