Plugins

Note

This page is a focused guide for plugin usage and contribution. For everything reachable from a Protein object, see The Protein Object.

Plugins extend Sparrow analyses through Protein.plugin. The plugin manager discovers subclasses of sparrow.sequence_analysis.plugins.BasePlugin from sparrow.sequence_analysis.community_plugins.contributed.

Using Plugins

from sparrow import Protein

p = Protein("MEEEKKKKSSSTTTDDD")

# discover available plugin callables
available = [name for name in dir(p.plugin) if not name.startswith("_")]

# run a plugin
value = p.plugin.MultiplicativeFCR(factor=2.5)

Caching and Call Semantics

Plugin calls are memoized by argument signature in PluginWrapper using (args, frozenset(kwargs.items())). Plugin argument values must therefore be hashable.

Plugin lifecycle:

  1. PluginManager discovers valid plugin subclasses.

  2. First attribute access lazily loads and instantiates the plugin.

  3. Calling the wrapper dispatches to calculate(*args, **kwargs).

  4. Repeated calls with identical arguments return cached results.

Plugin Contribution Tutorial

This tutorial describes the minimum steps to add a community plugin.

Step 1: Create a plugin class

Add a subclass of BasePlugin in:

  • sparrow/sequence_analysis/community_plugins/contributed.py

from sparrow.sequence_analysis.plugins import BasePlugin


class ExampleMetric(BasePlugin):
    """Return a scaled FCR as a simple plugin example."""

    def calculate(self, scale: float = 1.0) -> float:
        return scale * self.protein.FCR

Step 2: Verify discovery and execution

from sparrow import Protein

p = Protein("MEEEKKKKSSSTTTDDD")
assert "ExampleMetric" in dir(p.plugin)
result = p.plugin.ExampleMetric(scale=2.0)

Step 3: Add tests

Add focused tests to sparrow/tests/test_plugins.py for:

  • plugin result correctness

  • cache behavior for repeated calls

  • invalid plugin access behavior (if relevant)

Step 4: Add docs

Document plugin purpose, parameters, and return values in class/method docstrings. Plugin class names are user-facing API names via protein.plugin.<ClassName>.

Reference: Plugin Infrastructure

Key user entrypoint: sparrow.protein.Protein.plugin.

sparrow.sequence_analysis.plugins.PluginManager

Discover, load, cache, and expose community contributed plugins.

sparrow.sequence_analysis.plugins.BasePlugin

Abstract base class for all contributed plugins.

sparrow.sequence_analysis.community_plugins.contributed.MultiplicativeFCR

class PluginManager(protein_obj)[source]

Bases: object

Discover, load, cache, and expose community contributed plugins.

A PluginManager instance behaves as a dynamic attribute container where each attribute access corresponding to a discovered plugin name returns a callable PluginWrapper. Invoking that callable executes the plugin’s BasePlugin.calculate() method with transparent caching keyed by arguments.

Parameters:

protein_obj (Protein) – Protein object whose sequence (and related metadata) plugin analyses will operate on.

_available_plugins

Names of all plugin classes discovered under the contributed namespace.

Type:

list[str]

_PluginManager__protein_obj

Stored protein instance (private attribute).

Type:

Protein

_PluginManager__precomputed

Nested dictionary mapping plugin name to cached results keyed by the argument signature tuple used in PluginWrapper.

Type:

dict[str, dict[tuple, Any]]

_PluginManager__plugins

Loaded plugin instances keyed by name.

Type:

dict[str, BasePlugin]

Notes

  • Discovery happens once at initialization.

  • Attribute access for an undiscovered plugin raises AttributeError with a helpful list of available plugins.

  • Autocompletion in interactive environments is aided by overriding __dir__() to include discovered plugin names.

__init__(protein_obj)[source]

Initialize the manager and eagerly discover available plugins.

Parameters:

protein_obj (Protein) – Protein instance passed to each plugin upon first access.

class BasePlugin(protein)[source]

Bases: ABC

Abstract base class for all contributed plugins.

Subclasses must implement calculate(), operating on the provided protein object’s sequence to return an analysis result.

Parameters:

protein (Protein) – Protein instance supplied by PluginManager.

abstractmethod calculate()[source]

Run the plugin’s analysis logic.

Returns:

Result of the contributed analysis (type is plugin-specific).

Return type:

Any

property protein

Return the protein instance associated with this plugin.

Plugin infrastructure for Sparrow sequence analysis.

This module provides a lightweight dynamic plugin discovery and execution mechanism used by Sparrow to run community contributed sequence analysis routines. Plugins are simple subclasses of BasePlugin that implement a single BasePlugin.calculate() method. They are discovered at runtime from the sparrow.sequence_analysis.community_plugins.contributed namespace and exposed as attributes on PluginManager instances.

Typical usage

>>> mgr = PluginManager(protein_obj)
>>> result = mgr.HydrophobicityIndex()          # call plugin with no args
>>> result2 = mgr.SomeOtherMetric(window=5)     # call plugin with args (cached)

Caching

Results of plugin executions are memoized per plugin + arguments so repeated calls with identical arguments are O(1) after the first computation.

Notes

  • Accessing an unknown attribute raises AttributeError listing available plugins.

  • Autocompletion is improved via __dir__ which returns discovered plugin names.

class PluginWrapper(name, cache_dict, plugin_instance)[source]

Bases: object

Callable wrapper adding argument-aware result caching for a plugin.

The wrapper caches results keyed by the positional argument tuple and a frozenset of keyword argument items to avoid repeated calculations for identical invocations of the underlying plugin’s calculate method.

Parameters:
  • name (str) – Canonical plugin name (class name).

  • cache_dict (dict[str, dict[tuple, Any]]) – Shared memoization dictionary managed by PluginManager.

  • plugin_instance (BasePlugin) – Instantiated plugin object providing calculate.

Notes

The cache key is constructed as (args, frozenset(kwargs.items())) which requires that all argument values be hashable.

class PluginManager(protein_obj)[source]

Bases: object

Discover, load, cache, and expose community contributed plugins.

A PluginManager instance behaves as a dynamic attribute container where each attribute access corresponding to a discovered plugin name returns a callable PluginWrapper. Invoking that callable executes the plugin’s BasePlugin.calculate() method with transparent caching keyed by arguments.

Parameters:

protein_obj (Protein) – Protein object whose sequence (and related metadata) plugin analyses will operate on.

_available_plugins

Names of all plugin classes discovered under the contributed namespace.

Type:

list[str]

_PluginManager__protein_obj

Stored protein instance (private attribute).

Type:

Protein

_PluginManager__precomputed

Nested dictionary mapping plugin name to cached results keyed by the argument signature tuple used in PluginWrapper.

Type:

dict[str, dict[tuple, Any]]

_PluginManager__plugins

Loaded plugin instances keyed by name.

Type:

dict[str, BasePlugin]

Notes

  • Discovery happens once at initialization.

  • Attribute access for an undiscovered plugin raises AttributeError with a helpful list of available plugins.

  • Autocompletion in interactive environments is aided by overriding __dir__() to include discovered plugin names.

__init__(protein_obj)[source]

Initialize the manager and eagerly discover available plugins.

Parameters:

protein_obj (Protein) – Protein instance passed to each plugin upon first access.

class BasePlugin(protein)[source]

Bases: ABC

Abstract base class for all contributed plugins.

Subclasses must implement calculate(), operating on the provided protein object’s sequence to return an analysis result.

Parameters:

protein (Protein) – Protein instance supplied by PluginManager.

abstractmethod calculate()[source]

Run the plugin’s analysis logic.

Returns:

Result of the contributed analysis (type is plugin-specific).

Return type:

Any

property protein

Return the protein instance associated with this plugin.

Reference: Contributed Plugins Module

class MultiplicativeFCR(protein)[source]

Bases: BasePlugin

calculate(factor=2.0)[source]

This analysis doubles the FCR (fraction of charged residues) of the protein. This is a simple example of a contributed plugin.

Parameters:

factor (float) – The factor by which the FCR will be multiplied (default is 2.0)

Returns:

Returns the result of the contributed analysis

Return type:

float

property protein

Return the protein instance associated with this plugin.

class MultiplicativeFCR(protein)[source]

Bases: BasePlugin

calculate(factor=2.0)[source]

This analysis doubles the FCR (fraction of charged residues) of the protein. This is a simple example of a contributed plugin.

Parameters:

factor (float) – The factor by which the FCR will be multiplied (default is 2.0)

Returns:

Returns the result of the contributed analysis

Return type:

float

property protein

Return the protein instance associated with this plugin.