mloda-plugins: Building mloda Plugins
Check the registry index first
Always do this before writing a plugin: it may already exist. mloda-registry publishes community plugins
covering common {col}__{op} transforms (aggregation, window/scalar/frame aggregate, scalar/point arithmetic,
rank, offset, percentile, binning, datetime, string ops, time bucketization, ffill, ema, sessionization,
resample); see its plugins table for the full list. None
of it ships with plain pip install mloda; install what you need (pip install mloda-community for all, or
one package like pip install "mloda-community-rank[pandas]"), then confirm what's actually loaded:
from mloda.user import PluginLoader
from mloda.steward import get_feature_group_docs
PluginLoader.all()
for fg in get_feature_group_docs():
print(fg.name, fg.description)
An empty or unrelated result means it isn't installed yet, not that it doesn't exist; see
02-discover-plugins.md
for more on installed-vs-available. (The mloda skill covers the same check for requesting data instead of
writing a plugin.)
The three plugin types
Reach for a ComputeFramework only when adding a new execution backend, or an Extender for cross-cutting hooks.
Minimal example
A primary-source FeatureGroup (no inputs):
from mloda.provider import FeatureGroup
class CustomerScoring(FeatureGroup):
@classmethod
def calculate_feature(cls, data, features):
return {"customer_score": 100}
A chained one, reusable via an input__operation feature name (see "FeatureGroup: key decisions" below):
from mloda.provider import FeatureChainParserMixin, FeatureGroup
class MyOp(FeatureChainParserMixin, FeatureGroup):
PREFIX_PATTERN = r".*__([\w]+)_my_op$"
PROPERTY_MAPPING = {...}
@classmethod
def calculate_feature(cls, data, features): ...
Register either via PluginLoader.all() (installed package) or a direct import; see
03-create-plugin-in-project.md.
The plugin journey
Progression from using to sharing, each guide hosted in mloda-registry:
- Use an existing plugin / Discover plugins - start here, before writing anything.
- Create a plugin in your project - add a FeatureGroup inline, no separate package.
- Create a plugin package - scaffold a standalone installable package from mloda-plugin-template.
- Share with your team (private git) / Publish to the community registry / Contribute to official plugins / Become an official plugin.
Full progression: docs/guides/index.md.
FeatureGroup: key decisions
Full decision tree: guide 09. The recurring ones:
- Loads external data (file, DB, API)? Root feature pattern, see 01-root-features.md.
- Transforms 1+ existing features? Derived feature, see 02-derived-features.md.
- Should it be reusable via an
input__operation naming pattern? FeatureChainParserMixin, see 03-chained-features.md (2+ inputs: 04-multi-input-features.md).
- Multiple output columns? 05-multi-output-features.md (
feature~0, feature~1).
- Fitted/trained state between runs? 06-artifact-features.md.
- Time ordering, group-by, or joins across feature groups? 07-index-features.md / 08-links-joins.md.
- Group-identity option vs. runtime-only metadata? 11-options.md - a required context option that isn't forwarded through
input_features() breaks chained requests; see 26-input-feature-forwarding.md for the forwarding mechanism itself.
- Standard column transform (binning, window/scalar/frame aggregate, scalar/point arithmetic, rank, offset, percentile, string op, time bucketization, ffill, ema, resample, sessionization)? See the data operation patterns index before writing one from scratch.
- Feature defined via JSON/config instead of a naming pattern (e.g. to back the
mloda skill's LLM Tool Function pattern)? 22-feature-config.md.
- Ready to test? 10-testing-guide.md.
Full pattern index (27 guides, covering filters, validators, versioning, streaming, realtime execution, and
more): feature-group-patterns/index.md.
ComputeFramework: key decisions
Full decision tree: guide 10.
Full pattern index: compute-framework-patterns/index.md.
Extender: key decisions
Full guide: guide 11. Wraps feature calculation or input/output
validation; set a custom priority (lower runs first, default 100) if execution order matters; use class-level
storage for state under ParallelizationMode.MULTIPROCESSING (must be pickle-safe).
Reference
1---2name: mloda-plugins3description: Guide an AI agent through building mloda (https://github.com/mloda-ai/mloda) plugins: FeatureGroup, ComputeFramework, and Extender classes. Use to check the mloda-registry index for an existing plugin before writing one, when writing or reviewing a FeatureGroup/ComputeFramework/Extender implementation, or when packaging, sharing, or publishing a plugin to mloda-registry.4license: MIT5---67# mloda-plugins: Building mloda Plugins89## Check the registry index first1011Always do this before writing a plugin: it may already exist. mloda-registry publishes community plugins12covering common `{col}__{op}` transforms (aggregation, window/scalar/frame aggregate, scalar/point arithmetic,13rank, offset, percentile, binning, datetime, string ops, time bucketization, ffill, ema, sessionization,14resample); see its [plugins table](https://github.com/mloda-ai/mloda-registry#plugins) for the full list. None15of it ships with plain `pip install mloda`; install what you need (`pip install mloda-community` for all, or16one package like `pip install "mloda-community-rank[pandas]"`), then confirm what's actually loaded:1718```python19from mloda.user import PluginLoader20from mloda.steward import get_feature_group_docs2122PluginLoader.all()23for fg in get_feature_group_docs():24 print(fg.name, fg.description)25```2627An empty or unrelated result means it isn't installed yet, not that it doesn't exist; see28[02-discover-plugins.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/02-discover-plugins.md)29for more on installed-vs-available. (The `mloda` skill covers the same check for requesting data instead of30writing a plugin.)3132## The three plugin types3334| Type | Role | Full guide |35|------|------|------------|36| **FeatureGroup** | A data transformation, the unit you'll write most often | [09-create-feature-group.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/09-create-feature-group.md) |37| **ComputeFramework** | The execution backend a transformation runs on (Pandas, PyArrow, Polars, DuckDB, ...) | [10-create-compute-framework.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/10-create-compute-framework.md) |38| **Extender** | Hooks for logging, tracing, validation around feature calculation | [11-create-extender.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/11-create-extender.md) |3940Reach for a ComputeFramework only when adding a new execution backend, or an Extender for cross-cutting hooks.4142## Minimal example4344A primary-source FeatureGroup (no inputs):4546```python47from mloda.provider import FeatureGroup4849class CustomerScoring(FeatureGroup):50 @classmethod51 def calculate_feature(cls, data, features):52 return {"customer_score": 100}53```5455A chained one, reusable via an `input__operation` feature name (see "FeatureGroup: key decisions" below):5657```python58from mloda.provider import FeatureChainParserMixin, FeatureGroup5960class MyOp(FeatureChainParserMixin, FeatureGroup):61 PREFIX_PATTERN = r".*__([\w]+)_my_op$"62 PROPERTY_MAPPING = {...}6364 @classmethod65 def calculate_feature(cls, data, features): ...66```6768Register either via `PluginLoader.all()` (installed package) or a direct import; see69[03-create-plugin-in-project.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/03-create-plugin-in-project.md).7071## The plugin journey7273Progression from using to sharing, each guide hosted in mloda-registry:74751. [Use an existing plugin](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/01-use-existing-plugin.md) / [Discover plugins](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/02-discover-plugins.md) - start here, before writing anything.762. [Create a plugin in your project](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/03-create-plugin-in-project.md) - add a FeatureGroup inline, no separate package.773. [Create a plugin package](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/04-create-plugin-package.md) - scaffold a standalone installable package from [mloda-plugin-template](https://github.com/mloda-ai/mloda-plugin-template).784. [Share with your team](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/05-share-with-team.md) (private git) / [Publish to the community registry](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/06-publish-to-community.md) / [Contribute to official plugins](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/07-contribute-to-official.md) / [Become an official plugin](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/08-become-official.md).7980Full progression: [docs/guides/index.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/index.md).8182## FeatureGroup: key decisions8384Full decision tree: [guide 09](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/09-create-feature-group.md). The recurring ones:8586- **Loads external data (file, DB, API)?** Root feature pattern, see [01-root-features.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/01-root-features.md).87- **Transforms 1+ existing features?** Derived feature, see [02-derived-features.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/02-derived-features.md).88- **Should it be reusable via an `input__operation` naming pattern?** `FeatureChainParserMixin`, see [03-chained-features.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/03-chained-features.md) (2+ inputs: [04-multi-input-features.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/04-multi-input-features.md)).89- **Multiple output columns?** [05-multi-output-features.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/05-multi-output-features.md) (`feature~0`, `feature~1`).90- **Fitted/trained state between runs?** [06-artifact-features.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/06-artifact-features.md).91- **Time ordering, group-by, or joins across feature groups?** [07-index-features.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/07-index-features.md) / [08-links-joins.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/08-links-joins.md).92- **Group-identity option vs. runtime-only metadata?** [11-options.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/11-options.md) - a required context option that isn't forwarded through `input_features()` breaks chained requests; see [26-input-feature-forwarding.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/26-input-feature-forwarding.md) for the forwarding mechanism itself.93- **Standard column transform** (binning, window/scalar/frame aggregate, scalar/point arithmetic, rank, offset, percentile, string op, time bucketization, ffill, ema, resample, sessionization)? See the [data operation patterns index](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/data-operation-patterns/index.md) before writing one from scratch.94- **Feature defined via JSON/config instead of a naming pattern** (e.g. to back the `mloda` skill's LLM Tool Function pattern)? [22-feature-config.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/22-feature-config.md).95- **Ready to test?** [10-testing-guide.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/10-testing-guide.md).9697Full pattern index (27 guides, covering filters, validators, versioning, streaming, realtime execution, and98more): [feature-group-patterns/index.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/feature-group-patterns/index.md).99100## ComputeFramework: key decisions101102Full decision tree: [guide 10](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/10-create-compute-framework.md).103104- **Needs a connection/session object?** Data lake table format (Iceberg, Delta, Hudi) -> [05-data-lake.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/05-data-lake.md); otherwise -> [03-stateful-connection.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/03-stateful-connection.md) (DuckDB, Spark).105- **Lazy evaluation?** [02-stateless-lazy.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/02-stateless-lazy.md) (Polars Lazy, Ibis).106- **Eager, no external deps?** [04-zero-dependency.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/04-zero-dependency.md); with deps -> [01-stateless-eager.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/01-stateless-eager.md) (Pandas, PyArrow).107- **Cross-framework conversion?** [08-framework-transformer.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/08-framework-transformer.md).108- **Joins/merges or filters?** [06-merge-engine.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/06-merge-engine.md) / [07-filter-engine.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/07-filter-engine.md).109- **Ready to test?** [09-testing-guide.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/09-testing-guide.md).110111Full pattern index: [compute-framework-patterns/index.md](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/compute-framework-patterns/index.md).112113## Extender: key decisions114115Full guide: [guide 11](https://github.com/mloda-ai/mloda-registry/blob/main/docs/guides/11-create-extender.md). Wraps feature calculation or input/output116validation; set a custom priority (lower runs first, default 100) if execution order matters; use class-level117storage for state under `ParallelizationMode.MULTIPROCESSING` (must be pickle-safe).118119## Reference120121- Registry (community/enterprise plugins, guides): <https://github.com/mloda-ai/mloda-registry>122- Plugin template (scaffold for a standalone package): <https://github.com/mloda-ai/mloda-plugin-template>123- Core docs: <https://mloda-ai.github.io/mloda/>