Manifest Reference¶
This document provides complete reference for plugin manifests and entry points.
PluginEntry¶
A PluginEntry defines a single plugin within a manifest.
from lightfall.plugins import PluginEntry
entry = PluginEntry(
type_name="settings",
name="my_settings",
import_path="my_package.plugins:MySettingsPlugin",
metadata={"priority": 10},
preload=False,
)
Attributes¶
Attribute |
Type |
Required |
Description |
|---|---|---|---|
|
|
Yes |
Plugin type identifier (e.g., “settings”, “panel”) |
|
|
Yes |
Unique name within this type |
|
|
Yes |
Python import path in format |
|
|
No |
Additional plugin-specific metadata |
|
|
No |
If |
import_path Format¶
The import_path must be in the format module.path:ClassName:
# Correct
"my_package.plugins.settings:MySettingsPlugin"
"lightfall.ui.preferences.builtin:AppearanceSettingsPlugin"
# Incorrect - missing class name
"my_package.plugins.settings"
# Incorrect - wrong separator
"my_package.plugins.settings.MySettingsPlugin"
unique_id Property¶
Each entry has a unique_id property combining type and name:
entry = PluginEntry("settings", "my_settings", "...")
print(entry.unique_id) # "settings:my_settings"
Preload Plugins¶
Plugins with preload=True are loaded synchronously before the main window:
# Theme should apply before any windows appear
PluginEntry(
type_name="theme",
name="light",
import_path="lightfall.ui.theme.builtin:LightThemePlugin",
preload=True,
)
# Appearance settings loads saved theme on startup
PluginEntry(
type_name="settings",
name="appearance",
import_path="lightfall.ui.preferences.builtin:AppearanceSettingsPlugin",
preload=True,
)
Use preload for:
Themes (must apply before UI renders)
Settings that affect initial appearance
Panels that must be registered before window creation
PluginManifest¶
A PluginManifest groups multiple PluginEntry objects from a single source.
from lightfall.plugins import PluginManifest, PluginEntry
manifest = PluginManifest(
name="my-beamline-plugins",
version="1.0.0",
description="Custom plugins for beamline 7.0.1.1",
plugins=[
PluginEntry("plan", "my_scan", "my_beamline.plans:MyScanPlan"),
PluginEntry("plan", "my_align", "my_beamline.plans:MyAlignPlan"),
PluginEntry("settings", "beamline_config", "my_beamline.settings:Config"),
],
metadata={"author": "Beamline Team"},
)
Attributes¶
Attribute |
Type |
Required |
Description |
|---|---|---|---|
|
|
Yes |
Manifest identifier |
|
|
No |
Version string (default: “0.0.0”) |
|
|
No |
Human-readable description |
|
|
No |
List of plugin entries |
|
|
No |
Additional metadata |
Methods¶
get_plugins_by_type(type_name)¶
Filter plugins by type:
plans = manifest.get_plugins_by_type("plan")
# Returns list of PluginEntry with type_name="plan"
get_plugin_types()¶
Get all unique plugin types in the manifest:
types = manifest.get_plugin_types()
# Returns {"plan", "settings"}
Entry Points¶
External packages register manifests via Python entry points in pyproject.toml:
[project.entry-points."lightfall.plugins"]
my_beamline = "my_beamline.manifest:manifest"
Entry Point Group¶
All Lightfall plugin manifests use the group lightfall.plugins.
Entry Point Format¶
Name: Any unique identifier for your manifest
Value: Python import path to a
PluginManifestinstance
# Format: name = "module.path:variable_name"
[project.entry-points."lightfall.plugins"]
my_plugins = "my_package.manifest:manifest"
other_plugins = "my_package.other:other_manifest"
Manifest Module Example¶
# my_package/manifest.py
from lightfall.plugins import PluginManifest, PluginEntry
manifest = PluginManifest(
name="my-package",
version="1.0.0",
plugins=[
PluginEntry("plan", "my_scan", "my_package.plans:MyScanPlan"),
],
)
Discovery Process¶
On startup, PluginLoader discovers manifests:
Load the built-in manifest directly
Discover entry points in group
lightfall.pluginsLoad each entry point to get its
PluginManifestProcess all plugin entries from all manifests
Queue plugins for loading
# Simplified discovery code
from importlib.metadata import entry_points
eps = entry_points(group="lightfall.plugins")
for ep in eps:
manifest = ep.load() # Returns PluginManifest instance
for entry in manifest.plugins:
# Queue plugin for loading
...
Complete Example¶
Package Structure¶
my_beamline/
├── pyproject.toml
├── src/
│ └── my_beamline/
│ ├── __init__.py
│ ├── manifest.py # Plugin manifest
│ ├── plans/
│ │ ├── __init__.py
│ │ └── scans.py # Plan plugins
│ └── settings/
│ ├── __init__.py
│ └── config.py # Settings plugin
pyproject.toml¶
[project]
name = "my-beamline"
version = "1.0.0"
dependencies = ["lightfall"]
[project.entry-points."lightfall.plugins"]
my_beamline = "my_beamline.manifest:manifest"
manifest.py¶
from lightfall.plugins import PluginManifest, PluginEntry
manifest = PluginManifest(
name="my-beamline",
version="1.0.0",
description="Beamline 7.0.1.1 plugins",
plugins=[
PluginEntry(
type_name="plan",
name="grid_scan",
import_path="my_beamline.plans.scans:GridScanPlan",
),
PluginEntry(
type_name="settings",
name="beamline_config",
import_path="my_beamline.settings.config:BeamlineConfigPlugin",
),
],
)
See External Packages for more details on creating distributable plugin packages.