diff --git a/Hawkeye.VisionBuilder.Workflow/API/PythonAPI.cs b/Hawkeye.VisionBuilder.Workflow/API/PythonAPI.cs
new file mode 100644
index 0000000..40ea910
--- /dev/null
+++ b/Hawkeye.VisionBuilder.Workflow/API/PythonAPI.cs
@@ -0,0 +1,1092 @@
+//----------------------
+//
+// Generated using the NSwag toolchain v14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org)
+//
+//----------------------
+
+#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
+#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
+#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
+#pragma warning disable 612 // Disable "CS0612 '...' is obsolete"
+#pragma warning disable 649 // Disable "CS0649 Field is never assigned to, and will always have its default value null"
+#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
+#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."
+#pragma warning disable 8073 // Disable "CS8073 The result of the expression is always 'false' since a value of type 'T' is never equal to 'null' of type 'T?'"
+#pragma warning disable 3016 // Disable "CS3016 Arrays as attribute arguments is not CLS-compliant"
+#pragma warning disable 8600 // Disable "CS8600 Converting null literal or possible null value to non-nullable type"
+#pragma warning disable 8602 // Disable "CS8602 Dereference of a possibly null reference"
+#pragma warning disable 8603 // Disable "CS8603 Possible null reference return"
+#pragma warning disable 8604 // Disable "CS8604 Possible null reference argument for parameter"
+#pragma warning disable 8625 // Disable "CS8625 Cannot convert null literal to non-nullable reference type"
+#pragma warning disable 8765 // Disable "CS8765 Nullability of type of parameter doesn't match overridden member (possibly because of nullability attributes)."
+
+namespace Hawkeye.VisionBuilder.Workflow
+{
+ using System = global::System;
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class PythonModelAPI
+ {
+ #pragma warning disable 8618
+ private string _baseUrl;
+ #pragma warning restore 8618
+
+ private System.Net.Http.HttpClient _httpClient;
+ private static System.Lazy _settings = new System.Lazy(CreateSerializerSettings, true);
+ private Newtonsoft.Json.JsonSerializerSettings _instanceSettings;
+
+ #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+ public PythonModelAPI(string baseUrl, System.Net.Http.HttpClient httpClient)
+ #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+ {
+ BaseUrl = baseUrl;
+ _httpClient = httpClient;
+ Initialize();
+ }
+
+ private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
+ {
+ var settings = new Newtonsoft.Json.JsonSerializerSettings();
+ UpdateJsonSerializerSettings(settings);
+ return settings;
+ }
+
+ public string BaseUrl
+ {
+ get { return _baseUrl; }
+ set
+ {
+ _baseUrl = value;
+ if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/"))
+ _baseUrl += '/';
+ }
+ }
+
+ protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _instanceSettings ?? _settings.Value; } }
+
+ static partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
+
+ partial void Initialize();
+
+ partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
+ partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
+ partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
+
+ ///
+ /// Predict (classified indices)
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual System.Threading.Tasks.Task PredictAsync(FileParameter file)
+ {
+ return PredictAsync(file, System.Threading.CancellationToken.None);
+ }
+
+ /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
+ ///
+ /// Predict (classified indices)
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual async System.Threading.Tasks.Task PredictAsync(FileParameter file, System.Threading.CancellationToken cancellationToken)
+ {
+ var client_ = _httpClient;
+ var disposeClient_ = false;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ var boundary_ = System.Guid.NewGuid().ToString();
+ var content_ = new System.Net.Http.MultipartFormDataContent(boundary_);
+ content_.Headers.Remove("Content-Type");
+ content_.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary_);
+
+ if (file == null)
+ throw new System.ArgumentNullException("file");
+ else
+ {
+ var content_file_ = new System.Net.Http.StreamContent(file.Data);
+ if (!string.IsNullOrEmpty(file.ContentType))
+ content_file_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(file.ContentType);
+ content_.Add(content_file_, "file", file.FileName ?? "file");
+ }
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("POST");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ var urlBuilder_ = new System.Text.StringBuilder();
+ if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
+ // Operation Path: "predict"
+ urlBuilder_.Append("predict");
+
+ PrepareRequest(client_, request_, urlBuilder_);
+
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ var disposeResponse_ = true;
+ try
+ {
+ var headers_ = new System.Collections.Generic.Dictionary>();
+ foreach (var item_ in response_.Headers)
+ headers_[item_.Key] = item_.Value;
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = (int)response_.StatusCode;
+ if (status_ == 200 || status_ == 206)
+ {
+ var responseStream_ = response_.Content == null ? System.IO.Stream.Null : await ReadAsStreamAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ var fileResponse_ = new FileResponse(status_, headers_, responseStream_, null, response_);
+ disposeClient_ = false; disposeResponse_ = false; // response and client are disposed by FileResponse
+ return fileResponse_;
+ }
+ else
+ if (status_ == 422)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ throw new ApiException("Validation Error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
+ }
+ else
+ {
+ var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
+ }
+ }
+ finally
+ {
+ if (disposeResponse_)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ if (disposeClient_)
+ client_.Dispose();
+ }
+ }
+
+ ///
+ /// Predict (raw/uint8 flattened)
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual System.Threading.Tasks.Task PredictRawAsync(FileParameter file)
+ {
+ return PredictRawAsync(file, System.Threading.CancellationToken.None);
+ }
+
+ /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
+ ///
+ /// Predict (raw/uint8 flattened)
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual async System.Threading.Tasks.Task PredictRawAsync(FileParameter file, System.Threading.CancellationToken cancellationToken)
+ {
+ var client_ = _httpClient;
+ var disposeClient_ = false;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ var boundary_ = System.Guid.NewGuid().ToString();
+ var content_ = new System.Net.Http.MultipartFormDataContent(boundary_);
+ content_.Headers.Remove("Content-Type");
+ content_.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary_);
+
+ if (file == null)
+ throw new System.ArgumentNullException("file");
+ else
+ {
+ var content_file_ = new System.Net.Http.StreamContent(file.Data);
+ if (!string.IsNullOrEmpty(file.ContentType))
+ content_file_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(file.ContentType);
+ content_.Add(content_file_, "file", file.FileName ?? "file");
+ }
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("POST");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ var urlBuilder_ = new System.Text.StringBuilder();
+ if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
+ // Operation Path: "predictRaw"
+ urlBuilder_.Append("predictRaw");
+
+ PrepareRequest(client_, request_, urlBuilder_);
+
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ var disposeResponse_ = true;
+ try
+ {
+ var headers_ = new System.Collections.Generic.Dictionary>();
+ foreach (var item_ in response_.Headers)
+ headers_[item_.Key] = item_.Value;
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = (int)response_.StatusCode;
+ if (status_ == 200 || status_ == 206)
+ {
+ var responseStream_ = response_.Content == null ? System.IO.Stream.Null : await ReadAsStreamAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ var fileResponse_ = new FileResponse(status_, headers_, responseStream_, null, response_);
+ disposeClient_ = false; disposeResponse_ = false; // response and client are disposed by FileResponse
+ return fileResponse_;
+ }
+ else
+ if (status_ == 422)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ throw new ApiException("Validation Error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
+ }
+ else
+ {
+ var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
+ }
+ }
+ finally
+ {
+ if (disposeResponse_)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ if (disposeClient_)
+ client_.Dispose();
+ }
+ }
+
+ ///
+ /// Load a model from path
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual System.Threading.Tasks.Task LoadModelAsync(LoadModelIn body)
+ {
+ return LoadModelAsync(body, System.Threading.CancellationToken.None);
+ }
+
+ /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
+ ///
+ /// Load a model from path
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual async System.Threading.Tasks.Task LoadModelAsync(LoadModelIn body, System.Threading.CancellationToken cancellationToken)
+ {
+ if (body == null)
+ throw new System.ArgumentNullException("body");
+
+ var client_ = _httpClient;
+ var disposeClient_ = false;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(body, JsonSerializerSettings);
+ var content_ = new System.Net.Http.StringContent(json_);
+ content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("POST");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ var urlBuilder_ = new System.Text.StringBuilder();
+ if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
+ // Operation Path: "loadModel"
+ urlBuilder_.Append("loadModel");
+
+ PrepareRequest(client_, request_, urlBuilder_);
+
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ var disposeResponse_ = true;
+ try
+ {
+ var headers_ = new System.Collections.Generic.Dictionary>();
+ foreach (var item_ in response_.Headers)
+ headers_[item_.Key] = item_.Value;
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = (int)response_.StatusCode;
+ if (status_ == 200)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ return objectResponse_.Object;
+ }
+ else
+ if (status_ == 422)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ throw new ApiException("Validation Error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
+ }
+ else
+ {
+ var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
+ }
+ }
+ finally
+ {
+ if (disposeResponse_)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ if (disposeClient_)
+ client_.Dispose();
+ }
+ }
+
+ ///
+ /// Activate a loaded model
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual System.Threading.Tasks.Task ActivateModelAsync(ActivateModelIn body)
+ {
+ return ActivateModelAsync(body, System.Threading.CancellationToken.None);
+ }
+
+ /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
+ ///
+ /// Activate a loaded model
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual async System.Threading.Tasks.Task ActivateModelAsync(ActivateModelIn body, System.Threading.CancellationToken cancellationToken)
+ {
+ if (body == null)
+ throw new System.ArgumentNullException("body");
+
+ var client_ = _httpClient;
+ var disposeClient_ = false;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(body, JsonSerializerSettings);
+ var content_ = new System.Net.Http.StringContent(json_);
+ content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
+ request_.Content = content_;
+ request_.Method = new System.Net.Http.HttpMethod("POST");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ var urlBuilder_ = new System.Text.StringBuilder();
+ if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
+ // Operation Path: "activateModel"
+ urlBuilder_.Append("activateModel");
+
+ PrepareRequest(client_, request_, urlBuilder_);
+
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ var disposeResponse_ = true;
+ try
+ {
+ var headers_ = new System.Collections.Generic.Dictionary>();
+ foreach (var item_ in response_.Headers)
+ headers_[item_.Key] = item_.Value;
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = (int)response_.StatusCode;
+ if (status_ == 200)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ return objectResponse_.Object;
+ }
+ else
+ if (status_ == 422)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ throw new ApiException("Validation Error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
+ }
+ else
+ {
+ var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
+ }
+ }
+ finally
+ {
+ if (disposeResponse_)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ if (disposeClient_)
+ client_.Dispose();
+ }
+ }
+
+ ///
+ /// Get input tensor shape
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual System.Threading.Tasks.Task GetAcceptSizeAsync()
+ {
+ return GetAcceptSizeAsync(System.Threading.CancellationToken.None);
+ }
+
+ /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
+ ///
+ /// Get input tensor shape
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual async System.Threading.Tasks.Task GetAcceptSizeAsync(System.Threading.CancellationToken cancellationToken)
+ {
+ var client_ = _httpClient;
+ var disposeClient_ = false;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ request_.Method = new System.Net.Http.HttpMethod("GET");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ var urlBuilder_ = new System.Text.StringBuilder();
+ if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
+ // Operation Path: "getAcceptSize"
+ urlBuilder_.Append("getAcceptSize");
+
+ PrepareRequest(client_, request_, urlBuilder_);
+
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ var disposeResponse_ = true;
+ try
+ {
+ var headers_ = new System.Collections.Generic.Dictionary>();
+ foreach (var item_ in response_.Headers)
+ headers_[item_.Key] = item_.Value;
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = (int)response_.StatusCode;
+ if (status_ == 200)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ return objectResponse_.Object;
+ }
+ else
+ {
+ var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
+ }
+ }
+ finally
+ {
+ if (disposeResponse_)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ if (disposeClient_)
+ client_.Dispose();
+ }
+ }
+
+ ///
+ /// Get output tensor shape
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual System.Threading.Tasks.Task GetOutputSizeAsync()
+ {
+ return GetOutputSizeAsync(System.Threading.CancellationToken.None);
+ }
+
+ /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
+ ///
+ /// Get output tensor shape
+ ///
+ /// Successful Response
+ /// A server side error occurred.
+ public virtual async System.Threading.Tasks.Task GetOutputSizeAsync(System.Threading.CancellationToken cancellationToken)
+ {
+ var client_ = _httpClient;
+ var disposeClient_ = false;
+ try
+ {
+ using (var request_ = new System.Net.Http.HttpRequestMessage())
+ {
+ request_.Method = new System.Net.Http.HttpMethod("GET");
+ request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+ var urlBuilder_ = new System.Text.StringBuilder();
+ if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl);
+ // Operation Path: "getOutputSize"
+ urlBuilder_.Append("getOutputSize");
+
+ PrepareRequest(client_, request_, urlBuilder_);
+
+ var url_ = urlBuilder_.ToString();
+ request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
+
+ PrepareRequest(client_, request_, url_);
+
+ var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
+ var disposeResponse_ = true;
+ try
+ {
+ var headers_ = new System.Collections.Generic.Dictionary>();
+ foreach (var item_ in response_.Headers)
+ headers_[item_.Key] = item_.Value;
+ if (response_.Content != null && response_.Content.Headers != null)
+ {
+ foreach (var item_ in response_.Content.Headers)
+ headers_[item_.Key] = item_.Value;
+ }
+
+ ProcessResponse(client_, response_);
+
+ var status_ = (int)response_.StatusCode;
+ if (status_ == 200)
+ {
+ var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false);
+ if (objectResponse_.Object == null)
+ {
+ throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
+ }
+ return objectResponse_.Object;
+ }
+ else
+ {
+ var responseData_ = response_.Content == null ? null : await ReadAsStringAsync(response_.Content, cancellationToken).ConfigureAwait(false);
+ throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
+ }
+ }
+ finally
+ {
+ if (disposeResponse_)
+ response_.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ if (disposeClient_)
+ client_.Dispose();
+ }
+ }
+
+ protected struct ObjectResponseResult
+ {
+ public ObjectResponseResult(T responseObject, string responseText)
+ {
+ this.Object = responseObject;
+ this.Text = responseText;
+ }
+
+ public T Object { get; }
+
+ public string Text { get; }
+ }
+
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ private static System.Threading.Tasks.Task ReadAsStringAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken)
+ {
+ #if NET5_0_OR_GREATER
+ return content.ReadAsStringAsync(cancellationToken);
+ #else
+ return content.ReadAsStringAsync();
+ #endif
+ }
+
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ private static System.Threading.Tasks.Task ReadAsStreamAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken)
+ {
+ #if NET5_0_OR_GREATER
+ return content.ReadAsStreamAsync(cancellationToken);
+ #else
+ return content.ReadAsStreamAsync();
+ #endif
+ }
+
+ public bool ReadResponseAsString { get; set; }
+
+ protected virtual async System.Threading.Tasks.Task> ReadObjectResponseAsync(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Threading.CancellationToken cancellationToken)
+ {
+ if (response == null || response.Content == null)
+ {
+ return new ObjectResponseResult(default(T), string.Empty);
+ }
+
+ if (ReadResponseAsString)
+ {
+ var responseText = await ReadAsStringAsync(response.Content, cancellationToken).ConfigureAwait(false);
+ try
+ {
+ var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, JsonSerializerSettings);
+ return new ObjectResponseResult(typedBody, responseText);
+ }
+ catch (Newtonsoft.Json.JsonException exception)
+ {
+ var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
+ throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
+ }
+ }
+ else
+ {
+ try
+ {
+ using (var responseStream = await ReadAsStreamAsync(response.Content, cancellationToken).ConfigureAwait(false))
+ using (var streamReader = new System.IO.StreamReader(responseStream))
+ using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
+ {
+ var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
+ var typedBody = serializer.Deserialize(jsonTextReader);
+ return new ObjectResponseResult(typedBody, string.Empty);
+ }
+ }
+ catch (Newtonsoft.Json.JsonException exception)
+ {
+ var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
+ throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
+ }
+ }
+ }
+
+ private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
+ {
+ if (value == null)
+ {
+ return "";
+ }
+
+ if (value is System.Enum)
+ {
+ var name = System.Enum.GetName(value.GetType(), value);
+ if (name != null)
+ {
+ var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
+ if (field != null)
+ {
+ var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
+ as System.Runtime.Serialization.EnumMemberAttribute;
+ if (attribute != null)
+ {
+ return attribute.Value != null ? attribute.Value : name;
+ }
+ }
+
+ var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
+ return converted == null ? string.Empty : converted;
+ }
+ }
+ else if (value is bool)
+ {
+ return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
+ }
+ else if (value is byte[])
+ {
+ return System.Convert.ToBase64String((byte[]) value);
+ }
+ else if (value is string[])
+ {
+ return string.Join(",", (string[])value);
+ }
+ else if (value.GetType().IsArray)
+ {
+ var valueArray = (System.Array)value;
+ var valueTextArray = new string[valueArray.Length];
+ for (var i = 0; i < valueArray.Length; i++)
+ {
+ valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo);
+ }
+ return string.Join(",", valueTextArray);
+ }
+
+ var result = System.Convert.ToString(value, cultureInfo);
+ return result == null ? "" : result;
+ }
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class AcceptSizeOut
+ {
+
+ [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Status { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("accept_size", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public System.Collections.Generic.ICollection Accept_size { get; set; } = new System.Collections.ObjectModel.Collection();
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class ActivateModelIn
+ {
+
+ [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Name { get; set; }
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class Body_predict_predict_post
+ {
+
+ [Newtonsoft.Json.JsonProperty("file", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public byte[] File { get; set; }
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class Body_predict_raw_predictRaw_post
+ {
+
+ [Newtonsoft.Json.JsonProperty("file", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public byte[] File { get; set; }
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class HTTPValidationError
+ {
+
+ [Newtonsoft.Json.JsonProperty("detail", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public System.Collections.Generic.ICollection Detail { get; set; }
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class LoadModelIn
+ {
+
+ [Newtonsoft.Json.JsonProperty("path", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Path { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Name { get; set; }
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class StatusOut
+ {
+
+ [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Status { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Message { get; set; }
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class ValidationError
+ {
+
+ [Newtonsoft.Json.JsonProperty("loc", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required]
+ public System.Collections.Generic.ICollection Loc { get; set; } = new System.Collections.ObjectModel.Collection();
+
+ [Newtonsoft.Json.JsonProperty("msg", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Msg { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.Always)]
+ [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
+ public string Type { get; set; }
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class Loc
+ {
+
+ private System.Collections.Generic.IDictionary _additionalProperties;
+
+ [Newtonsoft.Json.JsonExtensionData]
+ public System.Collections.Generic.IDictionary AdditionalProperties
+ {
+ get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); }
+ set { _additionalProperties = value; }
+ }
+
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class FileParameter
+ {
+ public FileParameter(System.IO.Stream data)
+ : this (data, null, null)
+ {
+ }
+
+ public FileParameter(System.IO.Stream data, string fileName)
+ : this (data, fileName, null)
+ {
+ }
+
+ public FileParameter(System.IO.Stream data, string fileName, string contentType)
+ {
+ Data = data;
+ FileName = fileName;
+ ContentType = contentType;
+ }
+
+ public System.IO.Stream Data { get; private set; }
+
+ public string FileName { get; private set; }
+
+ public string ContentType { get; private set; }
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class FileResponse : System.IDisposable
+ {
+ private System.IDisposable _client;
+ private System.IDisposable _response;
+
+ public int StatusCode { get; private set; }
+
+ public System.Collections.Generic.IReadOnlyDictionary> Headers { get; private set; }
+
+ public System.IO.Stream Stream { get; private set; }
+
+ public bool IsPartial
+ {
+ get { return StatusCode == 206; }
+ }
+
+ public FileResponse(int statusCode, System.Collections.Generic.IReadOnlyDictionary> headers, System.IO.Stream stream, System.IDisposable client, System.IDisposable response)
+ {
+ StatusCode = statusCode;
+ Headers = headers;
+ Stream = stream;
+ _client = client;
+ _response = response;
+ }
+
+ public void Dispose()
+ {
+ Stream.Dispose();
+ if (_response != null)
+ _response.Dispose();
+ if (_client != null)
+ _client.Dispose();
+ }
+ }
+
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class ApiException : System.Exception
+ {
+ public int StatusCode { get; private set; }
+
+ public string Response { get; private set; }
+
+ public System.Collections.Generic.IReadOnlyDictionary> Headers { get; private set; }
+
+ public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Exception innerException)
+ : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException)
+ {
+ StatusCode = statusCode;
+ Response = response;
+ Headers = headers;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString());
+ }
+ }
+
+ [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.5.0.0 (NJsonSchema v11.4.0.0 (Newtonsoft.Json v13.0.0.0))")]
+ public partial class ApiException : ApiException
+ {
+ public TResult Result { get; private set; }
+
+ public ApiException(string message, int statusCode, string response, System.Collections.Generic.IReadOnlyDictionary> headers, TResult result, System.Exception innerException)
+ : base(message, statusCode, response, headers, innerException)
+ {
+ Result = result;
+ }
+ }
+
+}
+
+#pragma warning restore 108
+#pragma warning restore 114
+#pragma warning restore 472
+#pragma warning restore 612
+#pragma warning restore 649
+#pragma warning restore 1573
+#pragma warning restore 1591
+#pragma warning restore 8073
+#pragma warning restore 3016
+#pragma warning restore 8600
+#pragma warning restore 8602
+#pragma warning restore 8603
+#pragma warning restore 8604
+#pragma warning restore 8625
+#pragma warning restore 8765
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.Workflow/API/generator.nswag b/Hawkeye.VisionBuilder.Workflow/API/generator.nswag
new file mode 100644
index 0000000..2bb3122
--- /dev/null
+++ b/Hawkeye.VisionBuilder.Workflow/API/generator.nswag
@@ -0,0 +1,103 @@
+{
+ "runtime": "Net80",
+ "defaultVariables": null,
+ "documentGenerator": {
+ "fromDocument": {
+ "json": "",
+ "url": "http://localhost:8000/openapi.json",
+ "output": null,
+ "newLineBehavior": "Auto"
+ }
+ },
+ "codeGenerators": {
+ "openApiToCSharpClient": {
+ "clientBaseClass": null,
+ "configurationClass": null,
+ "generateClientClasses": true,
+ "suppressClientClassesOutput": false,
+ "generateClientInterfaces": false,
+ "suppressClientInterfacesOutput": false,
+ "clientBaseInterface": null,
+ "injectHttpClient": true,
+ "disposeHttpClient": true,
+ "protectedMethods": [],
+ "generateExceptionClasses": true,
+ "exceptionClass": "ApiException",
+ "wrapDtoExceptions": true,
+ "useHttpClientCreationMethod": false,
+ "httpClientType": "System.Net.Http.HttpClient",
+ "useHttpRequestMessageCreationMethod": false,
+ "useBaseUrl": true,
+ "generateBaseUrlProperty": true,
+ "generateSyncMethods": false,
+ "generatePrepareRequestAndProcessResponseAsAsyncMethods": false,
+ "exposeJsonSerializerSettings": false,
+ "clientClassAccessModifier": "public",
+ "typeAccessModifier": "public",
+ "propertySetterAccessModifier": "",
+ "generateNativeRecords": false,
+ "useRequiredKeyword": false,
+ "generateContractsOutput": false,
+ "contractsNamespace": null,
+ "contractsOutputFilePath": null,
+ "parameterDateTimeFormat": "s",
+ "parameterDateFormat": "yyyy-MM-dd",
+ "generateUpdateJsonSerializerSettingsMethod": true,
+ "useRequestAndResponseSerializationSettings": false,
+ "serializeTypeInformation": false,
+ "queryNullValue": "",
+ "className": "PythonModelAPI",
+ "operationGenerationMode": "SingleClientFromPathSegments",
+ "additionalNamespaceUsages": [],
+ "additionalContractNamespaceUsages": [],
+ "generateOptionalParameters": false,
+ "generateJsonMethods": false,
+ "enforceFlagEnums": false,
+ "parameterArrayType": "System.Collections.Generic.IEnumerable",
+ "parameterDictionaryType": "System.Collections.Generic.IDictionary",
+ "responseArrayType": "System.Collections.Generic.ICollection",
+ "responseDictionaryType": "System.Collections.Generic.IDictionary",
+ "wrapResponses": false,
+ "wrapResponseMethods": [],
+ "generateResponseClasses": true,
+ "responseClass": "SwaggerResponse",
+ "namespace": "Hawkeye.VisionBuilder.Workflow",
+ "requiredPropertiesMustBeDefined": true,
+ "dateType": "System.DateTimeOffset",
+ "jsonConverters": null,
+ "anyType": "object",
+ "dateTimeType": "System.DateTimeOffset",
+ "timeType": "System.TimeSpan",
+ "timeSpanType": "System.TimeSpan",
+ "arrayType": "System.Collections.Generic.ICollection",
+ "arrayInstanceType": "System.Collections.ObjectModel.Collection",
+ "dictionaryType": "System.Collections.Generic.IDictionary",
+ "dictionaryInstanceType": "System.Collections.Generic.Dictionary",
+ "arrayBaseType": "System.Collections.ObjectModel.Collection",
+ "dictionaryBaseType": "System.Collections.Generic.Dictionary",
+ "classStyle": "Poco",
+ "jsonLibrary": "NewtonsoftJson",
+ "jsonPolymorphicSerializationStyle": "NJsonSchema",
+ "generateDefaultValues": true,
+ "generateDataAnnotations": true,
+ "excludedTypeNames": [],
+ "excludedParameterNames": [],
+ "handleReferences": false,
+ "generateImmutableArrayProperties": false,
+ "generateImmutableDictionaryProperties": false,
+ "jsonSerializerSettingsTransformationMethod": null,
+ "inlineNamedArrays": false,
+ "inlineNamedDictionaries": false,
+ "inlineNamedTuples": true,
+ "inlineNamedAny": false,
+ "generateDtoTypes": true,
+ "generateOptionalPropertiesAsNullable": false,
+ "generateNullableReferenceTypes": false,
+ "templateDirectory": null,
+ "serviceHost": null,
+ "serviceSchemes": null,
+ "output": "PythonAPI.cs",
+ "newLineBehavior": "Auto"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.Workflow/DataTransfer/CSharpDataTransferHTTP.cs b/Hawkeye.VisionBuilder.Workflow/DataTransfer/CSharpDataTransferHTTP.cs
new file mode 100644
index 0000000..7cc6fe4
--- /dev/null
+++ b/Hawkeye.VisionBuilder.Workflow/DataTransfer/CSharpDataTransferHTTP.cs
@@ -0,0 +1,107 @@
+using static Community.CsharpSqlite.Sqlite3;
+
+namespace Hawkeye.VisionBuilder.Workflow.DataTransfer;
+
+public class CSharpDataTransferHTTP
+{
+ private readonly PythonModelAPI _api;
+ private readonly HttpClient _client;
+ private readonly CancellationTokenSource _pingCts = new();
+ private readonly Thread _pingThread;
+
+ public CSharpDataTransferHTTP()
+ {
+ var handler = new SocketsHttpHandler
+ {
+ PooledConnectionIdleTimeout = TimeSpan.FromSeconds(10),
+ MaxConnectionsPerServer = 100
+
+
+
+ };
+ _client = new HttpClient(handler)
+ {
+ // i've added this
+ DefaultRequestHeaders =
+ {
+ ExpectContinue = false
+ }
+ };
+ _api = new PythonModelAPI("http://localhost:8000",_client);
+ _pingThread = new Thread(PingLoop) { IsBackground = true };
+ _pingThread.Start();
+
+ }
+
+ private void PingLoop()
+ {
+ while (!_pingCts.Token.IsCancellationRequested)
+ {
+ try
+ {
+ _client.GetAsync("http://localhost:8000/").Wait();
+ }
+ catch
+ {
+ // Ignore errors, optionally log
+ }
+ Thread.Sleep(3000); // Ping every 3 seconds
+ }
+ }
+
+ public void LoadModel(string path, string modelName)
+ {
+ _api.LoadModelAsync(new LoadModelIn()
+ {
+ Name = modelName,
+ Path = Path.GetFileName(path)
+ }).Wait();
+ }
+
+ public void ActivateModel(string modelName)
+ {
+ _api.ActivateModelAsync(new ActivateModelIn(){Name = modelName}).Wait();
+ }
+
+ public int[] GetAcceptSize()
+ {
+ var response = _api.GetAcceptSizeAsync().Result;
+
+ return response.Accept_size.ToArray();
+ }
+
+ public int[] GetOutputSize()
+ {
+ var response = _api.GetOutputSizeAsync().Result;
+
+ return response.Accept_size.ToArray();
+
+ }
+
+ public byte[] PredictRaw(byte[] byteArray)
+ {
+ var response = _api.PredictRawAsync(new FileParameter(new MemoryStream(byteArray))).Result;
+ var stream = response.Stream;
+ // read the stream to byte array
+ using var memoryStream = new MemoryStream();
+ stream.CopyTo(memoryStream);
+ memoryStream.Seek(0, SeekOrigin.Begin);
+ var responseBytes = memoryStream.ToArray();
+ return responseBytes;
+ }
+
+ public byte[] Predict(byte[] byteArray)
+ {
+ var response = _api.PredictAsync(new FileParameter(new MemoryStream(byteArray))).Result;
+ var stream = response.Stream;
+ // read the stream to byte array
+ using var memoryStream = new MemoryStream();
+ stream.CopyTo(memoryStream);
+ memoryStream.Seek(0, SeekOrigin.Begin);
+ var responseBytes = memoryStream.ToArray();
+ return responseBytes;
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.Workflow/DataTransfer/PythonModelProxyHTTP.cs b/Hawkeye.VisionBuilder.Workflow/DataTransfer/PythonModelProxyHTTP.cs
index 6d73f0d..3fb2108 100644
--- a/Hawkeye.VisionBuilder.Workflow/DataTransfer/PythonModelProxyHTTP.cs
+++ b/Hawkeye.VisionBuilder.Workflow/DataTransfer/PythonModelProxyHTTP.cs
@@ -2,5 +2,26 @@
public class PythonModelProxyHTTP
{
-
+ private static bool _isInitialized = false;
+ private static UvicornScriptRunner _pythonScriptRunner;
+ private static CSharpDataTransferHTTP _cSharpDataTransferHTTP;
+
+ public static void Initialize()
+ {
+ if (_isInitialized) return;
+
+ var workDirAbsPath = Path.GetFullPath(@"..\Data\Models");
+ _pythonScriptRunner = new UvicornScriptRunner(workDirAbsPath);
+ _cSharpDataTransferHTTP = new CSharpDataTransferHTTP();
+
+ _pythonScriptRunner.Start();
+ Thread.Sleep(1000); // Wait for the server to start
+ }
+
+ public static CSharpDataTransferHTTP GetInterface()
+ {
+ if (!_isInitialized) Initialize();
+
+ return _cSharpDataTransferHTTP;
+ }
}
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.Workflow/DataTransfer/UvicornScriptRunner.cs b/Hawkeye.VisionBuilder.Workflow/DataTransfer/UvicornScriptRunner.cs
new file mode 100644
index 0000000..e9b0b21
--- /dev/null
+++ b/Hawkeye.VisionBuilder.Workflow/DataTransfer/UvicornScriptRunner.cs
@@ -0,0 +1,63 @@
+using System.Diagnostics;
+
+namespace Hawkeye.VisionBuilder.Workflow.DataTransfer;
+
+public class UvicornScriptRunner
+{
+ private Process process;
+ private readonly string _workingDirectory;
+
+ public UvicornScriptRunner(string workingDirectory)
+ {
+ _workingDirectory = workingDirectory;
+ }
+ public static string ConvertToWslPath(string windowsPath)
+ {
+ if (string.IsNullOrWhiteSpace(windowsPath))
+ throw new ArgumentException("Path cannot be null or empty.", nameof(windowsPath));
+
+ // Replace backslashes with forward slashes
+ string wslPath = windowsPath.Replace('\\', '/');
+
+ // Extract the drive letter and convert it to WSL format
+ if (wslPath.Length > 1 && wslPath[1] == ':')
+ {
+ char driveLetter = char.ToLower(wslPath[0]);
+ wslPath = $"/mnt/{driveLetter}{wslPath.Substring(2)}";
+ }
+
+ return wslPath;
+ }
+ public void Start()
+ {
+
+
+
+ //startInfo.CreateNoWindow = true;
+ // create and start the process
+ process = new Process();
+ var convertedWd = ConvertToWslPath(_workingDirectory);
+ var arg =
+ $@"--distribution ubuntu --user root --cd ""{convertedWd}"" -- uvicorn PythonModelAPI:app";
+ process.StartInfo = new ProcessStartInfo("wsl", arg)
+ {
+ UseShellExecute = false
+ };
+ process.Start();
+ // on windows only
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT)
+ ChildProcessTracker.AddProcess(process);
+
+
+ }
+
+ public void Stop()
+ {
+ if (process != null && !process.HasExited)
+ {
+ process.Kill();
+ process.Dispose();
+ process = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Hawkeye.VisionBuilder.Workflow/Hawkeye.VisionBuilder.Workflow.csproj b/Hawkeye.VisionBuilder.Workflow/Hawkeye.VisionBuilder.Workflow.csproj
index d3e6325..80b6571 100644
--- a/Hawkeye.VisionBuilder.Workflow/Hawkeye.VisionBuilder.Workflow.csproj
+++ b/Hawkeye.VisionBuilder.Workflow/Hawkeye.VisionBuilder.Workflow.csproj
@@ -9,13 +9,29 @@
Debug;Release;CPU
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Hawkeye.VisionBuilder.Workflow/Operations/AI/ColorAIOperation.cs b/Hawkeye.VisionBuilder.Workflow/Operations/AI/ColorAIOperation.cs
index 5a17478..67914b6 100644
--- a/Hawkeye.VisionBuilder.Workflow/Operations/AI/ColorAIOperation.cs
+++ b/Hawkeye.VisionBuilder.Workflow/Operations/AI/ColorAIOperation.cs
@@ -14,11 +14,11 @@ public abstract class ColorAIOperation:BaseOperation
public ColorAIOperation(string model_name)
{
_modelName = model_name;
- _cSharpDataTransferMQRPC = PythonModelProxyRPC.GetInterface();
+ _cSharpDataTransferMQRPC = PythonModelProxyHTTP.GetInterface();
CanHaveProcessingError = false;
}
- private readonly CSharpDataTransferMQRPC _cSharpDataTransferMQRPC;
+ private readonly CSharpDataTransferHTTP _cSharpDataTransferMQRPC;
private int _imageWidth;
private int _imageHeight;
@@ -52,15 +52,16 @@ public abstract class ColorAIOperation:BaseOperation
this.SetError("Model file not found");
return;
}
- _cSharpDataTransferMQRPC.TransferData