Skip to content

Conversation

@pesap
Copy link
Collaborator

@pesap pesap commented Apr 16, 2025

The proposed changes enable loading external plugins via standard python
packages "pip install X". These changes affect the r2x package somewhat
broadly and careful review is necessary.

The PluginManager object is a Singleton Class that is responsible for
hosting a variety of Class and function objects internal and external to
R2X. These objects include the following:

- Parsers (ReEDSParser, PlexosParser, ...)
- Model Configurations
- Exporters
- Filter Functions [Callable or str]
- DefaultFile objects

The components above are put together in a PluginComponent object that
external users can define. The plugin manager looks for entry_points of
"r2x_plugin" and loads a function that should create a dictionary of
name: PluginComponents to register.

R2X contains many default files which are now captured in the
DefaultFile class. This class automatically generates the full file path
of a default json file so that R2X can find it in either an internal or
external package. DefaultFiles also include field mappings.

The PluginManager also registers several types of callable functions.
Namely, CLI functions, "filter funcs", and "update_system" functions.
The PluginManager does this through decorators and importing the
functions upon initialization to register them. This allows external
users to define their own functions, and, so long as they are included
in the external modules entry point, they will automatically be
registered.

The PluginManger can be used in two different ways. First, you can
simply import the PluginManager class to add decorators to functions
that you wish to register. (For internal functions, this also requires
updating the PluginManager intialization method to import the functions
you want to register.). The second way is to create the singleton
instance of the PluginManger to get plugin components (parser,
exporters, configs, filter_funcs, cli_functions, and system_updates)

Although pluggy has some nice features around hook specifications. It
would still require making a plugin managment system to register those
hooks. More importantly, given the coupling between parsers,
configurations, exporters and default files, it seemed more
straightforward to write a custom plugin management system. Even though
pluggy could handle cli, filter and update functions, it was simple
enough to add that same functionality into the PluginManager.

---------

Co-authored-by: pesap <pesap@users.noreply.github.com>
pesap and others added 4 commits May 17, 2025 22:16
- Fixed the plugin_manager to use a the current script path and relative
navigation to load the sysmods in the /plugins directory.
- Added pytest-xdist to the dev dependencies so you can run tests in
parallel with `pytest -n auto`
Signed-off-by: pesap <pesap@users.noreply.github.com>
Co-authored-by: pesap <pesap@users.noreply.github.com>
Co-authored-by: Jarrad Wright <jwright2@nrel.gov>
Co-authored-by: mcllerena <marckcode@gmail.com>
Co-authored-by: Marck Llerena V <140716266+mcllerena@users.noreply.github.com>
Signed-off-by: pesap <pesap@users.noreply.github.com>
@pesap pesap marked this pull request as ready for review July 16, 2025 04:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces v2.0.0 with a major architectural refactor that implements a centralized plugin management system to replace the previous distributed module-based approach.

  • Introduces a new PluginManager system with singleton pattern for centralized plugin registration and discovery
  • Refactors all plugins to use decorator-based registration instead of module imports
  • Updates function signatures across plugins to standardize parser parameter placement and typing

Reviewed Changes

Copilot reviewed 51 out of 52 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
user_dict.yaml Adds example configuration file with various usage patterns for model configuration
src/r2x/plugin_manager/ New plugin management system with centralized registration and discovery
src/r2x/plugins/*.py Updates all plugins to use decorator-based registration with PluginManager
src/r2x/runner.py Refactors to use PluginManager instead of direct module imports
tests/test_*.py Updates test files to match new plugin architecture and API changes
src/r2x/models/getters.py New getter functions with singledispatch for component property access
Comments suppressed due to low confidence (1)

src/r2x/plugins/break_gens.py:213

  • [nitpick] The parameter name attr is ambiguous. Consider renaming it to attribute or value to be more descriptive of its purpose.
def _apply_new_value(attr: Any, proportion: float):

@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 80.67979% with 108 lines in your changes missing coverage. Please review.

Project coverage is 80.47%. Comparing base (0f938e3) to head (425fd13).

Files with missing lines Patch % Lines
src/r2x/plugin_manager/plugin_manager.py 68.42% 54 Missing ⚠️
src/r2x/plugin_manager/interfaces.py 72.72% 15 Missing ⚠️
src/r2x/plugin_manager/defaults.py 82.53% 11 Missing ⚠️
src/r2x/plugin_manager/utils.py 68.42% 6 Missing ⚠️
src/r2x/parser/handler.py 63.63% 4 Missing ⚠️
src/r2x/runner.py 85.18% 4 Missing ⚠️
src/r2x/exporter/plexos.py 66.66% 3 Missing ⚠️
src/r2x/parser/plexos.py 66.66% 3 Missing ⚠️
src/r2x/plugins/pcm_defaults.py 92.68% 3 Missing ⚠️
src/r2x/config_models.py 80.00% 2 Missing ⚠️
... and 3 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #187      +/-   ##
==========================================
- Coverage   83.28%   80.47%   -2.81%     
==========================================
  Files          42       52      +10     
  Lines        4510     5087     +577     
==========================================
+ Hits         3756     4094     +338     
- Misses        754      993     +239     
Files with missing lines Coverage Δ
src/r2x/config_scenario.py 95.77% <100.00%> (-0.03%) ⬇️
src/r2x/exporter/__init__.py 100.00% <100.00%> (ø)
src/r2x/exporter/sienna.py 95.14% <100.00%> (+0.45%) ⬆️
src/r2x/models/generators.py 97.69% <100.00%> (-0.62%) ⬇️
src/r2x/models/getters.py 100.00% <100.00%> (ø)
src/r2x/parser/__init__.py 100.00% <100.00%> (ø)
src/r2x/parser/polars_helpers.py 78.75% <100.00%> (+1.41%) ⬆️
src/r2x/plugin_manager/__init__.py 100.00% <100.00%> (ø)
src/r2x/plugins/break_gens.py 83.80% <100.00%> (+3.80%) ⬆️
src/r2x/plugins/cambium.py 24.52% <100.00%> (ø)
... and 19 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

pesap and others added 17 commits July 15, 2025 22:12
…ity. (#209)

Plexos test is broken and will be migrated to r2x-plexos eventually.

---------

Signed-off-by: pesap <pesap@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This branch was created from Micah's v2.0.0 branch and has certain
PlexosExporter specific changes to allow for the successful creation of
the XML file. It also updates minimum dependency versions of PlexosDB to
ensure it works with the r2x-plexos plugin.

---------

Signed-off-by: pesap <pesap@users.noreply.github.com>
Signed-off-by: Kinshuk Panda <kinshukpanda@gmail.com>
Co-authored-by: Micah Webb <webbmp91@gmail.com>
Co-authored-by: pesap <pesap@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: pesap <pesap@users.noreply.github.com>
Co-authored-by: mcllerena <marckcode@gmail.com>
…es (#222)

Signed-off-by: Marck Llerena V. <140716266+mcllerena@users.noreply.github.com>
Co-authored-by: pesap <pesap@users.noreply.github.com>
Signed-off-by: Marck Llerena V. <140716266+mcllerena@users.noreply.github.com>
Co-authored-by: pesap <pesap@users.noreply.github.com>
Co-authored-by: Srihari Sundar <hari.sundar@nrel.gov>
- Adds entry point to pyproject.toml for plugin discovery.
- Adds "run" method to PluginSpec.
…ration (#228)

Signed-off-by: Marck Llerena V. <140716266+mcllerena@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants