db371560bc
To enforce the 100 character line limit in markdown files introduced in https://github.com/astral-sh/uv/pull/5635, and to automate the formatting of markdown files, i've added prettier and formatted our markdown files with it. I've excluded the changelog and the generated references documentation from this for having too many changes, but we can also include them. I'm not particular on which style we use. My main motivations are (major) not having to reflow markdown files myself anymore and (minor) consistence between all markdown files. I've chosen prettier for similar reason as we chose black, it's a single good style that's automated and shared in the community. I do prefer prettier's style of not breaking inside of a link name though. This PR is in two parts, the first adds prettier to CI and documents using it, while the second actually formats the docs. When merge conflicts arise, we can drop the last commit and regenerate it with `npx prettier --prose-wrap always --write BENCHMARKS.md CONTRIBUTING.md README.md STYLE.md docs/*.md docs/concepts/**/*.md docs/guides/**/*.md docs/pip/**/*.md`. --------- Co-authored-by: Zanie Blue <contact@zanie.dev>
196 lines
5.5 KiB
Markdown
196 lines
5.5 KiB
Markdown
# Running scripts
|
|
|
|
A Python script is a file intended for standalone execution, e.g., with `python <script>.py`. Using
|
|
uv to execute scripts will ensure that script dependencies are properly managed inside and outside
|
|
of projects.
|
|
|
|
## Running a script without dependencies
|
|
|
|
If your script has no dependencies, you can execute it with `uv run`:
|
|
|
|
```python title="example.py"
|
|
print("Hello world")
|
|
```
|
|
|
|
```console
|
|
$ uv run example.py
|
|
Hello world
|
|
```
|
|
|
|
<!-- 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:
|
|
|
|
```python title="example.py"
|
|
import os
|
|
|
|
print(os.path.expanduser("~"))
|
|
```
|
|
|
|
```console
|
|
$ uv run example.py
|
|
/Users/astral
|
|
```
|
|
|
|
Arguments may be provided to the script:
|
|
|
|
```python title="example.py"
|
|
import sys
|
|
|
|
print(" ".join(sys.argv[1:]))
|
|
```
|
|
|
|
```console
|
|
$ uv run example.py test
|
|
test
|
|
|
|
$ uv run example.py hello world!
|
|
hello world!
|
|
```
|
|
|
|
Note that if you use `uv run` in a _project_, i.e. a directory with a `pyproject.toml`, it will
|
|
install the current project before running the script. If your script does not depend on the
|
|
project, use the `--no-project` flag to skip this:
|
|
|
|
```console
|
|
# Note, it is important that the flag comes _before_ the script
|
|
$ uv run --no-project example.py
|
|
```
|
|
|
|
See the [projects guide](./projects.md) for more details on working in projects.
|
|
|
|
## Running a script with dependencies
|
|
|
|
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.
|
|
|
|
For example, the following script requires `rich`.
|
|
|
|
```python title="example.py"
|
|
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
|
|
$ uv run --no-project example.py
|
|
Traceback (most recent call last):
|
|
File "/Users/astral/example.py", line 2, in <module>
|
|
from rich.progress import track
|
|
ModuleNotFoundError: No module named 'rich'
|
|
```
|
|
|
|
Request the dependency using the `--with` option:
|
|
|
|
```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:
|
|
|
|
```console
|
|
$ uv run --with 'rich>12,<13' example.py
|
|
```
|
|
|
|
Multiple dependencies can be requested by repeating with `--with` option.
|
|
|
|
Note that if `uv run` is used in a _project_, these dependencies will be included _in addition_ to
|
|
the project's dependencies. To opt-out of this behavior, use the `--no-project` flag.
|
|
|
|
## Declaring script dependencies
|
|
|
|
Python recently added a standard format for
|
|
[inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata).
|
|
This allows the dependencies for a script to be declared in the script itself.
|
|
|
|
To use inline script metadata, include a `script` section at the top of the script and declare the
|
|
dependencies using TOML:
|
|
|
|
```python title="example.py"
|
|
# /// 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')
|
|
]
|
|
```
|
|
|
|
uv also supports Python version requirements:
|
|
|
|
```python title="example.py"
|
|
# /// script
|
|
# requires-python = ">=3.12"
|
|
# dependencies = []
|
|
# ///
|
|
|
|
# Use some syntax added in Python 3.12
|
|
type Point = tuple[float, float]
|
|
print(Point)
|
|
```
|
|
|
|
uv will fetch the required Python version if it is not installed — see the documentation on
|
|
[Python versions](../concepts/python-versions.md) for more details. Note that the `dependencies`
|
|
field must be provided even if empty.
|
|
|
|
Note that when using inline script metadata, even if `uv run` is used in a _project_, the project's
|
|
dependencies will be ignored. The `--no-project` flag is not required.
|
|
|
|
## Using different Python versions
|
|
|
|
uv allows arbitrary Python versions to be requested on each script invocation, for example:
|
|
|
|
```python title="example.py"
|
|
import sys
|
|
|
|
print(".".join(map(str, sys.version_info[:3])))
|
|
```
|
|
|
|
```console
|
|
# Use the default Python version, may differ on your machine
|
|
$ uv run example.py
|
|
3.12.1
|
|
```
|
|
|
|
```console
|
|
# Use a specific Python version
|
|
$ uv run --python 3.10 example.py
|
|
3.10.13
|
|
```
|
|
|
|
See the [Python version request](../concepts/python-versions.md#requesting-a-version) documentation
|
|
for more details on requesting Python versions.
|