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, string? folder = null); void StopPython(); } public interface IAuthProvider { User CurrentUser { get; } } public class PythonResourceLoader : IResourceLoader, IAuthProvider { private readonly DealerSocket _dealer = new(); private readonly Guid _clientId = Guid.NewGuid(); public User CurrentUser { get; set; } = null!; public PythonResourceLoader(PythonConfig config) { StartPython(); _dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N")); _dealer.Connect($"tcp://{config.ZeroMqHost}:{config.ZeroMqPort}"); } private void StartPython() { try { 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(); } catch (Exception e) { Console.WriteLine(e); throw; } } public void Login(ApiCredentials credentials) { _dealer.SendFrame(RemoteCommand.Serialize(CommandType.Login, credentials)); var user = _dealer.Get(); if (user == null) throw new Exception("Can't get user from Auth provider"); CurrentUser = user; } public void StopPython() { _dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Exit))); _dealer.Close(); } public MemoryStream LoadFileFromPython(string fileName, string? folder = null) { try { _dealer.SendFrame(RemoteCommand.Serialize(CommandType.Load, new LoadFileData(fileName, folder))); if (!_dealer.TryReceiveFrameBytes(TimeSpan.FromSeconds(300), 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); } } }