2025-01-16 04:12:55 +08:00
---
title: Running scripts
description:
A guide to using uv to run Python scripts, including support for inline dependency metadata,
reproducible scripts, and more.
---
2024-07-15 17:59:39 -04:00
# Running scripts
2024-07-30 18:17:58 -04:00
A Python script is a file intended for standalone execution, e.g., with `python <script>.py` . Using
2024-08-03 08:41:33 -05:00
uv to execute scripts ensures that script dependencies are managed without manually managing
environments.
!!! note
If you are not familiar with Python environments: every Python installation has an environment
that packages can be installed in. Typically, creating [_virtual_ environments ](https://docs.python.org/3/library/venv.html ) is recommended to
isolate packages required by each script. uv automatically manages virtual environments for you
and prefers a [declarative ](#declaring-script-dependencies ) approach to dependencies.
2024-07-15 17:59:39 -04:00
## Running a script without dependencies
2024-07-22 13:15:11 -04:00
If your script has no dependencies, you can execute it with `uv run` :
2024-07-15 17:59:39 -04:00
2024-07-23 14:29:59 -04:00
```python title="example.py"
2024-07-15 17:59:39 -04:00
print("Hello world")
` ``
` ``console
$ uv run example.py
Hello world
` ``
2024-07-22 13:15:11 -04:00
<!-- TODO(zanieb): Once we have a ` python` shim, note you can execute it with ` python` here -->
Similarly, if your script depends on a module in the standard library, there's nothing more to do:
2024-07-15 17:59:39 -04:00
2024-07-25 21:23:22 +07:00
` ``python title="example.py"
2024-07-15 17:59:39 -04:00
import os
print(os.path.expanduser("~"))
` ``
` ``console
$ uv run example.py
/Users/astral
` ``
2024-07-22 13:15:11 -04:00
Arguments may be provided to the script:
2024-07-15 17:59:39 -04:00
2024-07-23 14:29:59 -04:00
` ``python title="example.py"
2024-07-15 17:59:39 -04:00
import sys
print(" ".join(sys.argv[1:]))
` ``
` ``console
$ uv run example.py test
test
$ uv run example.py hello world!
hello world!
` ``
2024-08-23 12:18:49 -04:00
Additionally, your script can be read directly from stdin:
2024-08-24 01:03:59 -04:00
` ``console
$ echo 'print("hello world!")' | uv run -
` ``
Or, if your shell supports [here-documents](https://en.wikipedia.org/wiki/Here_document):
2024-08-23 12:18:49 -04:00
` ``bash
uv run - <<EOF
print("hello world!")
EOF
` ``
2025-03-13 16:42:10 -07:00
Note that if you use ` uv run` in a _project_, i.e., a directory with a ` pyproject.toml`, it will
2024-07-30 18:17:58 -04:00
install the current project before running the script. If your script does not depend on the
2024-07-30 18:40:38 -04:00
project, use the ` --no-project` flag to skip this:
2024-07-15 17:59:39 -04:00
` ``console
2025-01-06 13:41:44 -05:00
$ # Note: the ` --no-project` flag must be provided _before_ the script name.
2024-07-30 18:40:38 -04:00
$ uv run --no-project example.py
2024-07-15 17:59:39 -04:00
` ``
2024-07-22 13:15:11 -04:00
See the [projects guide](./projects.md) for more details on working in projects.
2024-07-15 17:59:39 -04:00
## Running a script with dependencies
2024-07-30 18:17:58 -04:00
When your script requires other packages, they must be installed into the environment that the
script runs in. uv prefers to create these environments on-demand instead of using a long-lived
virtual environment with manually managed dependencies. This requires explicit declaration of
dependencies that are required for the script. Generally, it's recommended to use a
[project](./projects.md) or [inline metadata](#declaring-script-dependencies) to declare
dependencies, but uv supports requesting dependencies per invocation as well.
2024-07-15 17:59:39 -04:00
For example, the following script requires ` rich`.
2024-07-23 14:29:59 -04:00
` ``python title="example.py"
2024-07-15 17:59:39 -04:00
import time
from rich.progress import track
for i in track(range(20), description="For example:"):
time.sleep(0.05)
` ``
If executed without specifying a dependency, this script will fail:
` ``console
2024-07-30 18:40:38 -04:00
$ uv run --no-project example.py
2024-07-15 17:59:39 -04:00
Traceback (most recent call last):
File "/Users/astral/example.py", line 2, in <module>
from rich.progress import track
ModuleNotFoundError: No module named 'rich'
` ``
2024-07-22 13:15:11 -04:00
Request the dependency using the ` --with` option:
2024-07-15 17:59:39 -04:00
` ``console
$ uv run --with rich example.py
For example: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:01
` ``
Constraints can be added to the requested dependency if specific versions are needed:
2024-07-25 21:23:22 +07:00
` ``console
2024-07-15 17:59:39 -04:00
$ uv run --with 'rich>12,<13' example.py
` ``
Multiple dependencies can be requested by repeating with ` --with` option.
2024-07-30 18:17:58 -04:00
Note that if ` uv run` is used in a _project_, these dependencies will be included _in addition_ to
2024-07-30 18:40:38 -04:00
the project's dependencies. To opt-out of this behavior, use the ` --no-project` flag.
2024-07-15 17:59:39 -04:00
2024-09-25 15:48:01 -07:00
## Creating a Python script
2024-07-15 17:59:39 -04:00
2024-08-02 15:58:31 +02:00
Python recently added a standard format for
[inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata).
2024-09-25 15:48:01 -07:00
It allows for selecting Python versions and defining dependencies. Use ` uv init --script` to
initialize scripts with the inline metadata:
` ``console
$ uv init --script example.py --python 3.12
` ``
## Declaring script dependencies
The inline metadata format allows the dependencies for a script to be declared in the script itself.
2024-07-15 17:59:39 -04:00
2024-08-19 17:47:17 -05:00
uv supports adding and updating inline script metadata for you. Use ` uv add --script` to declare the
dependencies for the script:
` ``console
$ uv add --script example.py 'requests<3' 'rich'
` ``
This will add a ` script` section at the top of the script declaring the dependencies using TOML:
2024-07-15 17:59:39 -04:00
2024-07-23 14:29:59 -04:00
` ``python title="example.py"
2024-07-15 17:59:39 -04:00
# /// script
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
` ``
uv will automatically create an environment with the dependencies necessary to run the script, e.g.:
` ``console
$ uv run example.py
[
│ ('1', 'PEP Purpose and Guidelines'),
│ ('2', 'Procedure for Adding New Modules'),
│ ('3', 'Guidelines for Handling Bug Reports'),
│ ('4', 'Deprecation of Standard Modules'),
│ ('5', 'Guidelines for Language Evolution'),
│ ('6', 'Bug Fix Releases'),
│ ('7', 'Style Guide for C Code'),
│ ('8', 'Style Guide for Python Code'),
│ ('9', 'Sample Plaintext PEP Template'),
│ ('10', 'Voting Guidelines')
]
` ``
2024-08-03 08:41:33 -05:00
!!! important
2024-11-19 13:52:12 -06:00
When using inline script metadata, even if ` uv run` is [used in a _project_](../concepts/projects/run.md), the project's dependencies will be ignored. The ` --no-project` flag is not required.
2024-08-03 08:41:33 -05:00
uv also respects Python version requirements:
2024-07-15 17:59:39 -04:00
2024-07-23 14:29:59 -04:00
` ``python title="example.py"
2024-07-15 17:59:39 -04:00
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
# Use some syntax added in Python 3.12
type Point = tuple[float, float]
print(Point)
` ``
2024-08-03 08:41:33 -05:00
!!! note
2024-07-15 17:59:39 -04:00
2024-08-03 08:41:33 -05:00
The ` dependencies` field must be provided even if empty.
` uv run` will search for and use the required Python version. The Python version will download if it
is not installed — see the documentation on [Python versions](../concepts/python-versions.md) for
more details.
2024-07-15 17:59:39 -04:00
2025-04-16 17:20:27 +02:00
## Using a shebang to create an executable file
A shebang can be added to make a script executable without using ` uv run` — this makes it easy to
run scripts that are on your ` PATH` or in the current folder.
For example, create a file called ` greet` with the following contents
` ``python title="greet"
#!/usr/bin/env -S uv run --script
print("Hello, world!")
` ``
Ensure that your script is executable, e.g., with ` chmod +x greet`, then run the script:
` ``console
$ ./greet
Hello, world!
` ``
Declaration of dependencies is also supported in this context, for example:
` ``python title="example"
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx"]
# ///
import httpx
print(httpx.get("https://example.com"))
` ``
2025-02-12 13:52:22 +00:00
## Using alternative package indexes
2025-06-05 12:09:49 -05:00
If you wish to use an alternative [package index](../concepts/indexes.md) to resolve dependencies,
you can provide the index with the ` --index` option:
2025-02-12 13:52:22 +00:00
` ``console
$ uv add --index "https://example.com/simple" --script example.py 'requests<3' 'rich'
` ``
This will include the package data in the inline metadata:
` ``python
# [[tool.uv.index]]
# url = "https://example.com/simple"
` ``
If you require authentication to access the package index, then please refer to the
2025-06-05 12:09:49 -05:00
[package index](../concepts/indexes.md) documentation.
2025-02-12 13:52:22 +00:00
2025-01-08 19:33:55 -05:00
## Locking dependencies
uv supports locking dependencies for PEP 723 scripts using the ` uv.lock` file format. Unlike with
projects, scripts must be explicitly locked using ` uv lock`:
` ``console
$ uv lock --script example.py
` ``
Running ` uv lock --script` will create a ` .lock` file adjacent to the script (e.g.,
` example.py.lock`).
Once locked, subsequent operations like ` uv run --script`, ` uv add --script`, ` uv export --script`,
and ` uv tree --script` will reuse the locked dependencies, updating the lockfile if necessary.
If no such lockfile is present, commands like ` uv export --script` will still function as expected,
but will not create a lockfile.
2024-08-29 13:44:47 -07:00
## Improving reproducibility
2025-01-08 19:33:55 -05:00
In addition to locking dependencies, uv supports an ` exclude-newer` field in the ` tool.uv` section
of inline script metadata to limit uv to only considering distributions released before a specific
date. This is useful for improving the reproducibility of your script when run at a later point in
time.
2024-08-29 13:44:47 -07:00
The date must be specified as an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamp
(e.g., ` 2006-12-02T02:07:43Z`).
` ``python title="example.py"
# /// script
# dependencies = [
# "requests",
# ]
# [tool.uv]
# exclude-newer = "2023-10-16T00:00:00Z"
# ///
import requests
print(requests.__version__)
` ``
2024-07-15 17:59:39 -04:00
## Using different Python versions
uv allows arbitrary Python versions to be requested on each script invocation, for example:
2024-07-23 14:29:59 -04:00
` ``python title="example.py"
2024-07-15 17:59:39 -04:00
import sys
print(".".join(map(str, sys.version_info[:3])))
` ``
` ``console
2024-08-03 08:41:33 -05:00
$ # Use the default Python version, may differ on your machine
2024-07-15 17:59:39 -04:00
$ uv run example.py
2024-10-07 12:38:12 -05:00
3.12.6
2024-07-15 17:59:39 -04:00
` ``
` ``console
2024-08-03 08:41:33 -05:00
$ # Use a specific Python version
2024-07-15 17:59:39 -04:00
$ uv run --python 3.10 example.py
2024-10-07 12:38:12 -05:00
3.10.15
2024-07-15 17:59:39 -04:00
` ``
2024-07-30 18:17:58 -04:00
See the [Python version request](../concepts/python-versions.md#requesting-a-version) documentation
for more details on requesting Python versions.
2024-08-03 08:41:33 -05:00
2024-08-22 20:44:37 -04:00
## Using GUI scripts
On Windows ` uv` will run your script ending with ` .pyw` extension using ` pythonw`:
` ``python title="example.pyw"
from tkinter import Tk, ttk
root = Tk()
root.title("uv")
frm = ttk.Frame(root, padding=10)
frm.grid()
ttk.Label(frm, text="Hello World").grid(column=0, row=0)
root.mainloop()
` ``
` ``console
PS> uv run example.pyw
` ``
{: style="height:50px;width:150px"}
Similarly, it works with dependencies as well:
` ``python title="example_pyqt.pyw"
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QGridLayout
app = QApplication(sys.argv)
widget = QWidget()
grid = QGridLayout()
text_label = QLabel()
text_label.setText("Hello World!")
grid.addWidget(text_label)
widget.setLayout(grid)
widget.setGeometry(100, 100, 200, 50)
widget.setWindowTitle("uv")
widget.show()
sys.exit(app.exec_())
` ``
` ``console
PS> uv run --with PyQt5 example_pyqt.pyw
` ``
{: style="height:50px;width:150px"}
2024-08-03 08:41:33 -05:00
## Next steps
To learn more about ` uv run`, see the [command reference ](../reference/cli.md#uv-run ).
2024-08-05 16:12:37 -05:00
Or, read on to learn how to [run and install tools ](./tools.md ) with uv.