Move away from Python Interop for better stability

This commit is contained in:
2026-03-09 17:11:59 -07:00
parent 52c5062d6e
commit ac67be137c
8 changed files with 134 additions and 60 deletions
+26 -36
View File
@@ -1,65 +1,55 @@
using Python.Runtime;
using Controllers.Processes;
namespace Controllers.PythonInterop {
public class AIModule {
public AIModule(string PythonPathBase = "/usr/local/", string PythonVersion = "python3.11") {
// Use the user provided python runner
Runtime.PythonDLL = PythonPathBase + $"lib/lib{PythonVersion}.so";
string _PyPath = "";
string _ExecPath = "";
// Use our local environment for the python libraries
PythonEngine.PythonHome = PythonPathBase;
// Include all the paths for python packages most importantly our venv
PythonEngine.PythonPath = $"{PythonPathBase}lib/{PythonVersion}:{PythonPathBase}lib/{PythonVersion}/lib-dynload:{PythonPathBase}lib/{PythonVersion}/site-packages:{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AIPython")}";
// Initiilize python
PythonEngine.Initialize();
// Needed because C# calls the python from each connections worker thread
PythonEngine.BeginAllowThreads();
public AIModule() {
_PyPath = "/usr/bin/python3.11";
_ExecPath = $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AIPython")}";
}
public void PullAI() {
using (Py.GIL()) {
dynamic datapuller = Py.Import("datapuller");
using (datapuller.pull()){ }
(bool, string) Success = PyProcess.RunPythonProcess(_PyPath, _ExecPath + "/datapuller.py");
if (!Success.Item1) {
Console.WriteLine(Success.Item2);
}
}
public void TrainAI() {
using (Py.GIL()) {
dynamic trainer = Py.Import("ai-trainer");
using (trainer.TrainAI()){ }
(bool, string) Success = PyProcess.RunPythonProcess(_PyPath, _ExecPath + "/aitrainer.py");
if (!Success.Item1) {
Console.WriteLine(Success.Item2);
}
}
// Return ( Error, Signal )
public (string, int) PredictAI(string StockSymbol) {
try {
using (Py.GIL()) {
dynamic predictor = Py.Import("ai-predictor");
using (dynamic x = predictor.Predict(StockSymbol)) {
int result = (int)x;
return ("", result);
}
(bool, string) Success = PyProcess.RunPythonProcess(_PyPath, _ExecPath + "/aipredictor.py", returns: true, PyArgs: StockSymbol);
if (!Success.Item1) {
return (Success.Item2, 0);
} else {
if (int.TryParse(Success.Item2, out int parsed)) {
return ("", parsed);
}
} catch (Exception ex) {
return (ex.ToString(), 0);
return ("Python returns an unknown value", 0);
}
}
public float GetCurrentPrice(string StockSymbol) {
using (Py.GIL()) {
dynamic price = Py.Import("currentprice");
using (dynamic x = price.getCurrentPrice(StockSymbol)) {
float CurrentPrice = (float)x;
return x;
(bool, string) Success = PyProcess.RunPythonProcess(_PyPath, _ExecPath + "/currentprice.py", returns: true, PyArgs: StockSymbol);
if (!Success.Item1) {
return 0;
} else {
if (float.TryParse(Success.Item2, out float parsed)) {
return parsed;
}
return 0;
}
}
}
}