Перейти к содержанию

Python — внешний исполнитель для смарт-скриптов

Python-скриптинг в 1Форме реализован через внешний HTTP-сервис Python Executor, на который платформа отправляет код смарт-скрипта. Ниже описаны протокол обмена, настройки подключения, состав передаваемого контекста и отличия Python от остальных языков смарт-скриптов (Lua, JavaScript, OneScript, C#).

Статус и обзор

Реализовано. Python-скриптинг доступен в продакшене с версии 2.268.35. Frontend-редактор поддерживает выбор Python в v2.268.38.

Платформа поддерживает пять языков смарт-скриптов:

Язык Движок ScriptLanguage (enum) LanguageId (БД) Модель исполнения
Lua NLua Lua = 0 0 Внутри платформы
JavaScript Jint 4.6.0 JavaScript = 1 1 Внутри платформы
Python Python Executor (HTTP) Python = 2 2 Внешний сервис
OneScript OneScript OneScript = 3 3 Внутри платформы
C# Roslyn Scripting 4.12 CSharp = 4 4 Внутри платформы

Ключевое отличие Python от Lua и JavaScript: скрипт исполняется не внутри платформы, а отправляется HTTP-запросом на внешний сервис Python Executor.


Версионирование Python SmartScript — обязательно

Каждый Python SmartScript обязан содержать комментарий с версией и датой в начале скрипта. Правило версионирования критично для отладки и отката: без явной версии невозможно определить, какой код выполнялся на момент инцидента.

# v1 | 2026-03-08 15:30 | Начальная версия
# v2 | 2026-03-08 16:45 | Добавлена проверка прав

Версия увеличивается при каждом изменении. Соглашение о версионировании единое для всех языков смарт-скриптов — подробнее в разделе Паттерны JS-скриптов.


Как платформа выполняет Python-скрипт

Когда смарт-действие запускает скрипт с языком Python, платформа определяет язык скрипта, собирает контекст и отправляет код на внешний сервис Python Executor по HTTP. Результат выполнения возвращается обратно и используется в смарт-действии. Скрипты на остальных языках (Lua, JavaScript, OneScript, C#) платформа выполняет сама, без обращения к внешнему сервису.

Протокол обмена с Python Executor

Запрос к Python Executor:

POST {PythonExecutor.ApiUrl}/execute/code
Headers:
  Content-Type: application/json
  X-Api-Key: {ApiKey}   (если настроен)

Body:
{
  "ScriptCode": "def execute(ctx):\n    return ctx['CONTEXT']",
  "Context": { ... },
  "Timeout": 30
}

Ответ при успешном выполнении:

{
  "Status": "ok",
  "Result": 12345,
  "Output": "debug output...",
  "DurationMs": 42
}

Ответ при ошибке:

{
  "Status": "error",
  "Error": "NameError: name 'foo' is not defined",
  "Output": "",
  "DurationMs": 5
}

Обработка ошибок. Платформа прерывает смарт-действие с ошибкой в следующих случаях: сетевая ошибка или таймаут при обращении к сервису; ответ со статусом error (текст ошибки берётся из поля Error); не задан адрес сервиса (ApiUrl).


Контекст скрипта

Python-скрипт получает данные только через объект ctx. Платформа собирает контекст и передаёт его в скрипт, отфильтровывая значения по типу:

Тип значения Что передаётся
Объекты платформы (задача, пользователь и т.п.) Только идентификатор (Id)
Примитивы (строка, число, логическое значение, дата) Передаются как есть
Коллекции (списки, словари) Только если содержат значения, пригодные для передачи в JSON
Сложные объекты Пропускаются

Ключи ctx

Ключ Тип Когда присутствует Значение
DB_TYPE str всегда MSSQL или PG — тип СУБД площадки
EVENTPARAMS dict всегда параметры события, по которому запущен скрипт; вне события — пустой словарь
EVENTPARAMS_NATIVE list если скрипт запущен по событию те же параметры в исходном виде
CONTEXT int если у скрипта задан тип контекста Id контекстного объекта — задачи, пользователя или письма, в зависимости от типа контекста
SESSION_USER int если скрипт запущен с контекстом Id пользователя, от имени которого выполняется скрипт
session_user_id int то же дубль SESSION_USER

Ключа SYSTEM_INFO (версия платформы и приложение) в Python нет: платформа его формирует, но объект такого типа не сериализуется в JSON и отбрасывается при сборке контекста.

Пример — идентификатор текущей задачи (тип контекста скрипта «Задача»):

def execute(ctx):
    return ctx.get("CONTEXT")

Шаблон, который редактор подставляет при создании скрипта на Python, — одна строка def execute(ctx):; тело функции дописывается вручную.


Возврат результата и вывод

Результат скрипта определяется двумя способами, приоритет — у первого:

  1. Если в скрипте определена функция execute(ctx), платформа вызывает её и берёт возвращённое значение.
  2. Иначе результатом становится переменная result, если она задана в скрипте.

Вывод print() в результат не входит: сервис возвращает вывод и строковое представление результата в поле Output ответа, а редактор показывает его в панели вывода (вкладки «Сообщения» и «Результат»).


Конфигурация и Frontend (AdminSPA)

Настройки подключения к Python Executor хранятся в настройках сервиса:

Параметр Описание
ApiUrl URL Python Executor (например, http://python-executor:8000)
ApiKey API-ключ для авторизации (опционально)

Timeout запроса — 30 секунд. Значение задано константой движка: в отличие от JavaScript и C#, лимит Python настройкой не переопределяется.

Создание скрипта и выбор языка (AdminSPA). Язык выбирается при создании скрипта — в диалоге создания автоматизации, поле «Режим редактирования»: Lua, JavaScript, Python, OneScript, C#. В самом редакторе переключателя языка нет: выбранный язык показан в тулбаре текстом, по нему включаются подсветка синтаксиса, расширение при скачивании кода и шаблон новой заготовки (для Python — def execute(ctx):).

Редактор смарт-скрипта в AdminSPA: язык скрипта в тулбаре, кнопки «Выполнить» и «Библиотека», поле кода и история версий


Сравнение с Lua/JS

Ключевые отличия Python от языков, выполняемых внутри платформы:

Аспект Lua (NLua) JavaScript (Jint) Python (Executor)
Модель Внутри платформы Внутри платформы Внешний HTTP-сервис
Sandbox Ограниченный Строгий Список разрешённых имён и модулей; код исполняется в процессе сервиса
Таймаут 5 мин 5 мин 30 сек
API-объекты платформы (SQL, SMART, CACHE, REGISTRY, FILES) Доступны Доступны Недоступны — только данные из ctx
Внешний HTTP Доступен Доступен Доступен через requests / httpx
Библиотеки (include) Да Да Нет
Возврат результата RESULT = value RESULT = value return из execute(ctx) либо переменная result
Зависимости NLua + Lua DLL Нет (pure .NET) Python Executor (Docker)

Ограничения Python: объекты API платформы недоступны — SQL, SMART, CACHE, REGISTRY, FILES и платформенная обёртка над HTTP. Скрипт оперирует данными из контекста и стандартной библиотекой Python; внешний HTTP-вызов возможен напрямую сетевой библиотекой (requests, httpx), а обращение к БД — нет. Для работы с БД и смарт-действиями рекомендуются Lua или JavaScript.

Состав песочницы и полный перечень доступных из скрипта модулей описаны в документации самого сервиса. Пакеты, установленные в образе, и пакеты, разрешённые скрипту, — разные списки: часть библиотек нужна только внутренним обработчикам сервиса и из смарт-скрипта недоступна.


Связанные документы домена Smart Actions

Документация по другим языкам смарт-скриптов: