Спецификация стадии¶
Спецификация стадии — YAML в её docstring: description, arguments,
outputs и визуальные подсказки для редактора.
description: "Increment numeric value by delta"
icon: "+" # глиф, ссылка на SVG, data-URI или <svg>-разметка
icon_mono: false # перекрасить SVG в цвет узла (монохромные наборы)
color: "#ff8800" # акцент карточки (по умолчанию — цвет категории)
icon принимает четыре формы:
| Значение | Что рисуется |
|---|---|
"+", "👋" |
глиф или эмодзи |
"/icons/globe.svg", "https://…/x.svg" |
SVG по ссылке |
"data:image/svg+xml;utf8,…" |
data-URI |
"<svg …>…</svg>" |
разметка из docstring |
icon_mono: true рисует SVG маской в цвет узла — для монохромных наборов
(lucide, feather, tabler), использующих currentColor. Без icon редактор
рисует монограмму из имени стадии (IncrementStage → IS), без color —
детерминированный цвет категории.
В get_specs() попадает ещё четыре вещи, и они задаются атрибутами
класса, а не ключами докстринга: category, timeout, allowed_events и
allowed_inputs (EventSpec / InputSpec с payload_schema).
| В докстринге | Атрибутом класса |
|---|---|
description, icon, icon_mono, color |
category |
arguments, outputs, reserve |
timeout |
allowed_events, allowed_inputs |
category: или timeout:, написанные в докстринге, разбираются и
отбрасываются, и ничто об этом не предупреждает. get_specs() отдаёт
значение атрибута, поэтому спека и дедлайн, который держит прогон, друг другу
не противоречат — заметить нечего. Стадия, которая просит timeout: 90 только
в докстринге, работает с дефолтом BaseStage, тридцатью секундами, и
редактору сообщают те же тридцать.
У прозы есть языки, у идентификаторов нет¶
В спеке всё — либо идентификатор, либо проза. Имя, тип, категория, счётчик,
цвет — идентификаторы, одинаковые на любом языке, и не переводятся никогда.
description самой стадии и description каждого аргумента, выхода, события и
входа — проза, а у прозы язык есть.
Поэтому любое из них может быть таблицей {локаль: текст} вместо строки:
description:
en: "Increment numeric value by delta"
ru: "Увеличивает число на delta"
arguments:
delta:
type: int
description:
en: "How much to add"
ru: "Насколько увеличить"
А get_specs() отдаёт все языки, какие есть, а не выбирает один:
>>> IncrementStage.get_specs()["description"]
{'en': 'Increment numeric value by delta', 'ru': 'Увеличивает число на delta'}
Именно эта форма нужна клиенту. Редактор забирает спеки один раз, а его читатель выбирает язык потом — и выбирает заново всякий раз, когда передумает, — так что спеку, уже сведённую к одному языку, приходилось бы забирать снова на каждое такое «передумал». Спека несёт выбор; выбирает тот, кто её рисует.
Проза на одном языке остаётся обычной строкой: таблица из одной записи была бы выбором, не несущим информации:
Явно названная локаль прозу сворачивает — для того, кто действительно отвечает одному читателю, а не обслуживает клиента:
Таблица — это весь механизм для горстки стадий. Для сотни каталог gettext
менее многословен, и встроенные стадии живут именно так — и о том и о другом в
Локализации.
Что стадия просит зарезервировать¶
reserve объявляет, сколько прогон стадии может израсходовать, в тех
счётчиках, которые считает хост. Значения — числа или CEL по
args, то есть по аргументам в том виде, в каком их получит стадия:
Это объявлено, а не вычислено, потому что читается до запуска стадии:
хост отказывает графу, который не может оплатить, не исполняя его, а
редактор показывает цифру на карточке. Сколько потрачено на самом деле,
сообщает сама стадия через self.charge(...) — и это уже код, потому что
правда известна только в конце.
Вот во что спецификация выше превращается на холсте: иконка, описание, аргументы, которые узел читает, и выходы, которые он пишет.
