Источники Node и Python¶
Иногда нужные вам данные скрыты за кодом, который ваша команда уже написала: модель скоринга, клиент внутреннего сервиса, скрипт, приводящий в порядок выгрузку. Источник Node или Python позволяет отдавать этот код в виде таблиц. Вы помечаете функции, которыми хотите поделиться, указываете Provisa, где лежит код, и каждая помеченная функция становится таблицей, которую любая роль читает по тем же правилам, что и любую другую таблицу.
Во что превращается функция¶
Provisa читает объявления самого кода: теги JSDoc и типы TypeScript для Node, docstring и аннотации типов для Python. Значение имеют три тега.
| Тег | Становится |
|---|---|
@table |
Таблицей. Функция возвращает список или итерируемый объект, и каждый элемент — это строка |
@command |
Командой, которая выполняется по запросу |
@stream |
Живой таблицей. Функция — генератор, и каждая строка отправляется, как только она выдана |
Функция без тега игнорируется. Незнакомый Provisa тег отклоняется, как и тип, который он не может отобразить. Отказ называет функцию и перечисляет все проблемы сразу, так что вы исправляете их за один проход.
Тип строки задаёт столбцы. Текст, числа, логические значения, даты и метки времени отображаются в свои типы столбцов, списки остаются списками, а вложенные объекты становятся именованными типами. Когда тип строки нестрогий (any, unknown или Record в TypeScript, Any или dict в Python), Provisa один раз вызывает функцию без аргументов и предлагает столбцы по вернувшимся строкам. Если у функции есть обязательный параметр, так её вызвать нельзя, и столбцы вы типизируете сами при регистрации таблицы.
Параметры функции становятся параметрами таблицы. Параметр без значения по умолчанию обязателен, поэтому чтение без него отклоняется ещё до запуска вашего кода. Параметр со значением по умолчанию необязателен; если его опустить, применяется ваше значение по умолчанию. Стюард всё равно может сделать необязательный параметр обязательным.
Откуда берётся код¶
Код закреплён, поэтому источник всегда выполняет ровно то, что было зарегистрировано:
- Пакет: пакет npm для Node или пакет PyPI для Python, точной версии.
- Git-репозиторий: полный коммит из 40 символов, с подкаталогом, если код лежит не в корне.
- Загрузка: архив
.zip,.tgzили.tar.gzс кодом.
Код Node выполняется на Node.js, Bun или Deno — на ваш выбор. Код Python выполняется на Python, который поставляется с Provisa. Если у кода больше одного модуля Python верхнего уровня, укажите в поле Входной модуль, через какой в него входить.
Установка зависимостей¶
Коду с зависимостями нужен lockfile, и каждая установка следует ему в точности. Без него пакет, объявляющий зависимости, отклоняется, и отказ подсказывает добавить lockfile.
| Среда выполнения | Lockfile |
|---|---|
| Node.js | package-lock.json или npm-shrinkwrap.json |
| Bun | bun.lock или bun.lockb |
| Deno | deno.lock |
| Python | uv.lock (со своим pyproject.toml), pylock.toml или requirements.txt с --hash в каждой строке |
Опубликованный пакет редко содержит свой lockfile, поэтому форма принимает его рядом со ссылкой на пакет.
Ни одному пакету не разрешено запускать собственные скрипты установки: npm устанавливает с --ignore-scripts, а Python ставит только wheels и никогда не собирает из дистрибутива исходного кода.
Пакеты берутся из собственных реестров вашей организации, если они есть. Администратор один раз вносит ваши реестры npm, индексы PyPI и хосты Git в разделе Admin → Реестры пакетов, и каждый источник Node и Python организации устанавливается через них. Публичному реестру npm и публичному PyPI запись не нужна. См. Реестры пакетов.
Установка кэшируется по хэшу содержимого кода, так что один и тот же код устанавливается один раз.
Песочница¶
Ваш код выполняется в собственном рабочем процессе, в песочнице. Он может читать свой установленный код и больше ничего на диске. Он достаёт только до хостов из списка разрешённого исходящего трафика развёртывания, через прокси, который запускает Provisa, и никогда — до собственных портов Provisa. Хост, который не может обеспечить песочницу, отказывается запускать рабочий процесс и называет, чего не хватает, вместо того чтобы выполнить код без ограничений. В Windows источники кода отклоняются.
Чтение таблицы¶
Таблица источника кода загружается в хранилище, а не читается на месте. Provisa вызывает функцию с аргументами чтения, проверяет каждую строку по столбцам и хранит строки под этими аргументами в течение TTL кэша таблицы. Затем к загруженным строкам применяются видимость, маски и правила строк, как к любой таблице.
Аргументы передаются как любой параметр таблицы: условиями _nf_ в SQL и аргументами полей в GraphQL.
Пример¶
Этот модуль Python оценивает, насколько вероятно, что клиент уйдёт:
from dataclasses import dataclass
from datetime import datetime
@dataclass
class RiskRow:
account_id: str
score: float
computed_at: datetime
reasons: list[str]
def churn_risk(account_id: str, as_of: datetime | None = None) -> list[RiskRow]:
"""Churn risk of one account.
@table
"""
...
Зарегистрируйте его как источник python из пакета PyPI, коммита Git или загрузки. Обнаружение затем предложит churn_risk как таблицу с четырьмя столбцами (account_id, score, computed_at, reasons), обязательным параметром account_id и необязательным as_of. Когда стюард зарегистрирует таблицу, читайте её в SQL:
Та же функция на TypeScript выглядит так: