using System.Diagnostics; using System.Text; using Azaion.CommonSecurity.DTO; using Azaion.CommonSecurity.DTO.Commands; using MessagePack; using NetMQ; using NetMQ.Sockets; namespace Azaion.CommonSecurity.Services; public interface IResourceLoader { MemoryStream LoadFileFromPython(string fileName); void StopPython(); } public interface IAuthProvider { User CurrentUser { get; } } public class PythonResourceLoader : IResourceLoader, IAuthProvider { private readonly ApiCredentials _credentials; private readonly AzaionApiClient _api; private readonly DealerSocket _dealer = new(); private readonly Guid _clientId = Guid.NewGuid(); public User CurrentUser { get; } public PythonResourceLoader(ApiConfig apiConfig, ApiCredentials credentials, AzaionApiClient api) { _credentials = credentials; _api = api; //StartPython(apiConfig, credentials); _dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N")); _dealer.Connect($"tcp://{SecurityConstants.ZMQ_HOST}:{SecurityConstants.ZMQ_PORT}"); _dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.GetUser))); var user = _dealer.Get(); if (user == null) throw new Exception("Can't get user from Auth provider"); CurrentUser = user; } private void StartPython( ApiConfig apiConfig, ApiCredentials credentials) { using var process = new Process(); process.StartInfo = new ProcessStartInfo { FileName = SecurityConstants.AZAION_INFERENCE_PATH, Arguments = $"-e {credentials.Email} -p {credentials.Password} -f {apiConfig.ResourcesFolder}", //UseShellExecute = false, //RedirectStandardOutput = true, // RedirectStandardError = true, //CreateNoWindow = true }; process.OutputDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; process.ErrorDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; process.Start(); } public void StopPython() { _dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Exit))); _dealer?.Close(); } public MemoryStream LoadFileFromPython(string fileName) { try { _dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Load, fileName))); if (!_dealer.TryReceiveFrameBytes(TimeSpan.FromSeconds(3), out var bytes)) throw new Exception($"Unable to receive {fileName}"); return new MemoryStream(bytes); } catch (Exception ex) { throw new Exception($"Failed to load fil0e '{fileName}': {ex.Message}", ex); } } }