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