I often finding myself writing one-off scripts to automate various parts of my day-to-day. You can see a few of them that have survived numerous refactors of my toolbox repo here. Python is my scripting language of choice, and until recently, I’d often find myself writing bash, to ensure that the script is portable, and easy to run.
Introducing PEP 723, a new feature that describes how meta-data can be written inside a Python script. Fortunately, my favorite package manager UV, are compliant with this PEP, which means it has made writing one-off Python scripts incredibly convenient. No more manually managing virtual environments or separate requirements.txt files your dependencies, as they now live right in your script.
The Old Way
Before PEP 723, running a simple script with external dependencies meant creating a virtual environment and managing a requirements file.
Let’s say I wanted a quick script to analyze some CSV data with pandas:
script.py
import pandas as pd
df = pd.read_csv("data.csv")
print(df.describe())
requirements.txt
pandas==3.0.2
To run this, I’d have to:
$ python -m venv venv
$ source venv/bin/activate
$ pip install -r requirements.txt
$ python script.py
$ deactivate
That’s a lot of steps for a simple script. Multiple files to manage.
The New Way
With PEP 723 and UV, the same script now looks like this:
script.py:
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "pandas==3.2.0",
# ]
# ///
import pandas as pd
df = pd.read_csv("data.csv")
print(df.describe())
And that’s it. No separate files, no virtual environment to create. Just run:
$ uv run script.py
UV handles everything for us automatically. It reads the dependencies from the script comment block, creates an isolated environment, installs the packages, and runs our script. All in one command.
Conclusion
I now find myself writing my scripts in Python, which is much more comfortable. I figured I’d share this incase it helps anyone else out ;)