Plugins
The SDK includes a local developer kit for kernel plugins: a directory with a plugin.json descriptor and Python entry files. It scaffolds, validates, runs and packs a plugin on your machine, with no platform installation and no network access. The descriptor format, component types and sandbox are described in Plugins; this page covers the kit.
The kit is 0.1.8+: it needs a honeyframeapi release newer than 0.1.7.
The workflow
honeyframe plugin init row-tagger --type recipe # scaffold a plugin directory
honeyframe plugin check row-tagger # validate plugin.json
honeyframe plugin run row-tagger recipe --params params.json --input rows.csv
honeyframe plugin pack row-tagger # validate, then zip
initcreates a new directory (it refuses a non-empty one) with aplugin.jsonand an entry file for the component type:recipe,transform,connector,scenario_step, or the descriptor-onlymonitor_adapter. The scaffold always passescheck.checkvalidatesplugin.jsonwith the same rules and messages as the platform, including that every entry file exists inside the plugin directory.runexecutes one component (see the warning below).packvalidates, then writes<id>-<version>.zipwithplugin.jsonat the archive root. Dotfiles,__pycache__,*.pyc, existing zips and symbolic links are left out.
Every flag is listed in CLI → plugin.
:::danger plugin run executes your code in your own process
honeyframe plugin run loads the component's entry file and runs it in the CLI's own Python process, as your user, on your machine. It is not sandboxed: the code can read your files, use your network and see your credentials. Run only plugins you wrote or trust.
To limit exposure, the command hides every HONEYFRAME_* and HUB_* environment variable from the plugin for the duration of the run; --pass-env keeps them. On the platform, by contrast, plugins always run in an isolated subprocess without platform credentials, and the platform validates the descriptor again at install.
:::
Entry-file contracts
run calls a function by operation. The default operation follows the component type.
| Component type | Default --op | Your entry file defines | Returns |
|---|---|---|---|
recipe, transform | process | process(rows, params) | a list of dicts (new keys become new columns) |
connector | test | test(params), or sources(params) | a dict (test) or a list of dicts (sources) |
connector | read (--op read --source NAME) | read(params, source) | a list of dicts |
connector | sources | sources(params) | a list of dicts, at most 500 |
scenario_step | run_step | run(params) | a dict |
rows arrives as CSV semantics: a list of dicts whose values are all strings. process needs --input rows.csv; its output goes to --output or <input>.out.csv. read writes <component>.out.csv in the current directory unless --output is given. params comes from the --params JSON file.
A scaffolded recipe entry file looks like this:
def process(rows, params):
# rows: list[dict[str, str]]; params: the component's configured values.
tag = params.get("tag", "")
out = []
for r in rows:
r = dict(r)
r["tagged_by"] = tag
out.append(r)
return out
Using the kit from Python
The same functions are importable from honeyframeapi.plugin_dev:
from honeyframeapi import plugin_dev
plugin_id, files = plugin_dev.init_plugin("row-tagger", "recipe")
descriptor, errors = plugin_dev.load_and_validate("row-tagger")
if descriptor is None:
raise SystemExit("\n".join(errors))
print(plugin_dev.summarize_descriptor(descriptor))
summary, out_path = plugin_dev.run_component(
"row-tagger", "recipe", params={"tag": "qa"},
input_csv="rows.csv", pass_env=False, # hide HONEYFRAME_* / HUB_* variables
)
archive = plugin_dev.pack_plugin("row-tagger")
validate_descriptor(data, *, root=None)validates an already-parsed descriptor and returns(normalized_descriptor, errors); it never raises.run_component(plugin_dir, component_name, *, op=None, params=None, input_csv=None, source=None, output=None, pass_env=True)returns(summary, output_path). Note that the library default ispass_env=True; the CLI's default is to hide the variables.- Kit-level problems raise
plugin_dev.PluginDevError; errors from your entry file are re-raised unchanged.
After packing
Installing a packed plugin on a platform is an operator action; see Plugins → Installing and managing. Once a plugin that contributes recipe types is enabled for your organization, create its recipes from code with project.create_plugin_recipe; see dbt and recipes → Plugin recipes.
Verified against honeyframeapi 0.1.8.