using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MarketData.CNNProcessing { public class CNNClient { public enum Model{resnet50,resnet50B,inception,vgg16,lenet5,ping}; private static readonly string Alive="Alive"; private readonly HttpClient client = new HttpClient(); private string baseUrl; private static int REQUEST_TIMEOUT=15000; public CNNClient(String baseUrl) { client.Timeout=new TimeSpan(0,0,0,0,REQUEST_TIMEOUT); if(!baseUrl.StartsWith("http://") && !baseUrl.StartsWith("HTTP://"))baseUrl="http://"+baseUrl; this.baseUrl=baseUrl; } private String GetModelUrl(CNNClient.Model model) { return baseUrl+"/predict_"+model.ToString(); } public String Predict(CNNClient.Model model,Stream stream) { try { string responsePayload = Upload(GetModelUrl(model),stream).GetAwaiter().GetResult(); return responsePayload; } catch(Exception exception) { return exception.ToString(); } } // This method is used to process an image through PIL. All images that are being used in training should ultimately be processed through // PIL (Python Image Library) so that images can be normalized by python prior to training. We do this because we use PIL during the // prediction process and we want all images used in training/validation and all images used for prediction to be touched by and processed // by PIL public Stream ProcessImage(Stream stream) { return UploadImage(baseUrl+"/process_image", stream); } public bool Ping() { try { string responsePayload = Upload(baseUrl+"/ping").GetAwaiter().GetResult(); if(null==responsePayload)return false; return responsePayload.Equals(Alive); } catch(Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception encountered: {0}",exception.ToString())); return false; } } private async Task Upload(String url,Stream stream) { try { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url)) { int streamEnd = Convert.ToInt32(stream.Length); byte[] byteArray = new byte[streamEnd]; stream.Read(byteArray, 0, streamEnd); request.Content=new ByteArrayContent(byteArray); using (HttpResponseMessage response = await client.SendAsync(request)) { return await response.Content.ReadAsStringAsync(); } } } catch(Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception encountered: {0}",exception.ToString())); return null; } } /// /// This method uploads an image stream to the specified url and receives the processed image back. /// The processed image simply processes the image through PIL (Python Image Library) /// private Stream UploadImage(String url,Stream stream) { try { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url)) { int streamEnd = Convert.ToInt32(stream.Length); byte[] byteArray = new byte[streamEnd]; stream.Read(byteArray, 0, streamEnd); request.Content=new ByteArrayContent(byteArray); HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult(); return response.Content.ReadAsStreamAsync().GetAwaiter().GetResult(); } } catch(Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception encountered: {0}",exception.ToString())); return null; } } private async Task Upload(String url) { try { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url)) { HttpResponseMessage response = await client.SendAsync(request); return await response.Content.ReadAsStringAsync(); } } catch(Exception exception) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception encountered: {0}",exception.ToString())); return null; } } } }