2025-09-30 17:10:02 +00:00
|
|
|
using BotSharp.Abstraction.Models;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Python.Runtime;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace BotSharp.Plugin.PythonInterpreter.Services;
|
|
|
|
|
|
|
|
|
|
public class PyInterpretService : ICodeInterpretService
|
|
|
|
|
{
|
|
|
|
|
private readonly IServiceProvider _services;
|
|
|
|
|
private readonly ILogger<PyInterpretService> _logger;
|
|
|
|
|
|
|
|
|
|
public PyInterpretService(
|
|
|
|
|
IServiceProvider services,
|
|
|
|
|
ILogger<PyInterpretService> logger)
|
|
|
|
|
{
|
|
|
|
|
_services = services;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string Provider => "python-interpreter";
|
|
|
|
|
|
2025-10-01 01:45:32 +00:00
|
|
|
public async Task<CodeInterpretResult> RunCode(string codeScript, CodeInterpretOptions? options = null)
|
2025-09-30 17:10:02 +00:00
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (Py.GIL())
|
|
|
|
|
{
|
|
|
|
|
// Import necessary Python modules
|
|
|
|
|
dynamic sys = Py.Import("sys");
|
|
|
|
|
dynamic io = Py.Import("io");
|
|
|
|
|
|
|
|
|
|
// Redirect standard output/error to capture it
|
|
|
|
|
dynamic stringIO = io.StringIO();
|
|
|
|
|
sys.stdout = stringIO;
|
|
|
|
|
sys.stderr = stringIO;
|
|
|
|
|
|
|
|
|
|
// Set global items
|
|
|
|
|
using var globals = new PyDict();
|
2025-09-30 20:26:32 +00:00
|
|
|
if (codeScript.Contains("__main__") == true)
|
2025-09-30 17:10:02 +00:00
|
|
|
{
|
|
|
|
|
globals.SetItem("__name__", new PyString("__main__"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set arguments
|
2025-10-01 01:45:32 +00:00
|
|
|
if (options?.Arguments?.Any() == true)
|
2025-09-30 17:10:02 +00:00
|
|
|
{
|
2025-09-30 20:03:06 +00:00
|
|
|
var list = new PyList();
|
|
|
|
|
list.Append(new PyString("code.py"));
|
2025-09-30 17:10:02 +00:00
|
|
|
|
2025-10-01 01:45:32 +00:00
|
|
|
foreach (var arg in options.Arguments)
|
2025-09-30 17:10:02 +00:00
|
|
|
{
|
2025-09-30 20:03:06 +00:00
|
|
|
if (!string.IsNullOrWhiteSpace(arg.Key) && !string.IsNullOrWhiteSpace(arg.Value))
|
|
|
|
|
{
|
|
|
|
|
list.Append(new PyString($"--{arg.Key}"));
|
|
|
|
|
list.Append(new PyString($"{arg.Value}"));
|
|
|
|
|
}
|
2025-09-30 17:10:02 +00:00
|
|
|
}
|
2025-09-30 20:03:06 +00:00
|
|
|
sys.argv = list;
|
2025-09-30 17:10:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute Python script
|
2025-09-30 20:26:32 +00:00
|
|
|
PythonEngine.Exec(codeScript, globals);
|
2025-09-30 17:10:02 +00:00
|
|
|
|
|
|
|
|
// Get result
|
2025-10-01 01:45:32 +00:00
|
|
|
var result = stringIO.getvalue()?.ToString() as string;
|
2025-09-30 17:10:02 +00:00
|
|
|
|
|
|
|
|
// Restore the original stdout/stderr
|
|
|
|
|
sys.stdout = sys.__stdout__;
|
|
|
|
|
sys.stderr = sys.__stderr__;
|
|
|
|
|
|
|
|
|
|
return new CodeInterpretResult
|
|
|
|
|
{
|
2025-10-01 01:45:32 +00:00
|
|
|
Result = result?.TrimEnd('\r', '\n'),
|
2025-09-30 17:10:02 +00:00
|
|
|
Success = true
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2025-09-30 21:03:58 +00:00
|
|
|
var errorMsg = $"Error when executing python code in {nameof(PyInterpretService)}: {Provider}. {ex.Message}";
|
2025-09-30 17:10:02 +00:00
|
|
|
_logger.LogError(ex, errorMsg);
|
|
|
|
|
|
|
|
|
|
return new CodeInterpretResult
|
|
|
|
|
{
|
|
|
|
|
Success = false,
|
|
|
|
|
ErrorMsg = errorMsg
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|