Перейти к основному содержимому

Быстрый старт

dagstack/plugin-system — универсальный реестр плагинов для приложений любого домена, которым нужны подключаемые точки расширения. Типичные сценарии: источники данных, обработчики событий, notification-каналы, authentication-провайдеры, шаги пайплайна, интеграции с внешними системами. Плагины находятся в каталоге по манифестам, загружаются в реестр и вызываются через один из пяти классов диспетчеризации (singleton, broadcast-collect, broadcast-notify, chain, capability).

:::info Статус публикации Пакеты Python и TypeScript готовятся к публикации на PyPI и npmjs.org. Пока доступны из внутреннего репозитория. Go-реализация — в дорожной карте; в примерах ниже показана планируемая сигнатура. :::

Установка

:::warning Зрелость реализаций Полноценный runtime на сегодня есть только для Python. TypeScript — в разработке: опубликованы эмитируемые из спецификации константы и типы, runtime появится в следующих релизах. Go — в дорожной карте; примеры ниже показывают планируемую сигнатуру на основе language-agnostic спецификации (см. ADR-0001..0006). :::

pip install dagstack-plugin-system

Первый плагин

Минимальный рабочий плагин состоит из двух файлов в отдельной папке: манифеста dagstack.toml и модуля реализации.

Манифест плагина

Манифест декларирует вид (kind), имя, исполняющую среду (runtime) и совместимую версию ядра.

plugins/echo/dagstack.toml
[plugin]
name = "echo"
kind = "tool"
runtime = "in_process"
core_version = ">=0.1.0,<1.0.0"

Реализация плагина

plugins/echo/plugin.py
from dagstack.plugin_system import PluginContext


class EchoPlugin:
"""Returns the input message wrapped under the `echoed` key.

Mirrors the canonical `examples/echo_plugin.EchoTool` shipped
with the binding. Both sync and async `setup` / `teardown` are
accepted by the registry; the published example uses sync.
"""

def setup(self, context: PluginContext) -> None:
self._ctx = context

def execute(self, args: dict) -> dict:
return {"echoed": args["msg"]}

def teardown(self) -> None:
self._ctx = None

Обнаружение и загрузка реестра

Функция discover(path) рекурсивно сканирует каталог, находит все папки с dagstack.toml, валидирует манифесты и возвращает реестр с загруженными плагинами. Метод setup_all() выполняет инициализацию каждого плагина с учётом зависимостей между ними (топологическая сортировка).

import asyncio
import logging
from dagstack.plugin_system import PluginContext, PluginRegistry


async def main() -> None:
registry = PluginRegistry()
registry.discover("plugins/")

ctx = PluginContext(
config={},
logger=logging.getLogger("app"),
registry=registry,
)
await registry.setup_all(ctx)

for manifest in registry.list_manifests():
print(manifest.kind, manifest.name)

await registry.teardown_all()


asyncio.run(main())

Вызов плагина

Плагины получают через реестр по сочетанию kind + name. Возвращённый объект — это прокси, который применяет правила диспетчеризации, инъекцию ресурсов и проверки контракта.

echo = registry.get_plugin("tool", name="echo")
result = echo.execute({"msg": "hello"})
assert result == {"echoed": "hello"}

Что дальше

Понятия — как устроены основные компоненты:

Руководства — как решать типовые задачи:

Справочник — точные таблицы для быстрого поиска:

Спецификация — нормативные архитектурные решения:

Справочник API (генерация отложена до выхода реализаций в stable):