Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
The r2x CLI is the orchestrator for the
r2x ecosystem. It
discovers installed Python plugins, chains them into pipelines,
and manages Python environments, all from a single Rust binary.
Plugins handle every step of a power systems translation workflow: parsing source models, applying transforms, translating between formats, and exporting to targets like PLEXOS or Sienna. The CLI finds them via static analysis (no Python import side effects), resolves their dependencies, and pipes each step's output into the next.
Installation
Download the latest binary from the releases page, or use the one-liner installers below.
macOS / Linux
|
Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/NatLabRockies/r2x-cli/releases/latest/download/r2x-installer.ps1 | iex"
Verify it works:
[!NOTE] On first run, R2X uses UV to provision its managed CPython runtime and creates the R2X virtual environment. It does not require
python3.12inPATHor~/.local/bin. UV owns the CPython installation; R2X owns only the plugin virtual environment, which references that interpreter. Useuv python listto inspect UV's available interpreters. Source builds select a supported version withPYO3_PYTHONfromuv python find --managed-pythonandR2X_PYTHON_VERSION.
Upgrading
If you installed via the shell/powershell installer, a standalone updater is included:
Alternatively, re-run the installer to get the latest version:
# macOS / Linux
|
Quick Start
# 1. Scaffold a pipeline config
# 2. Install a plugin from PyPI
# 3. See what got installed
# 4. Run a pipeline
r2x init creates a pipeline.yaml with example variables,
pipeline definitions, and per-plugin configuration. Edit it to
match your data and you are running translations in under a
minute.
Plugin Management
| Command | What it does |
|---|---|
r2x install <package> |
Install from PyPI |
r2x install gh:NatLabRockies/r2x-reeds |
Install from a GitHub repo |
r2x install gh:NatLabRockies/r2x-reeds --branch dev |
Install a specific branch (--tag, --commit) |
r2x install -e /path/to/plugin |
Install in editable mode for local dev |
r2x remove <package> |
Uninstall a plugin |
r2x list |
List all installed plugins |
r2x list r2x-reeds |
Filter by package name |
r2x list r2x-reeds break-gens |
Filter by package and module |
r2x sync |
Re-run plugin discovery and refresh manifest metadata |
r2x sync --upgrade |
Upgrade compatible installed plugins, then sync and show version/commit changes |
r2x clean -y |
Wipe the plugin manifest and clean cache |
[!TIP] Plugin discovery uses static analysis (ast-grep) instead of importing Python modules. This makes
r2x syncandr2x installfast and safe, with no side effects from plugin code.
Running Pipelines
Pipelines chain plugins together in a named sequence defined in a YAML file. See Pipeline File Format for the full spec. For ready-to-use translation examples across ReEDS, Sienna, and PLEXOS, see:
# List available pipelines
# Dry run (preview without executing)
# Execute
# Execute and save output
# Save a System and its time-series sidecars as an infrasys ZIP archive
Running Plugins Directly
Skip the pipeline and run a single plugin with inline arguments. The short form is r2x run <plugin-ref>; r2x run plugin <plugin-ref> remains supported.
# Run a plugin directly with idiomatic flags
# Existing key=value arguments also work
# Pipe a System through compatible plugins in one shell job
|
# Write a durable System JSON entrypoint and its adjacent sidecar directory
# Read the durable System by path; relative sidecars resolve beside the JSON file
# Debug an uncaught plugin exception in an interactive post-mortem PDB session
# Use --input FILE for a durable input so stdin remains available to PDB
# Debug the failing step in a pipeline
# Show a plugin's help
# Run repeated invocations and print timing summary
# Compare two benchmark outputs (baseline vs current)
# Emit machine-readable status line in stderr
# Fail when regression exceeds 15%
# In CI, set optional regression gate
# List all runnable plugins
Use --pdb only from an interactive terminal. It opens Python's post-mortem
pdb for uncaught plugin exceptions, including failures in a pipeline, and
returns the original plugin error after continue or quit. Debugger prompts
are written to stderr. Noninteractive or piped invocations fail immediately;
when debugging interactively, prefer --input FILE so stdin remains available
for PDB commands.
Without -o, System JSON on stdout embeds an absolute r2x sidecar location,
so it is safe to pass to the next command in the same shell job. With -o,
r2x creates parent directories, replaces the JSON entrypoint, and writes a
portable sibling <stem>_time_series/ directory; read that artifact with -i,
not shell redirection. Plugin diagnostics use stderr, and exporters write their
configured files without emitting a JSON record.
For Torc parameterization, file dependencies, and the distinction between live pipes and durable -o / -i boundaries, see Use r2x plugin streams in Torc.
Pipeline File Format
Pipeline configs are YAML with three sections: variables for
substitution values, pipelines for named plugin sequences, and
config for per-plugin settings.
variables:
output_dir: "output"
reeds_run: /path/to/reeds/run
solve_year: 2032
pipelines:
reeds-test:
- r2x-reeds.reeds-parser
- r2x-reeds.break-gens
reeds-to-plexos:
- r2x-reeds.reeds-parser
- r2x-reeds-to-plexos.reeds-to-plexos
- r2x-plexos.plexos-exporter
config:
r2x-reeds.reeds-parser:
weather_year: 2012
solve_year: ${solve_year}
path: ${reeds_run}
r2x-reeds.break-gens:
drop_capacity_threshold: 5
r2x-plexos.exporter:
output: ${output_dir}
output_folder: ${output_dir}
Variables use ${var} syntax and are substituted at runtime
across all config values and output_folder.
Interactive System Shell
Load a system JSON and drop into an IPython session for exploration:
# Load an infrasys ZIP archive
The session exposes sys (the loaded system), plugins
(installed plugins), and lazy-loaded pd, np, plt for
pandas, numpy, and matplotlib. Type %r2x_help for the full
list of magic commands.
# From stdin
|
# Run a script against the system
# Run a script then stay interactive
Configuration
# Show current config
# Set values
# Reset everything
R2X uses the Python major.minor ABI that its PyO3 runtime was built against.
Use uv python list and uv python install to inspect or manage interpreter
installations directly. A configured Python patch version must use that same
major.minor ABI.
The r2x python command manages R2X's UV-backed plugin environment:
# Create or refresh the managed venv with UV
# Show the R2X venv's Python configuration
# Get the Python executable path
# Create or recreate the managed venv
# Install packages into the managed venv
[!TIP] The
r2x pythoncommands are shortcuts forr2x config python <action>. Both work identically.
# Show current logging settings
# Keep Python/plugin stdout out of the log file by default
# Cap log file size (bytes)
# Show Python log messages on console by default
# Override log file location
# Print the resolved log file path
# Command help
[!NOTE] Configuration is stored in
~/.config/r2x/config.tomlon Unix-like systems or%APPDATA%\r2x\config.tomlon Windows. Override with theR2X_CONFIGenvironment variable.
Verbosity
| Flag | Effect |
|---|---|
-q |
Suppress informational logs |
-qq |
Suppress logs and plugin stdout |
-v |
Debug logging |
-vv |
Trace logging |
--log-python |
Show Python logs on console |
--no-stdout |
Do not capture plugin stdout in logs |
Persisted logging defaults can be set with r2x log set ....
Plugin installation and r2x sync --upgrade print an immediate phase status to
stderr and stream uv diagnostics there. uv's progress display is enabled only
for an interactive terminal; pipes, CI, NO_COLOR, and TERM=dumb receive
plain, line-oriented status instead. Use -q or -qq to suppress status and
uv informational output, and -v or -vv to pass diagnostic verbosity through to uv. stdin is
inherited, so private Git and SSH installs can still prompt for credentials.
Architecture
flowchart LR
CLI[r2x CLI] --> Config[r2x-config]
CLI --> Manifest[r2x-manifest]
CLI --> AST[r2x-ast]
CLI --> Python[r2x-python]
CLI --> Logger[r2x-logger]
AST -->|ast-grep| Discovery[Plugin Discovery]
Python -->|PyO3| Runtime[Python Runtime]
Manifest --> Plugins[(Plugin Registry)]
The workspace is split into six crates:
| Crate | Role |
|---|---|
r2x-cli |
CLI entry point, command routing, pipeline execution |
r2x-config |
Configuration management, paths, Python/venv settings |
r2x-manifest |
Plugin manifest read/write, package metadata |
r2x-ast |
AST-based plugin discovery via ast-grep |
r2x-python |
PyO3 bridge for running Python plugins |
r2x-logger |
Structured logging with tracing |
Ecosystem
The r2x ecosystem is a set of independently published packages.
The CLI orchestrates them; r2x-core provides the shared plugin
framework; model packages supply parsers, exporters, and data
models; and translation packages convert between formats.
| Package | Description |
|---|---|
| r2x-cli (this repo) | Rust CLI that discovers, installs, and runs any r2x plugin. Chains plugins into pipelines and manages Python environments |
| r2x-core | Shared plugin framework: PluginContext, Rule, System, @getter registry |
| R2X | Translation plugins: ReEDS to PLEXOS, Sienna to PLEXOS, and more |
| r2x-reeds | ReEDS parser, transform plugins, and component models |
| r2x-plexos | PLEXOS parser/exporter and component models |
| r2x-sienna | Sienna parser/exporter and PowerSystems.jl-compatible models |
| infrasys | Foundational System container, time series management, and component storage |
| plexosdb | Standalone PLEXOS XML database reader/writer |
Building from Source
Prerequisites
|
|
[!IMPORTANT] Restart your shell after installing rustup and uv so both are available in your PATH.
Build and install
&&
PYO3_PYTHON="" \
R2X_PYTHON_VERSION=3.12
To build against another supported Python version:
PYO3_PYTHON="" \
R2X_PYTHON_VERSION=3.13
Set PYO3_PYTHON from uv python find --managed-python so PyO3 builds
against the UV-managed interpreter. R2X passes the requested version directly
to UV. Install that exact version first with uv python install <version>.
This places r2x and its adjacent r2x-runtime payload in ~/.cargo/bin/.
Run r2x; keep both files together when moving the installation.
PYO3_PYTHON="" \
R2X_PYTHON_VERSION=3.12
The build produces target/release/r2x and target/release/r2x-runtime.
Copy them to the same directory, then invoke r2x.
The justfile also honors R2X_PYTHON_VERSION, for example
R2X_PYTHON_VERSION=3.13 just test.
R2X_PYTHON_VERSION selects the Python ABI for a source build. The installed
CLI accepts only the same major.minor ABI for r2x config set python-version;
a patch version such as 3.12.1 is allowed for a binary built against 3.12.
When R2X_PYTHON_VERSION is set for a just task, install that version first
with uv python install <version>. This avoids accidentally building PyO3
against a different Python ABI than the one requested.
If you also set PYO3_PYTHON manually, it must point to an interpreter with the
same major.minor ABI as R2X_PYTHON_VERSION.
The project uses a justfile for common tasks:
- If the build fails with a Python error, verify
R2X_PYTHON_VERSIONis set to a supported version (for example3.12,3.13, or3.13.1) anduv python find --managed-python <version>returns a valid path. You may needuv python install <version>first. - If
r2xis not found after install, check that~/.cargo/binis in your$PATH. - On HPC systems with older glibc, building from source is usually required since pre-built binaries target glibc 2.28+.
License
BSD-3-Clause. See LICENSE.txt for the full text.
Copyright (c) 2025, Alliance for Sustainable Energy LLC.