Extensible framework for building power system model translators
R2X Core provides the shared infrastructure for translating between power-system model formats. It gives translator authors a typed plugin lifecycle, a configuration-driven data loading layer, declarative rule mapping, unit-aware models, and versioned upgrade helpers.
Use it when you are building or extending translators for models such as ReEDS, PLEXOS, SWITCH, Sienna, or other infrasys-backed power-system workflows.
Install · Quickstart · Core concepts · Documentation · Development · Roadmap · Contributing · License
pip install r2x-coreOr with uv:
uv add r2x-coreR2X Core supports Python 3.11, 3.12, and 3.13.
DataStore manages named DataFile definitions and reads them through the
configured DataReader pipeline.
from r2x_core import DataFile, DataStore, TabularProcessing
store = DataStore(path="/path/to/data")
store.add_data([
DataFile(
name="generators",
relative_fpath="gen.csv",
proc_spec=TabularProcessing(
column_mapping={"capacity_mw": "p_max_mw"},
filter_by={"status": "active"},
),
),
DataFile(name="loads", relative_fpath="load.parquet"),
])
generators = store.read_data("generators")
available = store.list_data()Use relative_fpath for files under the store root, fpath for explicit paths,
and ReaderConfig(kwargs=...) when the default reader needs format-specific
options such as HDF5 dataset keys.
Class plugins implement only the lifecycle hooks they need. Hooks return
Ok(...) or Err(...); Plugin.run() returns the final PluginContext and
raises PluginError on the first hook failure.
from rust_ok import Ok
from r2x_core import Plugin, PluginConfig, PluginContext, System
class MyModelConfig(PluginConfig):
input_folder: str
model_year: int
scenario: str = "base"
class MyModelTranslator(Plugin[MyModelConfig]):
def on_build(self):
system = System(name=f"{self.config.scenario}_{self.config.model_year}")
return Ok(system)
config = MyModelConfig(input_folder="/path/to/data", model_year=2030)
context = PluginContext(config=config)
plugin = MyModelTranslator.from_context(context)
result = plugin.run()
print(result.system.name)For focused System -> System transformations, expose a plain function and
register it through the r2x.transforms entry-point group.
from rust_ok import Ok, Result
from r2x_core import PluginConfig, System, expose_plugin
class ScaleConfig(PluginConfig):
scale: float = 1.0
@expose_plugin
def scale_system(system: System, config: ScaleConfig) -> Result[System, str]:
return Ok(system)[project.entry-points."r2x.transforms"]
scale_system = "my_package.transforms:scale_system"| Concept | What it does |
|---|---|
Plugin / PluginContext |
Coordinates translator lifecycle hooks and shared pipeline state. |
PluginConfig |
Provides typed Pydantic configuration for translators and transforms. |
DataFile / DataStore |
Declares, reads, and processes model input files. |
Rule / RuleFilter |
Maps source components to target components with declarative filters. |
HasUnits / Unit |
Adds unit-aware field validation and display formatting. |
UpgradeStep |
Applies versioned data or schema upgrade steps. |
R2X Core builds on infrasys for
System and Component primitives.
Full documentation is available at natlabrockies.github.io/r2x-core, including tutorials, how-to guides, and the API reference.
This repository uses uv and just for local
automation.
just setup
just hooks
just test
just docsCommon tasks:
| Command | Purpose |
|---|---|
just setup |
Install all dependency groups. |
just format |
Format Python code with Ruff. |
just lint |
Run Ruff checks. |
just type |
Run ty type checks. |
just test |
Run pytest. |
just docs |
Build Sphinx docs. |
just verify |
Run hooks, docstring coverage, and tests. |
We welcome contributions. See the contributing guide for local setup, development workflow, and review expectations.
R2X Core is released under the BSD 3-Clause License. See LICENSE.txt for details.