From a318840201eacc29bbccf6f054e44be02e0f32f1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 22:45:23 +0000 Subject: [PATCH 1/3] Initial plan From 3f06983dba14e70068a4729527dcdcee3cee80ad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 22:52:20 +0000 Subject: [PATCH 2/3] Make cim-graph and gridappsd-python optional dependencies to fix pre-release install issue Co-authored-by: nathantgray <18407725+nathantgray@users.noreply.github.com> --- pyproject.toml | 8 ++++++-- src/distopf/api.py | 6 ++++++ tests/cim_converter/conftest.py | 8 ++++++++ uv.lock | 15 ++++++++++----- 4 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 tests/cim_converter/conftest.py diff --git a/pyproject.toml b/pyproject.toml index d765b01..a93f027 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,8 +10,6 @@ authors = [ ] requires-python = ">=3.10" dependencies = [ - "cim-graph==0.4.1a2", - "gridappsd-python==2025.3.2a13", "cvxpy>=1.7.2", "networkx>=3.4.2", "numpy>=2.2.6", @@ -25,6 +23,12 @@ dependencies = [ "highspy>=1.13.0", ] +[project.optional-dependencies] +cim = [ + "cim-graph==0.4.1a2", + "gridappsd-python==2025.3.2a13", +] + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" diff --git a/src/distopf/api.py b/src/distopf/api.py index 7c9544c..9335117 100644 --- a/src/distopf/api.py +++ b/src/distopf/api.py @@ -1403,7 +1403,13 @@ def create_case_from_cim( try: # Lazy import to avoid loading cimgraph at module load time from distopf.cim_importer import CIMToCSVConverter + except ImportError as e: + raise ImportError( + "CIM file support requires optional dependencies. " + "Install them with: pip install distopf[cim]" + ) from e + try: cim_parser = CIMToCSVConverter(data_path) data = cim_parser.convert() diff --git a/tests/cim_converter/conftest.py b/tests/cim_converter/conftest.py new file mode 100644 index 0000000..8c215e9 --- /dev/null +++ b/tests/cim_converter/conftest.py @@ -0,0 +1,8 @@ +import pytest + +# Skip all CIM tests if the optional cim-graph dependency is not installed. +# Install it with: pip install distopf[cim] +pytest.importorskip( + "cimgraph", + reason="CIM tests require the 'cim' optional dependency: pip install distopf[cim]", +) diff --git a/uv.lock b/uv.lock index 3d59ffe..f046bb8 100644 --- a/uv.lock +++ b/uv.lock @@ -763,13 +763,11 @@ wheels = [ [[package]] name = "distopf" -version = "0.3.0" +version = "0.4.0" source = { editable = "." } dependencies = [ { name = "altdss", extra = ["all"] }, - { name = "cim-graph" }, { name = "cvxpy" }, - { name = "gridappsd-python" }, { name = "highspy" }, { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "networkx", version = "3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -784,6 +782,12 @@ dependencies = [ { name = "scipy", version = "1.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] +[package.optional-dependencies] +cim = [ + { name = "cim-graph" }, + { name = "gridappsd-python" }, +] + [package.dev-dependencies] dev = [ { name = "jupyter" }, @@ -805,9 +809,9 @@ dev = [ [package.metadata] requires-dist = [ { name = "altdss", extras = ["all"], specifier = ">=0.2.4" }, - { name = "cim-graph", specifier = "==0.4.1a2" }, + { name = "cim-graph", marker = "extra == 'cim'", specifier = "==0.4.1a2" }, { name = "cvxpy", specifier = ">=1.7.2" }, - { name = "gridappsd-python", specifier = "==2025.3.2a13" }, + { name = "gridappsd-python", marker = "extra == 'cim'", specifier = "==2025.3.2a13" }, { name = "highspy", specifier = ">=1.13.0" }, { name = "networkx", specifier = ">=3.4.2" }, { name = "numpy", specifier = ">=2.2.6" }, @@ -818,6 +822,7 @@ requires-dist = [ { name = "pyscipopt", specifier = ">=6.0.0" }, { name = "scipy", specifier = ">=1.15.3" }, ] +provides-extras = ["cim"] [package.metadata.requires-dev] dev = [ From baa57715be97ee123f95aa164d5cad49b42e54b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 23:01:02 +0000 Subject: [PATCH 3/3] docs: document optional cim extra in README Co-authored-by: nathantgray <18407725+nathantgray@users.noreply.github.com> --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index ceaf225..c8693ee 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,17 @@ minimization, and generation curtailment minimization, where either generator re ``` pip install distopf ``` + +### Optional Extras + +| Extra | Install command | Purpose | +|-------|----------------|---------| +| `cim` | `pip install distopf[cim]` | CIM XML file import support (requires pre-release packages `cim-graph` and `gridappsd-python`) | + +> **Note:** The `cim` extra depends on pre-release packages. If you do not need CIM file support, a plain +> `pip install distopf` is sufficient. CIM functionality will raise an informative `ImportError` if those +> packages are not installed. + ## Developer Installation To install the latest version from github: @@ -43,6 +54,10 @@ To install the latest version from github: `pip install -e .` +To also install the optional CIM extra in editable mode: + +`pip install -e ".[cim]"` + This installs your local DistOPF package the python environment you activated. The `-e` option enables editable mode, which allows you to directly edit the package and see changes immediately reflected in your environment without reinstalling. @@ -342,6 +357,28 @@ case = opf.create_case( ) ``` +# CIM XML Interface + +To load a power system model from a CIM XML file, install the optional `cim` extra first: + +``` +pip install distopf[cim] +``` + +Then pass the path to your `.xml` file: + +```python +import distopf as opf +case = opf.create_case(data_path="path/to/model.xml") +``` + +If the `cim` extra is not installed, calling `create_case` with a `.xml` file will raise: + +``` +ImportError: CIM file support requires optional dependencies. +Install them with: pip install distopf[cim] +``` + # Citing this tool Gray, Nathan T., Dubey, Anamika, Reiman, Andrew P., "DistOPF: Advanced Solutions for Distribution Optimal Power Flow Analysis - DistOPF v0.2 Documentation," (2025), https://doi.org/10.2172/2999990