Skip to content

feature/plugin - #14

Merged
bwalsh merged 22 commits into
developmentfrom
feature/plugin
Jun 26, 2026
Merged

bwalsh merged 22 commits into
developmentfrom
feature/plugin

Conversation

@bwalsh

@bwalsh bwalsh commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Add pluggable matcher architecture, example plugins, test coverage, and plugin documentation

Why

vrs-matcher had a single built-in matching algorithm. That was a good starting point, but it limited the project in a few ways:

  • users could not experiment with alternative matching or ranking strategies,
  • labs could not easily prototype workflow-specific logic without editing core code,
  • the CLI had no mechanism to discover or run custom matchers,
  • the notebook and examples demonstrated only the default algorithm,
  • documentation did not explain how a bioinformatician might extend matching for specific use cases.

This PR introduces a plugin system so matching algorithms can be supplied as:

  • built-in plugins,
  • installed Python packages discovered via entry points, or
  • local script files loaded directly from disk.

It also adds tests, an example plugin, notebook coverage, and more detailed documentation around practical plugin use cases.

What Changed

Core plugin architecture

Added src/vrs_matcher/plugins.py to define and manage matcher plugins:

  • PluginContext read-only facade over DB access helpers
  • MatcherPlugin protocol-style contract
  • built-in plugin registration
  • entry-point discovery via vrs_matcher.plugins
  • script plugin loading from --plugin-file
  • plugin validation and cache reset helpers

Built-in matcher refactor

Updated src/vrs_matcher/matcher.py so the existing identity matcher is now implemented as a built-in plugin while keeping the public API stable:

  • extracted current behavior into IdentityMatcherPlugin
  • kept match_pair(...) and match_against_all(...) as backward-compatible wrappers
  • added optional plugin selection parameters:
    • algorithm
    • plugin_file
  • preserved existing notebook import patterns and default behavior

CLI plugin support

Updated src/vrs_matcher/cli.py to support plugin selection:

  • added --algorithm to matching commands
  • added --plugin-file to load local script plugins
  • added vrs-matcher plugins list
  • surfaced plugin resolution/validation errors as CLI-friendly messages

Example plugin

Added examples/plugins/jaccard_floor_plugin.py:

  • demonstrates a script-loaded matcher plugin
  • reuses the current identity-style metrics
  • applies a minimum floor to the reported Jaccard-like primary score
  • serves as a minimal teaching example for custom scoring logic

Test coverage improvements

Added and expanded tests across plugins, notebooks, loader, and CLI behavior:

  • tests/test_plugins.py
    • built-in discovery
    • entry-point discovery (modern and legacy branches)
    • script plugin loading and failure paths
    • duplicate built-in registration behavior
    • explicit coverage for the shipped example plugin in examples/plugins/
  • tests/test_notebooks.py
    • verifies the example notebook still documents and exercises the expected matching workflow
    • runs the notebook’s core example workflow against the bundled example cohort
  • tests/test_loader.py
    • expanded branch coverage for scalar formatting, row filtering, candidate filtering, and batch flush behavior
  • tests/test_cli.py
    • added plugin-listing coverage
    • added script-plugin CLI invocation coverage

Documentation

Expanded plugin documentation for both developers and bioinformatics users:

  • updated README.md plugin section to explain when built-in, local script, and packaged plugins are appropriate
  • added/expanded docs/plugins.md with:
    • plugin architecture overview
    • plugin contract and minimal template
    • practical development workflow
    • validation guidance
    • troubleshooting
    • bioinformatics-oriented example ideas for:
      • rare-variant-weighted identity confirmation
      • candidate-gene-only sample matching
      • combinations of the two

Validation

Ran the following successfully:

  • uv run pytest ✅
  • uv run pytest tests/test_plugins.py ✅
  • uv run pytest tests/test_loader.py tests/test_cli.py ✅
  • uv run pytest tests/test_notebooks.py ✅
  • uv run ruff check . ✅

Latest full-suite result:

  • 102 passed, 1 skipped

Reviewer Notes

  • The public matcher API remains backward-compatible for existing notebook and Python callers.
  • The default behavior is unchanged when no plugin arguments are supplied.
  • The example plugin is intentionally simple and meant as a teaching/reference implementation.
  • The plugin system currently standardizes on MatchResult, so custom plugins still report their primary score in the jaccard field.

Follow-ups (Optional)

  • Add a richer plugin example that uses cohort frequency or sidecar metadata
  • Support structured plugin configuration files instead of script-level constants
  • Add first-class built-in plugins for additional research workflows if they become stable enough
  • Consider exposing plugin-specific metadata or score labels in CLI output

Copilot AI review requested due to automatic review settings June 1, 2026 20:06

Copilot AI left a comment

Copy link
Copy Markdown

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 a pluggable matcher architecture so vrs-matcher can run alternative matching/ranking algorithms via built-in implementations, Python entry points, or local script files, while keeping the existing matcher API and CLI behavior backward-compatible by default.

Changes:

  • Added a new plugin system (plugins.py) with built-in registration, entry-point discovery, and script-plugin loading.
  • Refactored the existing identity matcher into a built-in plugin and routed match_pair / match_against_all through plugin resolution.
  • Extended the CLI, documentation, examples, and tests to cover plugin selection, listing, and script plugin execution.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/vrs_matcher/plugins.py New plugin registry/discovery/loader implementation for matchers.
src/vrs_matcher/matcher.py Refactors identity matching into a built-in plugin and adds plugin selection parameters to public match APIs.
src/vrs_matcher/cli.py Adds --algorithm, --plugin-file, and plugins list support to the CLI.
examples/plugins/jaccard_floor_plugin.py Adds a reference script plugin demonstrating custom scoring behavior.
docs/plugins.md New comprehensive documentation for plugin authoring and usage.
README.md Adds a plugin section and basic usage examples.
tests/test_plugins.py Adds coverage for built-in, entry-point, and script plugin behaviors and error paths.
tests/test_cli.py Adds CLI coverage for listing plugins and running a script plugin.
tests/test_loader.py Adds coverage for loader edge cases and batch/cleanup behavior.
tests/test_notebooks.py Adds smoke tests to ensure the example notebook workflow remains valid.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/vrs_matcher/plugins.py
Comment thread src/vrs_matcher/plugins.py
Comment thread src/vrs_matcher/matcher.py
Comment thread src/vrs_matcher/matcher.py
bwalsh and others added 4 commits June 1, 2026 13:10
PR review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Comment thread src/vrs_matcher/plugins.py Outdated
bwalsh and others added 2 commits June 1, 2026 13:38
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@lbeckman314

lbeckman314 commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

Review Steps

1. Update ✔️

➜ cd vrs-matcher

➜ git checkout feature/plugin
gbranch 'feature/plugin' set up to track 'origin/feature/plugin'.
Switched to a new branch 'feature/plugin'

➜ git show --summary --oneline
6cf6bd1 (HEAD -> feature/plugin, origin/feature/plugin) adds plugin loading flow

2. Run Built-in Plugin (identity) ✔️

README.md

➜ uv run vrs-matcher plugins list
identity

➜ uv run vrs-matcher load-samples examples/example-cohort.vcf --db matches.db
Loaded 6 allele records into matches.db

➜ uv run vrs-matcher match-sample SAMPLE_A --db matches.db --algorithm identity
Sample                          Jaccard    WConc   Shared
------------------------------------------------------------
SAMPLE_B                         0.6667   1.0000        2
SAMPLE_C                         0.3333   0.5000        1

3. Run Script Plugin (Jaccard Floor) ✔️

plugins.md

➜ uv run vrs-matcher match-sample SAMPLE_A --db matches.db --plugin-file examples/plugins/jaccard_floor_plugin.py
Sample                          Jaccard    WConc   Shared
------------------------------------------------------------
SAMPLE_B                         0.6667   1.0000        2
SAMPLE_C                         0.3333   0.5000        1

3. Test ✔️

➜ uv run pytest
102 passed, 1 skipped in 1.55s

➜ uv run ruff check
All checks passed!

@lbeckman314 lbeckman314 mentioned this pull request Jun 11, 2026

@lbeckman314 lbeckman314 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tip

  • All new plugin steps pass, as do the tests (see Review Steps above)!
  • Created PR #16 with optional updated docs + examples

Important

  • I have not yet tried creating a custom plugin (following the steps in plugins.md). This might be a good next review step (but shouldn't block this PR from being merged)...

@bwalsh

bwalsh commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

I have not yet tried creating a custom plugin (following the steps in plugins.md). This might be a good next review step (but shouldn't block this PR from being merged)...

@lbeckman314 that would be an excellent idea

@lbeckman314

lbeckman314 commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

Creating example plugin at https://github.com/EllrottLab/vrs-matcher-example-plugin

bwalsh added 9 commits June 17, 2026 16:02
Add integration test to verify that my_plugin produces different results from the identity algorithm.
Refactor test to use sample IDs directly from the database instead of MatchContext. Update variable names for clarity.
Refactor database connection handling in the sample matching process.
bwalsh and others added 4 commits June 17, 2026 17:13
@bwalsh
bwalsh merged commit e14e6d4 into development Jun 26, 2026
1 check passed
@bwalsh
bwalsh deleted the feature/plugin branch June 26, 2026 17:12
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.

3 participants