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

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

Статус

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


Обзор

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

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

Ключевое отличие Python от Lua/JS: скрипт исполняется не в процессе бэкенда, а отправляется HTTP-запросом на внешний Python Executor.


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

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

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

Версия инкрементируется при каждом изменении. Подробнее: docs/domains/smart-actions/js-jint-patterns.md §0.


Архитектура

Точка входа

SmartScriptService.EvaluateSmartScript(SmartScriptDto, ...) — ветвление по языку:

smartScript.Language == Python
    → EvaluatePythonSmartScript → PythonScriptEngine.ExecuteScript(...)
    → HTTP POST → Python Executor → результат

smartScript.Language == JavaScript
    → EvaluateJSSmartScript → JsScriptEngine.ExecuteScript(...)

smartScript.Language == Lua (default)
    → EvaluateLuaSmartScript → LuaScriptEngine.ExecuteScript(...)

Файл: TCClassLib/Smart/Scripting/SmartScriptService.cs

Ключевые классы

Класс Файл Роль
PythonScriptEngine Engine/PythonScriptEngine.cs HTTP-клиент к Python Executor
PythonExecutorSettings настройки из ServiceSettingsEntity ApiUrl, ApiKey
SmartScriptService Smart/Scripting/SmartScriptService.cs Маршрутизация Lua/JS/Python

Протокол исполнения

Запрос к Python Executor

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

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

Ответ

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

При ошибке:

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

Обработка ошибок

  • HTTP-ошибка (5xx, timeout) → TCLogicException
  • Status: "error"TCLogicException с текстом из Error
  • Отсутствие настроек (ApiUrl не задан) → TCLogicException

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

Бэкенд собирает контекст из SmartScriptDto.Context с фильтрацией типов:

Тип значения Что передаётся
EntityBase Только .Id (int)
Примитивы (string, int, bool, DateTime) As-is
Коллекции (List, Dictionary) Только если содержат JSON-сериализуемые элементы
Объекты (сложные CLR) Пропускаются

Автоматически добавляется session_user_id из IContext.

Шаблон по умолчанию для нового скрипта:

def execute(ctx):
    pass

Конфигурация

Настройки хранятся в ServiceSettingsEntity (БД PythonExecutorServiceSettingsEntity):

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

Timeout запроса: 30 секунд (фиксированный).


Frontend (AdminSPA)

С версии 2.268.38 редактор смарт-скриптов (EditLuaExpressionComponent) поддерживает Python:

  • Monaco переключается на lang="python" через маппинг scriptTypeToMonacoLang
  • Шаблон по умолчанию: def execute(ctx):
  • Выбор языка: dropdown с пятью опциями (Lua, JavaScript, Python, OneScript, C#)

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

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

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


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

  • docs/domains/smart-actions/js-scripting-jint.md — JS-движок (Jint)
  • docs/domains/smart-actions/backend.md — архитектура смарт-действий
  • docs/domains/smart-actions/faq-lua-pcall-error-handling.md — проблемы NLua на .NET 9