How to write self-contained Python scripts using PEP 723 inline metadata
Prerequisites
- uv installed on your system
- Basic knowledge of Python scripting
Step 1: Create a simple script
First, create a basic Python script that requires external dependencies:
# github_stats.py
import requests
def get_repo_stats(repo):
url = f"https://api.github.com/repos/{repo}"
response = requests.get(url)
data = response.json()
return data
if __name__ == "__main__":
repo = "astral-sh/uv"
stats = get_repo_stats(repo)
print(f"Repository: {stats['full_name']}")
print(f"Stars: {stats['stargazers_count']}")
print(f"Forks: {stats['forks_count']}")
print(f"Open Issues: {stats['open_issues_count']}")Tip
To scaffold a new script with the PEP 723 block already filled in, run uv init --script github_stats.py --python 3.12. The Add dependencies step still applies.
Step 2: Add dependencies using uv
Instead of manually editing the script to add metadata, use uv’s built-in command:
uv add --script github_stats.py --python="3.9" requestsThis adds the required inline metadata to your script:
# /// script
# requires-python = ">=3.9"
# dependencies = [
# "requests",
# ]
# ///
import requests
# rest of script...Step 3: Run the script with uv
Now run your script using uv:
uv run github_stats.pyWhen you run this command, uv will:
- Read the inline metadata
- Create a temporary virtual environment
- Install the specified dependencies
- Execute your script in this environment
Step 4: Make your script executable (Unix systems)
To run your script directly without typing uv run, add a shebang line and make it executable:
# Edit your script to add this as the first line
#!/usr/bin/env -S uv run --script
# Then make it executable
chmod +x github_stats.pyNow you can run the script directly:
./github_stats.pyThe -S flag tells env to split the string that follows it into separate arguments. Without it, the kernel treats uv run --script as a single program name and fails with No such file or directory, because the Linux execve syscall only accepts one optional argument after the interpreter path. -S is standard on macOS (BSD env) and on Linux with GNU coreutils 8.30 (2018) or newer.
Running with pdm
Inline metadata is a Python standard defined in PEP 723, and can also be used with other tools like PDM (pdm run github_stats.py), Hatch (hatch run github_stats.py), and pip (pipx run github_stats.py).