Authoring 1: Scaffold & register

A plugin is a small Python package that adds widgets (and more) to led-ticker without changing core. Over these four pages you’ll build one — example.counter, a deliberately tiny widget that shows the number of days since a date (no data, no async; real plugins like the pool widget fetch live data and render richer screens) — then survey everything else you can contribute.
A plugin is just a module that exposes a register(api) function. led-ticker calls it once at startup and hands you an api object; you call methods on it to register your contributions.
Prerequisites
Section titled “Prerequisites”You’ll work inside a led-ticker checkout:
- Clone it and run
make dev— this creates a local.venv/(nothing installed globally) and puts theled-tickercommand on itsPATH. - Your plugins live in
config/plugins/, next toconfig/config.toml. - To run
led-ticker plugins(below): with that venv active, runled-ticker pluginsdirectly; under Docker, rundocker compose exec led-ticker led-ticker plugins.
The smallest plugin that loads
Section titled “The smallest plugin that loads”-
Create a file for your plugin. A plugin can be a single
.pyfile or a package directory:example/__init__.py -
Add a
register(api)that does nothing yet:example/__init__.py def register(api):pass
Make led-ticker discover it
Section titled “Make led-ticker discover it”Put the file under your config’s plugins directory (default config/plugins/):
config/plugins/example/__init__.pyThe plugin’s namespace is its file/dir name — here, example.
Ship it as an installable package declaring a led_ticker.plugins entry point (covered in
Package & install):
[project.entry-points."led_ticker.plugins"]example = "example:register"The entry-point name (example) is the namespace.
Verify it loads
Section titled “Verify it loads”Run:
led-ticker pluginsYour example namespace should appear in the list (with no contributions yet).
Namespaces
Section titled “Namespaces”Everything a plugin registers is namespaced by <plugin>.<name>, so plugins never collide with core or each other. The widget you build next, registered as counter, becomes example.counter in config — type = "example.counter".