Skip to content

Starlark API — Flow Manager

Все функции доступны внутри transformCodeNode и logicConditionNode. Язык — Starlark (Python-подобный sandboxed-язык).

Ограничения:

  • Таймаут выполнения: 30 секунд
  • Поддержка верхнеуровневых конструкций: if, for, while, и переназначения глобалов (TopLevelControl + While + GlobalReassign)
  • TLS-обязателен для fetch(), max body 10MB, таймаут 10с

Глобальные переменные

SANDBOX_DIR

Путь к постоянному каталогу-песочнице. Доступен как глобальная переменная и через ctx.SandboxDir. Используется для files.export() и artefacts.save().

python
print(SANDBOX_DIR)       # → ./sandbox
print(ctx.SandboxDir)    # → ./sandbox

Глобальные функции

Вывод лога. Все аргументы приводятся к строке и соединяются пробелами. Лог доступен через NATS-событие node.log.

python
print("Статус:", getVar("status"))
print("x =", 42, "y =", 100)

setVar(name, value)

Устанавливает переменную в общем контексте. Переменная становится доступна всем последующим нодам пайплайна.

python
setVar("user_id", 123)
setVar("status", "approved")

Ошибки:

  • Если передано не ровно 2 аргумента
  • Если первый аргумент не является строкой

getVar(name, [default])

Возвращает значение переменной из контекста. Если переменная не найдена и передан default — возвращает его. Если default не передан и переменной нет — ошибка.

python
user = getVar("user_id")
status = getVar("status", "pending")  # вернёт "pending", если переменной нет

Ошибки:

  • Переменная не найдена и default не передан: variable "X" not found

enumerate(iterable, [start])

Как в Python: возвращает список пар (index, value). start по умолчанию 0.

python
items = ["a", "b", "c"]
for i, x in enumerate(items):
    print(i, x)  # 0 a / 1 b / 2 c

for i, x in enumerate(items, start=1):
    print(i, x)  # 1 a / 2 b / 3 c

Ошибки:

  • Аргумент не итерируемый: enumerate: X object is not iterable

fetch(url, [method], [body], [headers], [params])

Выполняет HTTP-запрос. Поддерживает позиционные и именованные аргументы.

python
# GET-запрос
resp = fetch("https://api.example.com/users")
print(resp.status, resp.body)

# POST с JSON
resp = fetch("https://api.example.com/data", method="POST", body='{"key":"value"}')
data = resp.json()

# С заголовками
resp = fetch("https://api.example.com/auth", headers={"Authorization": "Bearer token"})

# Query-параметры объектом — экранируются автоматически
resp = fetch("https://api.example.com/search", params={"q": "hello world", "limit": 10})
# → https://api.example.com/search?limit=10&q=hello+world

Аргументы:

АргументТипПо умолчаниюОписание
urlstringURL запроса (обязательный)
methodstring"GET"HTTP-метод
bodystringNoneТело запроса
headersdict{}Заголовки запроса
paramsdictNoneQuery-параметры (см. ниже)

Query-параметры (params):

Ключи — строки, значения — строка, число, bool, список/кортеж или None.

python
# Список или кортеж — повторяющийся параметр
fetch(url, params={"tag": ["go", "python"]})   # ?tag=go&tag=python

# bool приводится к true/false, а не к питоновским True/False
fetch(url, params={"active": True})            # ?active=true

# None пропускается — удобно для опциональных параметров,
# не нужно вырезать ключ из словаря вручную
cursor = getVar("cursor", None)
fetch(url, params={"limit": 50, "cursor": cursor})  # ?limit=50, если cursor пуст

Параметры дополняют query, уже присутствующий в URL, а не затирают его:

python
fetch("https://api.example.com/list?page=1", params={"limit": 10})
# → https://api.example.com/list?page=1&limit=10

Возвращаемое значение FetchResult:

СвойствоТипОписание
.statusintHTTP-код статуса
.bodystringТело ответа как строка
.bytesbytesСырое тело ответа
.json()methodПарсит тело как JSON
.content_typestringЗначение заголовка Content-Type
.headersdictЗаголовки ответа (значения — списки строк)

Ошибки:

  • params не является словарём: fetch: 'params' must be a dict, got X
  • Нестроковый ключ: fetch: all 'params' keys must be strings, got X
  • Неподдерживаемый тип значения (например, вложенный dict): fetch: 'params' value for "key" must be a string, number or bool, got X

Сеть. Ограничений по адресам у fetch() нет — запрос уходит на любой указанный хост, включая внутренние/приватные адреса.


b64encode(value) / b64decode(value)

Кодирование/декодирование в стандартном base64.

  • b64encode(value) — принимает строку или bytes, возвращает base64-строку.
  • b64decode(value) — принимает base64-строку, возвращает декодированную строку.
python
token = b64encode("user:pass")          # "dXNlcjpwYXNz"
resp = fetch(
    "https://api.example.com/secure",
    headers={"Authorization": "Basic " + token},
)

original = b64decode("dXNlcjpwYXNz")     # "user:pass"

Ошибки:

  • b64encode: аргумент не строка и не bytesb64encode: argument must be a string or bytes, got X
  • b64decode: невалидный base64 — b64decode: invalid base64: ...

json_encode(value) / json_decode(value)

Сериализация Starlark-значения в JSON-строку и обратно.

  • json_encode(value) — принимает dict/list/скаляр (и вложенные структуры), возвращает JSON-строку.
  • json_decode(value) — принимает JSON-строку или bytes, возвращает dict/list/скаляр.
python
payload = {"object_kind": "push", "ref": "refs/heads/main"}
raw = json_encode(payload)              # '{"object_kind":"push","ref":"refs/heads/main"}'

event = json_decode(raw)
print(event["object_kind"])             # push

# типичный кейс: сырое тело webhook
body = ctx.trigger.body                 # строка
data = json_decode(body)

Ошибки:

  • json_encode: несериализуемое значение — json_encode: ...
  • json_decode: аргумент не строка и не bytesjson_decode: argument must be a string or bytes, got X
  • json_decode: невалидный JSON — json_decode: json parse error: ...

setupProcess(parallel, [workers], [stop_after_error])

Настраивает режим выполнения веток, создаваемых через runProcess(). Вызывается перед runProcess().

АргументТипОбязательныйПо умолчаниюОписание
parallelboolДаЗапускать ветки параллельно (true) или последовательно (false)
workersintНет0Максимальное количество параллельных веток (0 = без ограничений)
stop_after_errorboolНетfalseПри true — все ветки падают при ошибке в одной; при false — цепочка успешна, если хотя бы одна ветка завершилась успешно
python
# Параллельный запуск, падать при первой ошибке
setupProcess(True, stop_after_error=True)

for item in getVar("task_list"):
    runProcess({"task": item})
python
# Параллельный запуск с ограничением 3 веток
setupProcess(True, workers=3)

for team in ["backend", "frontend", "qa"]:
    runProcess({"team": team})
python
# Последовательный запуск, не падать при ошибках
setupProcess(False, stop_after_error=False)

for step in ["validate", "transform", "load"]:
    runProcess({"step": step})

runProcess([obj])

Запускает ветку выполнения. Параметр obj (обычно dict) используется для создания контекста ветки — ключи и значения мёржаются с клонированным контекстом.

Поведение:

  • Устанавливает ctx.StopFlow = true (текущая нода не продолжается)
  • Каждая ветка получает свой клон контекста (ctx.Clone()) с мёрджем данных из obj
  • Режим параллельности/последовательности определяется через setupProcess()
python
# Настроить параллельный запуск до 5 веток
setupProcess(parallel=True, workers=5)

teams = ["backend", "frontend", "qa", "devops"]
for team in teams:
    runProcess({"team": team, "action": "deploy"})
python
# Простой фан-аут без настройки (последовательно, без ограничений)
runProcess({"branch": "email"})
runProcess({"branch": "slack"})

Ошибки:

  • Если передано больше 1 аргумента

Контекст execution context

Контекст — это общее хранилище переменных, передаваемое между нодами пайплайна. Каждая нода получает клон контекста от предыдущей ноды, что позволяет ветвление с изолированными состояниями.

Жизненный цикл

  1. Инициализация — контекст создаётся при старте пайплайна. Источник: context из запроса или пустой {}.
  2. Передача — при переходе к следующей ноде контекст клонируется (ctx.Clone()).
  3. Ветвление — при runProcess() или logicConditionNode создаются независимые клоны для каждой ветки.
  4. Завершение — финальный контекст сохраняется в инстансе пайплайна.

Доступ к переменным

СпособОписание
ctx.get(key)Возвращает значение или None
ctx.set(key, value)Устанавливает значение
getVar(key, [default])Глобальная функция (эквивалент ctx.get)
setVar(key, value)Глобальная функция (эквивалент ctx.set)
python
# Через методы ctx
ctx.set("processed", True)
value = ctx.get("user_id")

# Через глобальные функции (эквивалентно)
setVar("processed", True)
value = getVar("user_id")

Встроенные переменные контекста

ctx.trigger (webhook / event)

Заполняется при старте пайплайна через inputHttpRequestNode или inputEventNode.

HTTP webhook (source: "http"):

КлючТипОписание
trigger.sourcestring"http"
trigger.methodstringHTTP-метод (POST, …)
trigger.bodystringСырое тело запроса
trigger.jsondict / list / скалярТело, распарсенное как JSON (если валидно)
trigger.querydictQuery-параметры
trigger.headersdictЗаголовки (только если в ноде включено «Добавлять заголовки»)
python
# Предпочтительно — уже распарсенный JSON
event = ctx.trigger.json
print(event["object_kind"])

# Или вручную из строки
event = json_decode(ctx.trigger.body)

NATS event (source: "event"): аналогично, payload доступен через ctx.trigger (см. inputEventNode).

artefacts (после jobNode)

После выполнения jobNode в контекст автоматически добавляется переменная artefacts — словарь со списками ID артефактов:

КлючТипОписание
artefacts.previouslist[string]Артефакты, созданные последним job-нодом
artefacts.alllist[string]Все артефакты, накопленные с начала пайплайна
python
# После jobNode — получить артефакты из контекста
prev = getVar("artefacts")["previous"]
all_ = getVar("artefacts")["all"]

print("Артефакты этого шага:", prev)
print("Все артефакты:", all_)

Пример: передача артефакта между нодами

python
# Нода 1 (после jobNode): артефакт уже в контексте
artifact_id = getVar("artefacts")["previous"][0]

# Нода 2: читаем файл из артефакта
data = artefacts.read(artifact_id, "result.json")
print(data)

Артефакты (artefacts)

Глобальный модуль для работы с артефактами (ZIP-файлы в storage-сервисе). Доступен как глобальная переменная artefacts.

Для сохранения артефактов beyond выполнения пайплайна используйте artefacts.save() — он извлекает ZIP-архив в постоянный каталог {SANDBOX_DIR}/{pipeline_id}/.

artefacts.list(artefact_id)

Возвращает список имён файлов в артефакте.

python
files = artefacts.list("550e8400-e29b-41d4-a716-446655440000")
for f in files:
    print(f)  # "data.csv", "result.json"

Возвращаемое значение: list[string] — имена файлов


artefacts.read(artefact_id, filename)

Читает содержимое файла из артефакта.

python
data = artefacts.read(artefact_id, "data.csv")
print("Прочитано символов:", len(data))

Возвращаемое значение: string


artefacts.extract(artefact_id, [dest])

Извлекает все файлы из артефакта во временный каталог.

python
# В текущий рабочий каталог (ARTIFACTS_TMP_DIR/<instance_id>)
artefacts.extract(artefact_id)

# В указанную поддиректорию
artefacts.extract(artefact_id, "my_data")

Аргументы:

АргументТипПо умолчаниюОписание
artefact_idstringUUID артефакта (обязательный)
deststringтекущий каталогПоддиректория относительно рабочего каталога (опциональный)

Возвращаемое значение: string — путь куда распаковано


artefacts.create(files)

Создаёт новый ZIP-артефакт из файлов на диске и загружает его в storage.

python
# Из файлов в рабочем каталоге
artifact_id = artefacts.create([
    "output/result.txt",
    "output/meta.json",
])

# С явным указанием имён
artifact_id = artefacts.create([
    {"name": "result.txt", "path": "output/result.txt"},
    {"name": "data.json", "path": "output/data.json"},
])
print("Создан артефакт:", artifact_id)

Аргументы:

АргументТипОписание
fileslist[string | dict]Список путей к файлам или словарей {"name": string, "path": string}

Возвращаемое значение: string — UUID созданного артефакта


artefacts.save(artefact_id, name, [dest_dir], [extract])

Сохраняет артефакт в постоянный каталог-песочницу (SANDBOX_DIR/{pipeline_id}/). По умолчанию ZIP-архив сохраняется как файл. С extract=True — распаковывается в директорию. Файлы, сохранённые через эту функцию, не удаляются после завершения выполнения пайплайна.

python
# Сохранение ZIP-архива как файла
artefacts.save(artefact_id, "workspace.zip")
# → SANDBOX_DIR/{pipeline_id}/workspace.zip

# Сохранение в поддиректорию
artefacts.save(artefact_id, "build.zip", "releases")
# → SANDBOX_DIR/{pipeline_id}/releases/build.zip

# Распаковка артефакта в директорию
artefacts.save(artefact_id, "source", extract=True)
# → SANDBOX_DIR/{pipeline_id}/source/file1.txt
# → SANDBOX_DIR/{pipeline_id}/source/file2.txt

# Распаковка в поддиректорию
artefacts.save(artefact_id, "code", "projects", extract=True)
# → SANDBOX_DIR/{pipeline_id}/projects/code/file1.txt

Аргументы:

АргументТипОбязательныйПо умолчаниюОписание
artefact_idstringДаUUID артефакта
namestringДаИмя файла или директории
dest_dirstringНет""Поддиректория относительно {SANDBOX_DIR}/{pipeline_id}/
extractboolНетfalseРаспаковать ZIP в директорию с именем name

Возвращаемое значение: string — полный путь куда сохранено

Ограничения:

  • name не может содержать .. или / (защита от path traversal)
  • dest_dir не может содержать ..
  • Максимальный распакованный размер: 1 GiB
  • Переменная SANDBOX_DIR должна быть настроена в конфигурации

Платформенный клиент (up)

Глобальный модуль для доступа к API всех сервисов платформы. Доступен как глобальная переменная up. Использует Service Token для межсервисного взаимодействия.

Доступные подмодули

ПодмодульОписание
up.authАутентификация и управление пользователями
up.spacesУправление пространствами
up.documentsУправление документами
up.commandsУправление командами и задачами
up.schedulerУправление календарями и событиями
up.storageРабота с файловым хранилищем
up.propsУправление свойствами
up.gatewayПроверка состояния платформы
up.flow_managerУправление пайплайнами, шаблонами и инстансами
up.spark_gridМедиа-файлы и теги (spark-grid)
up.ai_routerAI-провайдеры, чаты, completions и RAG

Методы загрузки файлов (storage.upload, spark_grid.upload_file), требующие потокового тела запроса, из Starlark недоступны — используйте модули files и artefacts для работы с файлами внутри пайплайна.


up.auth

up.auth.login(login, password)

Авторизация пользователя.

python
resp = up.auth.login("user@example.com", "password123")
print(resp)

up.auth.register(login, email, password, [first_name, last_name])

Регистрация нового пользователя.

python
resp = up.auth.register("newuser", "user@example.com", "pass123", "Иван", "Петров")

up.auth.logout()

Выход из системы.

python
up.auth.logout()

up.auth.refresh()

Обновление сессии.

python
resp = up.auth.refresh()

up.auth.get_profile()

Получение профиля текущего пользователя.

python
profile = up.auth.get_profile()
print(profile["login"], profile["email"])

up.auth.update_profile([login], [first_name], [last_name])

Обновление профиля пользователя.

python
up.auth.update_profile(first_name="Новое Имя")

up.auth.change_password(current_password, new_password)

Смена пароля.

python
up.auth.change_password("old_pass", "new_pass")

up.auth.check_login_availability(login)

Проверяет, свободен ли логин. Возвращает bool.

python
free = up.auth.check_login_availability("newuser")

up.auth.get_user_sessions()

Список активных сессий текущего пользователя.

python
sessions = up.auth.get_user_sessions()

up.auth.terminate_session(session_id)

Завершает указанную сессию.

python
up.auth.terminate_session("session-id")

up.auth.terminate_all_sessions()

Завершает все сессии, кроме текущей.

python
up.auth.terminate_all_sessions()

up.auth.get_oauth_providers()

Список привязанных OAuth-провайдеров.

python
providers = up.auth.get_oauth_providers()

up.auth.get_oauth_url(provider)

Возвращает URL авторизации для OAuth-провайдера (строка).

python
url = up.auth.get_oauth_url("google")

up.auth.create_access_token(name, [note], [ttl])

Создаёт персональный access-токен. note и ttl — именованные аргументы.

python
token = up.auth.create_access_token("CI token", note="для деплоя", ttl="720h")

up.auth.get_access_tokens()

Список access-токенов пользователя.

python
tokens = up.auth.get_access_tokens()

up.auth.revoke_access_token(token_id)

Отзывает access-токен.

python
up.auth.revoke_access_token("token-uuid")

Публичный список пользователей.

python
users = up.auth.get_public_users(limit=20, search="иван")

up.auth.get_public_user(user_id)

Публичная информация о пользователе по ID.

python
user = up.auth.get_public_user("user-uuid")

up.auth.get_admin_users([offset], [limit], [status], [role], [search], [sort_by], [sort_order])

Список пользователей для админа (требуется роль admin).

python
users = up.auth.get_admin_users(status="active", role="user", limit=50)

up.auth.get_admin_user(user_id)

Детальная информация о пользователе для админа (требуется роль admin).

python
user = up.auth.get_admin_user("user-uuid")

up.auth.update_admin_user(user_id, [email], [first_name], [last_name], [login], [role], [status])

Обновление пользователя админом (требуется роль admin). Поля — именованные аргументы.

python
up.auth.update_admin_user("user-uuid", role="admin", status="active")

up.auth.update_admin_user_status(user_id, status)

Изменение статуса пользователя админом (требуется роль admin).

python
up.auth.update_admin_user_status("user-uuid", "blocked")

up.spaces

up.spaces.create(name)

Создание нового пространства.

python
space = up.spaces.create("Мой проект")
print(space["id"])

up.spaces.list()

Получение списка пространств.

python
spaces = up.spaces.list()
for s in spaces:
    print(s["name"])

up.spaces.get(space_id)

Получение пространства по ID.

python
space = up.spaces.get("space-uuid")

up.spaces.update(space_id, name)

Переименование пространства.

python
up.spaces.update("space-uuid", "Новое имя")

up.spaces.delete(space_id)

Удаление пространства.

python
up.spaces.delete("space-uuid")

up.spaces.share(space_id, user_id)

Предоставление доступа к пространству.

python
up.spaces.share("space-uuid", "user-uuid")

up.spaces.unshare(space_id, user_id)

Отзыв доступа к пространству.

python
up.spaces.unshare("space-uuid", "user-uuid")

up.documents

up.documents.create(space_id, name, body, type, [parent_id])

Создание документа.

python
doc = up.documents.create(
    "space-uuid",
    "Новый документ",
    "Содержимое документа",
    "text",
    "parent-uuid"  # опционально
)

up.documents.get(space_id, document_id)

Получение документа.

python
doc = up.documents.get("space-uuid", "doc-uuid")
print(doc["body"])

up.documents.list(space_id)

Список документов в пространстве.

python
docs = up.documents.list("space-uuid")

up.documents.tree(space_id)

Дерево документов.

python
tree = up.documents.tree("space-uuid")

up.documents.update(space_id, document_id, [name], [body], [type], [parent_id])

Обновление документа.

python
up.documents.update("space-uuid", "doc-uuid", name="Обновленное имя")

up.documents.delete(space_id, document_id)

Мягкое удаление документа.

python
up.documents.delete("space-uuid", "doc-uuid")

up.documents.hard_delete(space_id, document_id)

Полное удаление документа.

python
up.documents.hard_delete("space-uuid", "doc-uuid")

up.documents.restore(space_id, document_id)

Восстановление документа.

python
up.documents.restore("space-uuid", "doc-uuid")

up.documents.move(space_id, document_id, parent_id)

Перемещение документа.

python
up.documents.move("space-uuid", "doc-uuid", "new-parent-uuid")

up.documents.duplicate(space_id, document_id, [name])

Дублирование документа.

python
up.documents.duplicate("space-uuid", "doc-uuid", "Копия документа")

up.documents.add_favorite(space_id, document_id)

Добавляет документ в избранное.

python
up.documents.add_favorite("space-uuid", "doc-uuid")

up.documents.get_favorites(space_id)

Список избранных документов пользователя в пространстве.

python
favs = up.documents.get_favorites("space-uuid")

up.documents.remove_favorite(space_id, document_id)

Убирает документ из избранного.

python
up.documents.remove_favorite("space-uuid", "doc-uuid")

up.commands

up.commands.create(name, description, type, source, [variables], [tags])

Создание команды.

python
cmd = up.commands.create(
    "Деплой",
    "Скрипт деплоя на прод",
    "shell",
    "./deploy.sh",
    variables=[{"name": "env", "description": "Окружение", "type": "string", "default": "staging"}],
    tags=["deploy", "prod"]
)

up.commands.list([offset], [limit], [search], [type], [tag], [sort_by], [sort_order])

Список команд.

python
cmds = up.commands.list(search="деплой", limit=10)

up.commands.get(command_id)

Получение команды.

python
cmd = up.commands.get("cmd-uuid")

up.commands.update(command_id, [name], [description], [type], [source])

Обновление команды.

python
up.commands.update("cmd-uuid", name="Новое имя")

up.commands.delete(command_id)

Удаление команды.

python
up.commands.delete("cmd-uuid")

up.commands.share(command_id, users)

Предоставление доступа к команде.

python
up.commands.share("cmd-uuid", [{"user_id": "user-uuid", "role": "executor"}])

up.commands.create_job(command_id, [status], [variables])

Создание задачи.

python
job = up.commands.create_job("cmd-uuid", variables=[{"name": "env", "value": "production"}])

up.commands.get_jobs([offset], [limit], [status], [command_id])

Получение списка задач.

python
jobs = up.commands.get_jobs(status="completed", limit=5)

up.commands.get_job(job_id)

Получение задачи.

python
job = up.commands.get_job("job-uuid")

up.commands.stop_job(job_id)

Остановка задачи.

python
up.commands.stop_job("job-uuid")

up.commands.get_job_logs(job_id, [offset], [limit])

Получение логов задачи.

python
logs = up.commands.get_job_logs("job-uuid", limit=100)

up.commands.remove_shared_user(command_id, user_id)

Убирает пользователя из доступа к команде.

python
up.commands.remove_shared_user("cmd-uuid", "user-uuid")

up.commands.create_collection(name, description, [visible])

Создание коллекции команд. visible — именованный аргумент (bool).

python
coll = up.commands.create_collection("Деплой-скрипты", "Прод-деплой", visible=True)

up.commands.get_collections([include_hidden])

Список коллекций пользователя.

python
colls = up.commands.get_collections(include_hidden=True)

up.commands.get_collection(collection_id, [include_hidden])

Коллекция вместе с командами и вложенными коллекциями.

python
coll = up.commands.get_collection("coll-uuid")

up.commands.update_collection(collection_id, [name], [description], [visible])

Обновление коллекции (поля — именованные аргументы).

python
up.commands.update_collection("coll-uuid", name="Новое имя")

up.commands.delete_collection(collection_id)

Удаление коллекции.

python
up.commands.delete_collection("coll-uuid")

up.commands.share_collection(collection_id, user_id, role)

Предоставление доступа к коллекции.

python
up.commands.share_collection("coll-uuid", "user-uuid", "executor")

up.commands.remove_collection_shared_user(collection_id, user_id)

Отзыв доступа к коллекции.

python
up.commands.remove_collection_shared_user("coll-uuid", "user-uuid")

up.commands.add_command_to_collection(collection_id, command_id)

Добавление команды в коллекцию.

python
up.commands.add_command_to_collection("coll-uuid", "cmd-uuid")

up.commands.add_child_collection(parent_collection_id, child_collection_id)

Добавление вложенной коллекции.

python
up.commands.add_child_collection("parent-uuid", "child-uuid")

up.commands.remove_child_collection(parent_collection_id, child_collection_id)

Удаление вложенной коллекции.

python
up.commands.remove_child_collection("parent-uuid", "child-uuid")

up.commands.remove_command_from_collection(collection_id, command_id)

Удаление команды из коллекции.

python
up.commands.remove_command_from_collection("coll-uuid", "cmd-uuid")

up.commands.create_job_as(user_id, command_id, [status], [variables])

Создание задачи от имени пользователя (Service Token + X-User-ID). status и variables — именованные аргументы.

python
job = up.commands.create_job_as("user-uuid", "cmd-uuid",
    variables=[{"name": "env", "value": "production"}])

up.commands.update_job(job_id, [status], [runner_id], [variables])

Обновление задачи (поля — именованные аргументы).

python
up.commands.update_job("job-uuid", status="stopped")

up.commands.delete_job(job_id)

Удаление задачи.

python
up.commands.delete_job("job-uuid")

up.commands.get_runners([offset], [limit])

Список раннеров (требуется роль admin).

python
runners = up.commands.get_runners(limit=50)

up.commands.get_runner(runner_id)

Информация о раннере, включая поддерживаемые переменные.

python
runner = up.commands.get_runner("runner-uuid")

up.commands.pause_runner(runner_id)

Мягкая пауза раннера: текущие задачи завершаются, новые не назначаются (требуется роль admin).

python
up.commands.pause_runner("runner-uuid")

up.commands.resume_runner(runner_id)

Возобновление работы раннера (требуется роль admin).

python
up.commands.resume_runner("runner-uuid")

up.commands.check_condition(condition, [variables])

Вычисляет условие с переданными переменными. Возвращает {"result": bool}.

python
res = up.commands.check_condition("env == 'prod'", {"env": "prod"})
print(res["result"])  # True

up.commands.validate_condition(condition)

Проверяет корректность выражения-условия. Возвращает {"valid": bool, "error": string}.

python
res = up.commands.validate_condition("env == 'prod'")

up.scheduler

up.scheduler.create_calendar(name, description, color, visibility)

Создание календаря.

python
cal = up.scheduler.create_calendar("Рабочий", "Рабочие события", "#4285F4", "private")

up.scheduler.list_calendars()

Список календарей.

python
cals = up.scheduler.list_calendars()

up.scheduler.get_calendar(calendar_id)

Получение календаря.

python
cal = up.scheduler.get_calendar("cal-uuid")

up.scheduler.update_calendar(calendar_id, [name], [description], [color], [visibility])

Обновление календаря.

python
up.scheduler.update_calendar("cal-uuid", name="Новое имя")

up.scheduler.delete_calendar(calendar_id)

Удаление календаря.

python
up.scheduler.delete_calendar("cal-uuid")

up.scheduler.share_calendar(calendar_id, user_id)

Предоставление доступа к календарю.

python
up.scheduler.share_calendar("cal-uuid", "user-uuid")

up.scheduler.unshare_calendar(calendar_id, user_id)

Отзыв доступа к календарю.

python
up.scheduler.unshare_calendar("cal-uuid", "user-uuid")

up.scheduler.create_event(calendar_id, title, description, start_at, end_at, [location], [all_day])

Создание события.

python
event = up.scheduler.create_event(
    "cal-uuid",
    "Совещание",
    "Обсуждение проекта",
    "2024-01-15T10:00:00Z",
    "2024-01-15T11:00:00Z",
    location="Конференц-зал"
)

up.scheduler.get_events(calendar_id, [from], [to])

Получение событий.

python
events = up.scheduler.get_events("cal-uuid", from="2024-01-01T00:00:00Z", to="2024-01-31T23:59:59Z")

up.scheduler.get_event(event_id)

Получение события.

python
event = up.scheduler.get_event("event-uuid")

up.scheduler.update_event(event_id, [title], [description], [start_at], [end_at])

Обновление события.

python
up.scheduler.update_event("event-uuid", title="Новое название")

up.scheduler.delete_event(event_id)

Удаление события.

python
up.scheduler.delete_event("event-uuid")

up.storage

up.storage.list([offset], [limit], [category], [sort_by], [sort_order])

Список файлов.

python
files = up.storage.list(category="artefacts", limit=10)

up.storage.get(file_id)

Получение информации о файле.

python
file_info = up.storage.get("file-uuid")

up.storage.get_url(file_id)

Получение URL для скачивания файла.

python
url = up.storage.get_url("file-uuid")
print(url)

up.storage.delete(file_id)

Удаление файла.

python
up.storage.delete("file-uuid")

up.storage.download(file_id)

Скачивает содержимое файла. Возвращает dict с полями bytes (сырые байты), content_type и file_name.

python
res = up.storage.download("file-uuid")
files.write("output/" + res["file_name"], res["bytes"])

up.storage.get_public(file_id)

Скачивает публичный файл (аватары, иконки пространств) без авторизации. Возвращает bytes.

python
data = up.storage.get_public("file-uuid")

up.props

up.props.create(name, value, [description])

Создание свойства.

python
prop = up.props.create("api_key", "sk-123456", "API ключ для внешнего сервиса")

up.props.list([offset], [limit], [search], [sort_by], [sort_order])

Список свойств.

python
props = up.props.list(search="api")

up.props.get(prop_id)

Получение свойства.

python
prop = up.props.get("prop-uuid")

up.props.update(prop_id, [name], [description], [value])

Обновление свойства.

python
up.props.update("prop-uuid", value="new-api-key")

up.props.delete(prop_id)

Удаление свойства.

python
up.props.delete("prop-uuid")

up.props.list_for_user(user_id, [offset], [limit], [search], [sort_by], [sort_order])

Список свойств указанного пользователя (Service Token + X-User-ID). Опции — именованные аргументы.

python
props = up.props.list_for_user("user-uuid", search="api")

up.props.share(prop_id, user_id)

Предоставление доступа к свойству.

python
up.props.share("prop-uuid", "user-uuid")

up.props.unshare(prop_id, user_id)

Отзыв доступа к свойству.

python
up.props.unshare("prop-uuid", "user-uuid")

up.gateway

up.gateway.health()

Проверка здоровья платформы.

python
health = up.gateway.health()
print(health)

up.gateway.ready()

Проверка готовности платформы.

python
ready = up.gateway.ready()

up.gateway.live()

Проверка доступности платформы.

python
live = up.gateway.live()

up.gateway.services()

Получение списка сервисов.

python
services = up.gateway.services()
for svc in services:
    print(svc["name"], svc["status"])

up.flow_manager

Управление пайплайнами, их версионными шаблонами и инстансами.

up.flow_manager.create_pipeline(name, [description])

Создание пайплайна.

python
pipe = up.flow_manager.create_pipeline("ETL", description="Ночная загрузка")

up.flow_manager.get_pipelines([offset], [limit], [search], [sort_by], [sort_order])

Список пайплайнов пользователя.

python
pipes = up.flow_manager.get_pipelines(search="etl", limit=10)

up.flow_manager.get_pipeline(pipeline_id)

Получение пайплайна по ID.

python
pipe = up.flow_manager.get_pipeline("pipeline-uuid")

up.flow_manager.update_pipeline(pipeline_id, [name], [description])

Обновление пайплайна (поля — именованные аргументы).

python
up.flow_manager.update_pipeline("pipeline-uuid", name="ETL v2")

up.flow_manager.delete_pipeline(pipeline_id)

Удаление пайплайна.

python
up.flow_manager.delete_pipeline("pipeline-uuid")

up.flow_manager.test_pipeline([template], [context])

Тестовый прогон пайплайна в памяти. template и context — словари (позиционно или именованно).

python
res = up.flow_manager.test_pipeline(
    template={"nodes": [], "edges": []},
    context={"user_id": 123},
)
print(res["run_id"], res["status"])

up.flow_manager.create_template(pipeline_id, template)

Создание новой версии шаблона пайплайна.

python
tpl = up.flow_manager.create_template("pipeline-uuid", {"nodes": [], "edges": []})

up.flow_manager.get_templates(pipeline_id)

Все версии шаблонов пайплайна.

python
tpls = up.flow_manager.get_templates("pipeline-uuid")

up.flow_manager.get_template(pipeline_id, version)

Конкретная версия шаблона.

python
tpl = up.flow_manager.get_template("pipeline-uuid", 3)

up.flow_manager.create_instance(pipeline_id, template_id, [context])

Создание инстанса пайплайна из шаблона.

python
inst = up.flow_manager.create_instance("pipeline-uuid", "template-uuid",
    context={"batch": "2024-01"})

up.flow_manager.get_instance(instance_id)

Получение инстанса по ID.

python
inst = up.flow_manager.get_instance("instance-uuid")

up.flow_manager.try_code_node(pipeline_id, template_id, code, [variables], [context])

Изолированный тестовый запуск code-ноды. variables и context — словари (именованные аргументы).

python
res = up.flow_manager.try_code_node("pipeline-uuid", "template-uuid",
    "setVar('x', 1)", context={"env": "test"})
print(res["success"], res["logs"])

up.flow_manager.try_job_node(pipeline_id, template_id, command_id, [variables])

Изолированный тестовый запуск job-ноды. variables — список {"name": ..., "value": ...}.

python
res = up.flow_manager.try_job_node("pipeline-uuid", "template-uuid", "cmd-uuid",
    variables=[{"name": "env", "value": "staging"}])

up.spark_grid

Работа с медиа-файлами и тегами сервиса spark-grid. Все методы требуют доступа к пространству (space_id).

up.spark_grid.list_files(space_id, [offset], [limit], [mime_type], [order_by], [order_direction], [tag_ids])

Список медиа-файлов в пространстве. tag_ids — список UUID-строк.

python
files_ = up.spark_grid.list_files("space-uuid", mime_type="image/png", limit=20)

up.spark_grid.get_file(space_id, file_id)

Метаданные медиа-файла.

python
media = up.spark_grid.get_file("space-uuid", "file-uuid")

up.spark_grid.download_file(space_id, file_id, [inline])

Скачивание содержимого файла. Возвращает dict с bytes, content_type, file_name.

python
res = up.spark_grid.download_file("space-uuid", "file-uuid")
files.write("output/media.bin", res["bytes"])

up.spark_grid.soft_delete_file(space_id, file_id)

Мягкое удаление медиа-файла.

python
up.spark_grid.soft_delete_file("space-uuid", "file-uuid")

up.spark_grid.hard_delete_file(space_id, file_id)

Полное удаление медиа-файла.

python
up.spark_grid.hard_delete_file("space-uuid", "file-uuid")

up.spark_grid.download_cover(space_id, file_id, cover_id, [inline])

Скачивание обложки/превью. Возвращает dict с bytes, content_type, file_name.

python
cover = up.spark_grid.download_cover("space-uuid", "file-uuid", "cover-uuid", inline=True)

up.spark_grid.replace_file_tags(space_id, file_id, tag_ids)

Заменяет все теги файла. tag_ids — список UUID-строк.

python
up.spark_grid.replace_file_tags("space-uuid", "file-uuid", ["tag-uuid-1", "tag-uuid-2"])

up.spark_grid.add_file_tag(space_id, file_id, tag_id)

Добавляет тег к файлу.

python
up.spark_grid.add_file_tag("space-uuid", "file-uuid", "tag-uuid")

up.spark_grid.remove_file_tag(space_id, file_id, tag_id)

Убирает тег с файла.

python
up.spark_grid.remove_file_tag("space-uuid", "file-uuid", "tag-uuid")

up.spark_grid.create_tag(space_id, name, color)

Создание тега в пространстве.

python
tag = up.spark_grid.create_tag("space-uuid", "Обложки", "#FF5733")

up.spark_grid.list_tags(space_id)

Список тегов пространства.

python
tags = up.spark_grid.list_tags("space-uuid")

up.spark_grid.update_tag(space_id, tag_id, [name], [color])

Обновление тега (поля — именованные аргументы).

python
up.spark_grid.update_tag("space-uuid", "tag-uuid", color="#00FF00")

up.spark_grid.delete_tag(space_id, tag_id)

Удаление тега и всех связей.

python
up.spark_grid.delete_tag("space-uuid", "tag-uuid")

up.ai_router

AI-провайдеры, chat completions, чаты с сообщениями и RAG (база знаний).

Для типовых сценариев в редакторе flow есть нативные AI-ноды (aiChatCompletionNode, aiRagSearchNode, aiRagIngestNode, aiAgentNode, aiProvidersNode). Они не заменяют up.ai_router — Code-нода остаётся для кастомной логики поверх того же API.

Retrieval в AI Router — hybrid: PostgreSQL FTS + pgvector, RRF, опционально query rewrite / LLM-rerank / multi-hop. Подробности пайплайна и env-флаги — в ai-router.md.

При send_message(..., scope=...) в чат подмешивается anti-hallucination system prompt и tool search_knowledge_base; ответы должны опираться на документы и цитировать Source: «…».

up.ai_router.list_providers([with_chats_count], [with_chats_tree])

Список провайдеров вызывающего пользователя.

python
providers = up.ai_router.list_providers(with_chats_count=True)

up.ai_router.list_available_providers()

Список типов провайдеров, поддерживаемых сервисом.

python
types = up.ai_router.list_available_providers()  # ["openai", "anthropic", ...]

up.ai_router.get_provider(provider_id)

Провайдер по ID.

python
provider = up.ai_router.get_provider("provider-uuid")

up.ai_router.get_provider_models(provider_id)

Список моделей, доступных у провайдера.

python
models = up.ai_router.get_provider_models("provider-uuid")

up.ai_router.create_provider(name=, type=, [api_key=], [base_url=], [default_model=])

Регистрация провайдера (admin). Все аргументы — именованные; name и type обязательны.

python
provider = up.ai_router.create_provider(
    name="OpenAI prod", type="openai",
    api_key="sk-...", default_model="gpt-4o",
)

# Yandex AI Studio / Alice AI — OpenAI-compatible endpoint
# (подробнее: ai-router.md → «Yandex AI Studio»)
provider = up.ai_router.create_provider(
    name="Yandex AI",
    type="openai",
    api_key="<YC_API_KEY>",
    base_url="https://ai.api.cloud.yandex.net/v1",
    default_model="gpt://<folder_id>/yandexgpt/latest",
)

up.ai_router.update_provider(provider_id, [name], [api_key], [base_url], [default_model], [is_active])

Обновление провайдера (admin). Поля — именованные аргументы.

python
up.ai_router.update_provider("provider-uuid", is_active=False)

up.ai_router.delete_provider(provider_id)

Удаление провайдера (admin).

python
up.ai_router.delete_provider("provider-uuid")

up.ai_router.chat_completion(messages, [provider], [model], [max_tokens], [temperature], [tools])

Chat completion. messages — список {"role": ..., "content": ...} (позиционно или messages=); tools — список описаний инструментов.

python
resp = up.ai_router.chat_completion(
    [{"role": "user", "content": "Привет!"}],
    provider="openai", model="gpt-4o", max_tokens=500,
)
print(resp["content"], resp["usage"]["total_tokens"])

up.ai_router.list_requests()

Список AI-запросов вызывающего пользователя.

python
reqs = up.ai_router.list_requests()
print(reqs["total"])

up.ai_router.get_request(request_id)

Один AI-запрос по ID.

python
req = up.ai_router.get_request("request-uuid")

up.ai_router.get_user_stats()

Статистика использования вызывающего пользователя.

python
stats = up.ai_router.get_user_stats()
print(stats["total_tokens"])

up.ai_router.create_chat(provider_id, [title], [model])

Создание чата под провайдером. title и model — именованные аргументы.

python
chat = up.ai_router.create_chat("provider-uuid", title="Поддержка", model="gpt-4o")

up.ai_router.list_chats(provider_id)

Список чатов под провайдером.

python
chats = up.ai_router.list_chats("provider-uuid")

up.ai_router.get_chat(provider_id, chat_id)

Чат по ID.

python
chat = up.ai_router.get_chat("provider-uuid", "chat-uuid")

up.ai_router.update_chat(provider_id, chat_id, title)

Переименование чата.

python
up.ai_router.update_chat("provider-uuid", "chat-uuid", "Новое название")

up.ai_router.delete_chat(provider_id, chat_id)

Удаление чата.

python
up.ai_router.delete_chat("provider-uuid", "chat-uuid")

up.ai_router.send_message(provider_id, chat_id, content, [thinking], [tools], [scope])

Отправка сообщения в чат; возвращает финальный ответ ассистента. tools — список строк (имена tool'ов), scope — RAG-скоуп для поиска по базе знаний (включает search_knowledge_base и дефолтный RAG system prompt).

python
msg = up.ai_router.send_message("provider-uuid", "chat-uuid",
    "Какой лимит ретраев у RGS?",
    scope="docs",
    tools=["search_knowledge_base"],
)
print(msg["content"])

up.ai_router.get_messages(provider_id, chat_id)

Все сообщения чата.

python
msgs = up.ai_router.get_messages("provider-uuid", "chat-uuid")

up.ai_router.ingest_document(scope=, content=, [title=], [content_type=], [metadata=])

Загрузка документа в базу знаний (RAG). Аргументы — именованные; scope и content обязательны. Текст очищается от HTML/шума, режется на чанки, индексируется в pgvector и FTS.

АргументТипОписание
scopestringОбласть знаний
contentstringТекст документа
titlestringЗаголовок (попадает в Source: «…» при поиске)
content_typestringtext (default), markdown или html
metadatadictДоп. поля чанков: category, author, date, …
python
res = up.ai_router.ingest_document(
    scope="docs",
    title="FAQ",
    content="<h1>FAQ</h1><p>Текст...</p>",
    content_type="html",
    metadata={"category": "support", "author": "team", "date": "2026-07-30"},
)
print(res["chunk_count"])

up.ai_router.list_scopes()

Список RAG-скоупов с document_count, alias, description, system_prompt.

python
scopes = up.ai_router.list_scopes()

up.ai_router.delete_scope(scope)

Очистка RAG-скоупа: удаляет чанки и документы текущего пользователя для указанного scope, обновляет document_count. Настройки скоупа (alias, description, system prompt) не удаляются.

python
up.ai_router.delete_scope("docs")

Файлы (files)

Глобальный модуль для работы с файлами в рабочем каталоге пайплайна. Доступен как глобальная переменная files. Все пути разрешаются относительно рабочего каталога (ARTIFACTS_TMP_DIR/<instance_id>).

Для сохранения файлов beyond выполнения пайплайна используйте files.export() — он копирует файлы в постоянный каталог {SANDBOX_DIR}/{pipeline_id}/.

files.list([path])

Возвращает список файлов и директорий.

python
items = files.list()          # корень рабочего каталога
items = files.list("output")  # поддиректория output
for item in items:
    print(item["name"], item["size"], item["is_dir"])

Возвращаемое значение: list[dict] — список {"name": string, "size": int, "is_dir": bool}


files.read(path)

Читает содержимое файла.

python
data = files.read("output/result.txt")
print(data)

Возвращаемое значение: string


files.write(path, data)

Записывает данные в файл (создаёт родительские директории автоматически).

python
files.write("output/report.txt", "Hello World")
files.write("output/config.json", '{"key": "value"}')

Поддерживаемые типы данных: string, bytes


files.delete(path)

Удаляет файл или директорию.

python
files.delete("output/old_file.txt")
files.delete("output/old_dir")

files.mkdir(path)

Создаёт директорию (включая родительские).

python
files.mkdir("output/subdir")

files.export(src, [dest_dir])

Копирует файл или директорию из временного рабочего каталога в постоянный каталог-песочницу (SANDBOX_DIR/{pipeline_id}/). Файлы, экспортированные через эту функцию, не удаляются после завершения выполнения пайплайна.

python
# Экспорт файла в корень песочницы
files.export("output/build.tar.gz")
# → SANDBOX_DIR/{pipeline_id}/output/build.tar.gz

# Экспорт файла в указанную поддиректорию
files.export("output/report.pdf", "/reports")
# → SANDBOX_DIR/{pipeline_id}/reports/output/report.pdf

# Экспорт всей директории
files.export("build/", "/exports")
# → SANDBOX_DIR/{pipeline_id}/exports/build/...

Аргументы:

АргументТипПо умолчаниюОписание
srcstringПуть к файлу или директории во временном каталоге (обязательный)
dest_dirstring""Поддиректория относительно {SANDBOX_DIR}/{pipeline_id}/ (опциональный)

Возвращаемое значение: string — полный путь куда скопировано

Ограничения:

  • src должен существовать в рабочем каталоге
  • dest_dir не может содержать .. (защита от path traversal)
  • Переменная SANDBOX_DIR должна быть настроена в конфигурации