Standalone PEP 723 scripts with Conda dependencies in Pixi

manzt1 pts0 comments

Standalone Scripts - Pixi

Skip to content

Initializing search

GitHub

Tutorials

Pytorch Installation

ROS 2

Rust

Switching From...

Multi Environment

Global Tools

Import Environments

Concepts

Building

Dependency Types

Workspace Dependencies

Build Backends

Key Concepts

Package Source

Inline Package Definitions

Dev Packages

Distributing

Integration

Continuous Integration

Extensions

Third Party

Advanced

Reference

Misc

Standalone Python scripts#

Pixi can give a single Python file its own environment. Dependencies and<br>configuration live in a PEP 723 inline metadata<br>block,<br>while the resolved environment stays in Pixi's cache instead of a workspace<br>next to the script.

Script commands use --script . The same init, run, add, remove,<br>and lock commands used for workspaces can therefore operate on either a<br>manifest or a standalone file.

Make a script self-contained#

This script downloads the USGS earthquake feed with httpx, then uses GDAL's<br>Python bindings to count the features:

earthquakes.pyimport httpx<br>from osgeo import ogr

ogr.UseExceptions()

response = httpx.get(<br>"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson"<br>dataset = ogr.Open(response.text)<br>print(f"{dataset.GetLayer().GetFeatureCount()} earthquakes in the past hour")

Initialize the metadata, add GDAL from Conda, add httpx from PyPI, and run<br>the file:

pixi init --script earthquakes.py --channel conda-forge<br>pixi add --script earthquakes.py gdal<br>pixi add --script earthquakes.py --pypi httpx<br>pixi run --script earthquakes.py<br>6 earthquakes in the past hour

Pixi preserves the Python source and writes the metadata into the file:

earthquakes.py# /// script<br># requires-python = ">=3.11"<br># dependencies = ["httpx"]<br># [tool.pixi.workspace]<br># channels = ["conda-forge"]<br># [tool.pixi.dependencies]<br># gdal = "*"<br># ///

The script now describes both sides of its environment. It can be copied<br>without a separate pixi.toml, pyproject.toml, or lock file.

Portable and Pixi-specific metadata#

PEP 723 defines two portable fields:

requires-python selects a compatible Python version.

dependencies lists packages installed from PyPI.

Pixi reads those fields and extends them with a focused subset of<br>tool.pixi:

tool.pixi.workspace configures channels, platforms, and resolver options.

tool.pixi.dependencies lists Conda packages.

tool.pixi.pypi-dependencies represents PyPI requirements that need<br>Pixi-specific fields, such as an index or editable installation.

tool.pixi.target. holds platform-specific dependencies,<br>constraints, and activation settings.

Other PEP 723 tools can use the portable fields and ignore tool.pixi. In the<br>example above, another tool can install httpx, but only Pixi also provides<br>GDAL. Pixi preserves metadata under other tool.* tables when editing a<br>script.

An explicit tool.pixi.dependencies.python requirement takes precedence over<br>requires-python when both are present.

Manage dependencies#

Use --pypi to choose PyPI. Without it, add and remove operate on Conda<br>dependencies:

pixi add --script earthquakes.py gdal<br>pixi add --script earthquakes.py --pypi "httpx>=0.28"<br>pixi remove --script earthquakes.py gdal<br>pixi remove --script earthquakes.py --pypi httpx

Requirements that standard PEP 723 can express remain in dependencies.<br>Richer requirements are written under tool.pixi:

# Add a dependency only for a declared platform.<br>pixi add --script analysis.py --platform linux-64 libblas

# Preserve a dependency-specific package index.<br>pixi add --script analysis.py --pypi \<br>--index https://pypi.example.com/simple "internal-api>=2"

# Install a local Python project in editable mode.<br>pixi add --script analysis.py --pypi --editable \<br>"analysis-tools @ ./analysis-tools"

Relative paths in metadata are resolved from the script's directory.

When no adjacent lock file exists, dependency mutations solve for validation<br>but write only the inline metadata. If a sidecar lock already exists, it is<br>updated as part of the mutation.

Run the script#

pixi run --script creates or reuses the cached environment, then invokes the<br>file with its declared Python and dependencies:

pixi run --script earthquakes.py

run also accepts a direct HTTP or HTTPS URL, including URLs without a<br>.py suffix:

pixi run --script https://example.com/earthquakes.py<br>pixi run --script https://gist.github.com/user/gist-id

Remote scripts must already contain a PEP 723 metadata block. They are fetched<br>on every invocation and executed from a secure temporary .py file, while<br>their environment is reused from Pixi's cache. Relative paths in remote<br>metadata resolve from the directory where Pixi was invoked.

Remote inputs are execution-only: commands that edit, inspect, export, or lock<br>a script continue to require a local path. A remote script has no adjacent lock<br>file, so it cannot be run with --locked or --frozen.

For a normal GitHub Gist page, Pixi selects the first filename ending in<br>.py, case-insensitively, or the first file when the Gist contains...

pixi script earthquakes dependencies pypi tool

Related Articles