From e5c589c1ad7ba2691ad29ff5f1d8b2b9e697ebbd Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Thu, 14 Nov 2024 14:23:34 +0100 Subject: [PATCH 01/11] :sparkles: add support for workflow execution file send & workflow response loading --- src/Mindee/Parsing/Common/Execution.cs | 90 +++++++++++++++++++ src/Mindee/Parsing/Common/ExecutionFile.cs | 22 +++++ src/Mindee/Parsing/Common/WorkflowResponse.cs | 23 +++++ 3 files changed, 135 insertions(+) create mode 100644 src/Mindee/Parsing/Common/Execution.cs create mode 100644 src/Mindee/Parsing/Common/ExecutionFile.cs create mode 100644 src/Mindee/Parsing/Common/WorkflowResponse.cs diff --git a/src/Mindee/Parsing/Common/Execution.cs b/src/Mindee/Parsing/Common/Execution.cs new file mode 100644 index 00000000..a3edaf75 --- /dev/null +++ b/src/Mindee/Parsing/Common/Execution.cs @@ -0,0 +1,90 @@ +using System; +using System.Text.Json.Serialization; +using Mindee.Product.Generated; + +namespace Mindee.Parsing.Common +{ + /// + /// Representation of a workflow execution. + /// + public class Execution where TInferenceModel : class, new() + { + /// + /// Identifier for the batch to which the execution belongs. + /// + [JsonPropertyName("batch_name")] + public string BatchName { get; set; } + + /// + /// The time at which the execution started. + /// + [JsonPropertyName("created_at")] + public DateTime CreatedAt { get; set; } + + /// + /// File representation within a workflow execution. + /// + [JsonPropertyName("file")] + public ExecutionFile File { get; set; } + + /// + /// Identifier for the execution. + /// + [JsonPropertyName("id")] + public string Id { get; set; } + + /// + /// Deserialized inference object. + /// + [JsonPropertyName("inference")] + public TInferenceModel Inference { get; set; } + + /// + /// Priority of the execution. + /// + [JsonPropertyName("priority")] + public string Priority { get; set; } + + /// + /// The time at which the file was tagged as reviewed. + /// + [JsonPropertyName("reviewed_at")] + public DateTime ReviewedAt { get; set; } + + /// + /// The time at which the file was uploaded to a workflow. + /// + [JsonPropertyName("available_at")] + public DateTime AvailableAt { get; set; } + + /// + /// Reviewed fields and values. + /// + [JsonPropertyName("reviewed_prediction")] + public GeneratedV1Document ReviewedPrediction { get; set; } + + /// + /// Execution Status. + /// + [JsonPropertyName("status")] + public string Status { get; set; } + + /// + /// Execution type. + /// + [JsonPropertyName("type")] + public string Type { get; set; } + + /// + /// The time at which the file was uploaded to a workflow. + /// + [JsonPropertyName("uploaded_at")] + public DateTime UploadedAt { get; set; } + + /// + /// Identifier for the workflow. + /// + [JsonPropertyName("workflow_id")] + public string WorkflowId { get; set; } + } +} diff --git a/src/Mindee/Parsing/Common/ExecutionFile.cs b/src/Mindee/Parsing/Common/ExecutionFile.cs new file mode 100644 index 00000000..0ef9ee79 --- /dev/null +++ b/src/Mindee/Parsing/Common/ExecutionFile.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace Mindee.Parsing.Common +{ + /// + /// File name. + /// + public class ExecutionFile + { + /// + /// File name. + /// + [JsonPropertyName("name")] + public string Name { get; set; } + + /// + /// Identifier for the execution. + /// + [JsonPropertyName("alias")] + public string Alias { get; set; } + } +} diff --git a/src/Mindee/Parsing/Common/WorkflowResponse.cs b/src/Mindee/Parsing/Common/WorkflowResponse.cs new file mode 100644 index 00000000..09c03cf5 --- /dev/null +++ b/src/Mindee/Parsing/Common/WorkflowResponse.cs @@ -0,0 +1,23 @@ +using System.Text.Json.Serialization; +using Mindee.Product.Generated; + +namespace Mindee.Parsing.Common +{ + /// + /// Represents the server response after a document is sent to a workflow. + /// + public class WorkflowResponse where TInferenceModel : class, new() + { + /// + /// Set the prediction model used to parse the document. + /// + [JsonPropertyName(("execution"))] + public Execution Execution { get; set; } + + + /// + /// Default product is GeneratedV1. + /// + public class Default : WorkflowResponse { } + } +} From 3ecb788fe7c520f7eac2887e5862a5091c4a9edf Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Thu, 14 Nov 2024 15:27:40 +0100 Subject: [PATCH 02/11] add functional calls & accessors --- src/Mindee/Http/IHttpApi.cs | 11 +++++ src/Mindee/Http/MindeeApi.cs | 17 ++++++++ src/Mindee/Http/PredictParameter.cs | 12 +++--- src/Mindee/MindeeClient.cs | 40 +++++++++++++++++++ src/Mindee/Parsing/Common/Execution.cs | 12 ++++-- src/Mindee/Parsing/Common/WorkflowResponse.cs | 8 ++-- 6 files changed, 87 insertions(+), 13 deletions(-) diff --git a/src/Mindee/Http/IHttpApi.cs b/src/Mindee/Http/IHttpApi.cs index 5aed1df9..58bcb079 100644 --- a/src/Mindee/Http/IHttpApi.cs +++ b/src/Mindee/Http/IHttpApi.cs @@ -43,5 +43,16 @@ Task> DocumentQueueGetAsync( string jobId , CustomEndpoint endpoint = null) where TModel : class, new(); + + /// + /// Send a document to a workflow. + /// + /// The ID of the workflow. + /// + /// Document type. + Task> ExecutionQueuePost( + string workflowId, + PredictParameter predictParameter) + where TModel : class, new(); } } diff --git a/src/Mindee/Http/MindeeApi.cs b/src/Mindee/Http/MindeeApi.cs index 4e938800..9ccde186 100644 --- a/src/Mindee/Http/MindeeApi.cs +++ b/src/Mindee/Http/MindeeApi.cs @@ -115,6 +115,23 @@ string jobId return handledResponse; } + public async Task> ExecutionQueuePost( + string workflowId, + PredictParameter predictParameter) + where TModel : class, new() + { + var request = new RestRequest( + $"v1/workflows/{workflowId}/executions" + , Method.Post); + + AddPredictRequestParameters(predictParameter, request); + + _logger?.LogInformation($"HTTP POST to {_baseUrl + request.Resource} ..."); + + var response = await _httpClient.ExecutePostAsync(request); + return ResponseHandler>(response); + } + private static void AddPredictRequestParameters(PredictParameter predictParameter, RestRequest request) { if (predictParameter.LocalSource != null) diff --git a/src/Mindee/Http/PredictParameter.cs b/src/Mindee/Http/PredictParameter.cs index 12a74c93..b0aa6ae3 100644 --- a/src/Mindee/Http/PredictParameter.cs +++ b/src/Mindee/Http/PredictParameter.cs @@ -38,13 +38,13 @@ public sealed class PredictParameter public bool Cropper { get; } /// - /// + /// Prediction parameters for requests. /// - /// - /// - /// - /// - /// + /// Local input source containing the file. + /// Source URL to use. + /// Whether to include the full OCR response in the payload (compatible APIs only). + /// Whether to include the full text in the payload (compatible APIs only) + /// Whether to crop the document before enqueuing on the API. public PredictParameter( LocalInputSource localSource, UrlInputSource urlSource, diff --git a/src/Mindee/MindeeClient.cs b/src/Mindee/MindeeClient.cs index 7bc57813..38221c44 100644 --- a/src/Mindee/MindeeClient.cs +++ b/src/Mindee/MindeeClient.cs @@ -609,6 +609,46 @@ LocalInputSource inputSource throw new MindeeException($"Could not complete after {retryCount} attempts."); } + /// + /// Send a local file to a workflow execution. + /// + /// The workflow id. + /// + /// + /// + /// Set the prediction model used to parse the document. + /// The response object will be instantiated based on this parameter. + /// + public async Task> ExecuteWorkflowAsync( + string workflowId, + LocalInputSource inputSource + , PredictOptions predictOptions = null + , PageOptions pageOptions = null) + where TInferenceModel : class, new() + { + _logger?.LogInformation("Asynchronous parsing of {} ...", typeof(TInferenceModel).Name); + + if (pageOptions != null && inputSource.IsPdf()) + { + inputSource.FileBytes = _pdfOperation.Split( + new SplitQuery(inputSource.FileBytes, pageOptions)).File; + } + + if (predictOptions == null) + { + predictOptions = new PredictOptions(); + } + + return await _mindeeApi.ExecutionQueuePost( + workflowId, + new PredictParameter( + localSource: inputSource, + urlSource: null, + allWords: predictOptions.AllWords, + fullText: predictOptions.FullText, + cropper: predictOptions.Cropper)); + } + /// /// Load a local prediction. /// Typically used when wanting to load from a webhook callback. diff --git a/src/Mindee/Parsing/Common/Execution.cs b/src/Mindee/Parsing/Common/Execution.cs index a3edaf75..24248124 100644 --- a/src/Mindee/Parsing/Common/Execution.cs +++ b/src/Mindee/Parsing/Common/Execution.cs @@ -19,7 +19,8 @@ namespace Mindee.Parsing.Common /// The time at which the execution started. /// [JsonPropertyName("created_at")] - public DateTime CreatedAt { get; set; } + [JsonConverter(typeof(DateTimeJsonConverter))] + public DateTime? CreatedAt { get; set; } /// /// File representation within a workflow execution. @@ -49,13 +50,15 @@ namespace Mindee.Parsing.Common /// The time at which the file was tagged as reviewed. /// [JsonPropertyName("reviewed_at")] - public DateTime ReviewedAt { get; set; } + [JsonConverter(typeof(DateTimeJsonConverter))] + public DateTime? ReviewedAt { get; set; } /// /// The time at which the file was uploaded to a workflow. /// [JsonPropertyName("available_at")] - public DateTime AvailableAt { get; set; } + [JsonConverter(typeof(DateTimeJsonConverter))] + public DateTime? AvailableAt { get; set; } /// /// Reviewed fields and values. @@ -79,7 +82,8 @@ namespace Mindee.Parsing.Common /// The time at which the file was uploaded to a workflow. /// [JsonPropertyName("uploaded_at")] - public DateTime UploadedAt { get; set; } + [JsonConverter(typeof(DateTimeJsonConverter))] + public DateTime? UploadedAt { get; set; } /// /// Identifier for the workflow. diff --git a/src/Mindee/Parsing/Common/WorkflowResponse.cs b/src/Mindee/Parsing/Common/WorkflowResponse.cs index 09c03cf5..79da4375 100644 --- a/src/Mindee/Parsing/Common/WorkflowResponse.cs +++ b/src/Mindee/Parsing/Common/WorkflowResponse.cs @@ -6,18 +6,20 @@ namespace Mindee.Parsing.Common /// /// Represents the server response after a document is sent to a workflow. /// - public class WorkflowResponse where TInferenceModel : class, new() + public class WorkflowResponse : CommonResponse where TModel : class, new() { /// /// Set the prediction model used to parse the document. /// [JsonPropertyName(("execution"))] - public Execution Execution { get; set; } + public Execution Execution { get; set; } /// /// Default product is GeneratedV1. /// - public class Default : WorkflowResponse { } + public class Default : WorkflowResponse + { + } } } From 8b04f6bcdb5a1ad4071d725aae6b385a1d6e0b05 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Thu, 14 Nov 2024 15:54:58 +0100 Subject: [PATCH 03/11] add test & sample file --- docs/code_samples/workflow_execution.txt | 23 +++ .../Mindee.UnitTests/Workflow/WorklowTest.cs | 142 ++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 docs/code_samples/workflow_execution.txt create mode 100644 tests/Mindee.UnitTests/Workflow/WorklowTest.cs diff --git a/docs/code_samples/workflow_execution.txt b/docs/code_samples/workflow_execution.txt new file mode 100644 index 00000000..c254debe --- /dev/null +++ b/docs/code_samples/workflow_execution.txt @@ -0,0 +1,23 @@ +using Mindee; +using Mindee.Input; +using Mindee.Product.Generated; + +string apiKey = "my-api-key"; +string filePath = "/path/to/the/file.ext"; +string workflowId = "workflow-id"; + +// Construct a new client +MindeeClient mindeeClient = new MindeeClient(apiKey); + +// Load an input source as a path string +// Other input types can be used, as mentioned in the docs +var inputSource = new LocalInputSource(filePath); + +// Call the API and parse the input +var response = await mindeeClient.ExecuteWorkflowAsync(workflowId, inputSource); + +// Print the execution ID to make sure it worked. +System.Console.WriteLine(response.Execution.Id); + +// Print the inference result. +// System.Console.WriteLine(response.Execution.Inference); diff --git a/tests/Mindee.UnitTests/Workflow/WorklowTest.cs b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs new file mode 100644 index 00000000..4a46ce47 --- /dev/null +++ b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs @@ -0,0 +1,142 @@ +using System.Text.Json; +using Mindee.Http; +using Mindee.Input; +using Mindee.Parsing.Common; +using Mindee.Pdf; +using Mindee.Product.Generated; +using Moq; + +namespace Mindee.UnitTests.Workflow +{ + [Trait("Category", "Workflow")] + public abstract class WorklowTest + { + private readonly MindeeClient client; + private readonly Mock mockedClient; + private readonly Mock mindeeApi; + + protected WorklowTest() + { + mindeeApi = new Mock(); + Mock pdfOperation = new Mock(); + client = new MindeeClient(pdfOperation.Object, mindeeApi.Object); + mockedClient = new Mock(); + } + + [Fact] + public async Task GivenAWorkflowMockFileShouldReturnAValidWorkflowObject() + { + // Arrange + var file = new FileInfo("src/test/resources/file_types/pdf/blank_1.pdf"); + var workflowResponse = new WorkflowResponse { Execution = new Execution(), ApiRequest = null }; + + mindeeApi.Setup(api => api.ExecutionQueuePost( + It.IsAny(), + It.IsAny())) + .ReturnsAsync(workflowResponse); + + // Act + var execution = await client.ExecuteWorkflowAsync( + "", + new LocalInputSource(file)); + + // Assert + Assert.NotNull(execution); + mindeeApi.Verify(api => api.ExecutionQueuePost( + It.IsAny(), + It.IsAny()), Times.Once); + } + + [Fact] + public async Task SendingADocumentToAnExecutionShouldDeserializeResponseCorrectly() + { + // Arrange + var jsonFile = File.ReadAllText("src/test/resources/workflows/success.json"); + var mockResponse = JsonSerializer.Deserialize>(jsonFile); + + mockedClient.Setup(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(mockResponse); + + string workflowId = "07ebf237-ff27-4eee-b6a2-425df4a5cca6"; + string filePath = "src/test/resources/products/financial_document/default_sample.jpg"; + var inputSource = new LocalInputSource(filePath); + + // Act + var response = await mockedClient.Object.ExecuteWorkflowAsync(workflowId, inputSource); + + // Assert + Assert.NotNull(response); + Assert.NotNull(response.ApiRequest); + Assert.Null(response.Execution.BatchName); + Assert.Null(response.Execution.CreatedAt); + Assert.Null(response.Execution.File.Alias); + Assert.Equal("default_sample.jpg", response.Execution.File.Name); + Assert.Equal("8c75c035-e083-4e77-ba3b-7c3598bd1d8a", response.Execution.Id); + Assert.Null(response.Execution.Inference); + Assert.Equal("medium", response.Execution.Priority); + Assert.Null(response.Execution.ReviewedAt); + Assert.Null(response.Execution.ReviewedPrediction); + Assert.Equal("processing", response.Execution.Status); + Assert.Equal("manual", response.Execution.Type); + Assert.Equal("2024-11-13T13:02:31.699190", + response.Execution.UploadedAt?.ToString("yyyy-MM-ddTHH:mm:ss.ffffff")); + Assert.Equal(workflowId, response.Execution.WorkflowId); + + mockedClient.Verify(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + workflowId, + It.Is(source => source.Filename == inputSource.Filename), + It.IsAny(), + It.IsAny()), Times.Once); + } + + [Fact] + public async Task SendingADocumentToAnExecutionWithPriorityAndAliasShouldDeserializeResponseCorrectly() + { + // Arrange + var jsonFile = File.ReadAllText("src/test/resources/workflows/success_low_priority.json"); + var mockResponse = JsonSerializer.Deserialize>(jsonFile); + + mockedClient.Setup(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(mockResponse); + + string workflowId = "07ebf237-ff27-4eee-b6a2-425df4a5cca6"; + string filePath = "src/test/resources/products/financial_document/default_sample.jpg"; + var inputSource = new LocalInputSource(filePath); + + // Act + var response = await mockedClient.Object.ExecuteWorkflowAsync(workflowId, inputSource); + + // Assert + Assert.NotNull(response); + Assert.NotNull(response.ApiRequest); + Assert.Null(response.Execution.BatchName); + Assert.Null(response.Execution.CreatedAt); + Assert.Equal("low-priority-sample-test", response.Execution.File.Alias); + Assert.Equal("default_sample.jpg", response.Execution.File.Name); + Assert.Equal("b743e123-e18c-4b62-8a07-811a4f72afd3", response.Execution.Id); + Assert.Null(response.Execution.Inference); + Assert.Equal("low", response.Execution.Priority); + Assert.Null(response.Execution.ReviewedAt); + Assert.Null(response.Execution.ReviewedPrediction); + Assert.Equal("processing", response.Execution.Status); + Assert.Equal("manual", response.Execution.Type); + Assert.Equal("2024-11-13T13:17:01.315179", + response.Execution.UploadedAt?.ToString("yyyy-MM-ddTHH:mm:ss.ffffff")); + Assert.Equal(workflowId, response.Execution.WorkflowId); + + mockedClient.Verify(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + workflowId, + It.Is(source => source.Filename == inputSource.Filename), + It.IsAny(), + It.IsAny()), Times.Once); + } + } +} From 6143deb4905857ee800ee0e43278a69ce088b195 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Thu, 14 Nov 2024 15:57:49 +0100 Subject: [PATCH 04/11] add URL loading for workflows --- src/Mindee/MindeeClient.cs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Mindee/MindeeClient.cs b/src/Mindee/MindeeClient.cs index 38221c44..d8a16df5 100644 --- a/src/Mindee/MindeeClient.cs +++ b/src/Mindee/MindeeClient.cs @@ -649,6 +649,38 @@ LocalInputSource inputSource cropper: predictOptions.Cropper)); } + /// + /// Send a remote file to a workflow execution. + /// + /// The workflow id. + /// + /// + /// Set the prediction model used to parse the document. + /// The response object will be instantiated based on this parameter. + /// + public async Task> ExecuteWorkflowAsync( + string workflowId, + UrlInputSource inputSource + , PredictOptions predictOptions = null) + where TInferenceModel : class, new() + { + _logger?.LogInformation("Asynchronous parsing of {} ...", typeof(TInferenceModel).Name); + + if (predictOptions == null) + { + predictOptions = new PredictOptions(); + } + + return await _mindeeApi.ExecutionQueuePost( + workflowId, + new PredictParameter( + localSource: null, + urlSource: inputSource, + allWords: predictOptions.AllWords, + fullText: predictOptions.FullText, + cropper: predictOptions.Cropper)); + } + /// /// Load a local prediction. /// Typically used when wanting to load from a webhook callback. From e6c4fc03dc9dcbb7dcb100c843e28460cb12a398 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Thu, 14 Nov 2024 16:00:14 +0100 Subject: [PATCH 05/11] rename mindeeAPI function --- src/Mindee/Http/IHttpApi.cs | 2 +- src/Mindee/Http/MindeeApi.cs | 2 +- src/Mindee/MindeeClient.cs | 4 ++-- tests/Mindee.UnitTests/Workflow/WorklowTest.cs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Mindee/Http/IHttpApi.cs b/src/Mindee/Http/IHttpApi.cs index 58bcb079..80f43a50 100644 --- a/src/Mindee/Http/IHttpApi.cs +++ b/src/Mindee/Http/IHttpApi.cs @@ -50,7 +50,7 @@ string jobId /// The ID of the workflow. /// /// Document type. - Task> ExecutionQueuePost( + Task> PostWorkflowExecution( string workflowId, PredictParameter predictParameter) where TModel : class, new(); diff --git a/src/Mindee/Http/MindeeApi.cs b/src/Mindee/Http/MindeeApi.cs index 9ccde186..4a121988 100644 --- a/src/Mindee/Http/MindeeApi.cs +++ b/src/Mindee/Http/MindeeApi.cs @@ -115,7 +115,7 @@ string jobId return handledResponse; } - public async Task> ExecutionQueuePost( + public async Task> PostWorkflowExecution( string workflowId, PredictParameter predictParameter) where TModel : class, new() diff --git a/src/Mindee/MindeeClient.cs b/src/Mindee/MindeeClient.cs index d8a16df5..701b5dbd 100644 --- a/src/Mindee/MindeeClient.cs +++ b/src/Mindee/MindeeClient.cs @@ -639,7 +639,7 @@ LocalInputSource inputSource predictOptions = new PredictOptions(); } - return await _mindeeApi.ExecutionQueuePost( + return await _mindeeApi.PostWorkflowExecution( workflowId, new PredictParameter( localSource: inputSource, @@ -671,7 +671,7 @@ UrlInputSource inputSource predictOptions = new PredictOptions(); } - return await _mindeeApi.ExecutionQueuePost( + return await _mindeeApi.PostWorkflowExecution( workflowId, new PredictParameter( localSource: null, diff --git a/tests/Mindee.UnitTests/Workflow/WorklowTest.cs b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs index 4a46ce47..7e52fd84 100644 --- a/tests/Mindee.UnitTests/Workflow/WorklowTest.cs +++ b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs @@ -30,7 +30,7 @@ public async Task GivenAWorkflowMockFileShouldReturnAValidWorkflowObject() var file = new FileInfo("src/test/resources/file_types/pdf/blank_1.pdf"); var workflowResponse = new WorkflowResponse { Execution = new Execution(), ApiRequest = null }; - mindeeApi.Setup(api => api.ExecutionQueuePost( + mindeeApi.Setup(api => api.PostWorkflowExecution( It.IsAny(), It.IsAny())) .ReturnsAsync(workflowResponse); @@ -42,7 +42,7 @@ public async Task GivenAWorkflowMockFileShouldReturnAValidWorkflowObject() // Assert Assert.NotNull(execution); - mindeeApi.Verify(api => api.ExecutionQueuePost( + mindeeApi.Verify(api => api.PostWorkflowExecution( It.IsAny(), It.IsAny()), Times.Once); } From 17f8f0c788532413e59824d8285e5fef27c0edb9 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Thu, 14 Nov 2024 16:06:00 +0100 Subject: [PATCH 06/11] fix code sample testing --- tests/test_code_samples.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_code_samples.sh b/tests/test_code_samples.sh index 89ed6e80..e16249ce 100755 --- a/tests/test_code_samples.sh +++ b/tests/test_code_samples.sh @@ -9,7 +9,7 @@ API_KEY=$3 if [ -z "${ACCOUNT}" ]; then echo "ACCOUNT is required"; exit 1; fi if [ -z "${ENDPOINT}" ]; then echo "ENDPOINT is required"; exit 1; fi -for f in $(find docs/code_samples -maxdepth 1 -name "*.txt" | sort -h) +for f in $(find docs/code_samples -maxdepth 1 -name "*.txt" -not -name "workflow_execution.txt" | sort -h) do echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" echo "${f}" From dfbf0ec7f2ea56e94f0091eff0bb86aba52a2ff1 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Fri, 15 Nov 2024 10:35:30 +0100 Subject: [PATCH 07/11] fix typo --- src/Mindee/Parsing/Common/ExecutionFile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mindee/Parsing/Common/ExecutionFile.cs b/src/Mindee/Parsing/Common/ExecutionFile.cs index 0ef9ee79..61b4442a 100644 --- a/src/Mindee/Parsing/Common/ExecutionFile.cs +++ b/src/Mindee/Parsing/Common/ExecutionFile.cs @@ -14,7 +14,7 @@ public class ExecutionFile public string Name { get; set; } /// - /// Identifier for the execution. + /// Optional alias for the file. /// [JsonPropertyName("alias")] public string Alias { get; set; } From 7eef138b16793ca71fd8f6d6802074845d30c507 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Mon, 18 Nov 2024 17:39:23 +0100 Subject: [PATCH 08/11] add alias & priority support --- docs/code_samples/workflow_execution.txt | 8 ++- src/Mindee/Http/GenericParameter.cs | 52 +++++++++++++++++ src/Mindee/Http/IHttpApi.cs | 4 +- src/Mindee/Http/MindeeApi.cs | 36 +++++++++++- src/Mindee/Http/PredictParameter.cs | 39 ++----------- src/Mindee/Http/WorkflowParameter.cs | 39 +++++++++++++ src/Mindee/MindeeClient.cs | 58 +++++++++---------- src/Mindee/MindeeClientOptions.cs | 38 ++++++++++++ .../Mindee.UnitTests/Workflow/WorklowTest.cs | 26 ++++----- 9 files changed, 215 insertions(+), 85 deletions(-) create mode 100644 src/Mindee/Http/GenericParameter.cs create mode 100644 src/Mindee/Http/WorkflowParameter.cs diff --git a/docs/code_samples/workflow_execution.txt b/docs/code_samples/workflow_execution.txt index c254debe..3f88535e 100644 --- a/docs/code_samples/workflow_execution.txt +++ b/docs/code_samples/workflow_execution.txt @@ -1,6 +1,5 @@ using Mindee; using Mindee.Input; -using Mindee.Product.Generated; string apiKey = "my-api-key"; string filePath = "/path/to/the/file.ext"; @@ -13,8 +12,11 @@ MindeeClient mindeeClient = new MindeeClient(apiKey); // Other input types can be used, as mentioned in the docs var inputSource = new LocalInputSource(filePath); -// Call the API and parse the input -var response = await mindeeClient.ExecuteWorkflowAsync(workflowId, inputSource); +// Send the document to a workflow execution +var response = await mindeeClient.ExecuteWorkflowAsync(workflowId, inputSource); + +// Alternatively, give it an alias: +// var response = await mindeeClient.ExecuteWorkflowAsync(workflowId, inputSource, new WorkflowOptions(alias: "my-alias")); // Print the execution ID to make sure it worked. System.Console.WriteLine(response.Execution.Id); diff --git a/src/Mindee/Http/GenericParameter.cs b/src/Mindee/Http/GenericParameter.cs new file mode 100644 index 00000000..9e96fe5d --- /dev/null +++ b/src/Mindee/Http/GenericParameter.cs @@ -0,0 +1,52 @@ +using Mindee.Exceptions; +using Mindee.Input; + +namespace Mindee.Http +{ + /// + /// G + /// + public class GenericParameter + { + + /// + /// A local input source. + /// + public LocalInputSource LocalSource { get; } + + /// + /// A URL input source. + /// + public UrlInputSource UrlSource { get; } + + /// + /// Whether to include the full text data for async APIs. + /// This performs a full OCR operation on the server and will increase response time and payload size. + /// + /// It is not available on all API. + public bool FullText { get; } + + /// + /// + /// + /// + /// + /// + /// + public GenericParameter(LocalInputSource localSource, UrlInputSource urlSource, bool fullText) + { + + if (localSource != null && urlSource != null) + { + throw new MindeeException("localSource and urlSource may not both be specified."); + } + if (localSource == null && urlSource == null) + { + throw new MindeeException("One of localSource or urlSource must be specified."); + } + LocalSource = localSource; + UrlSource = urlSource; + FullText = fullText; + } + } +} diff --git a/src/Mindee/Http/IHttpApi.cs b/src/Mindee/Http/IHttpApi.cs index 80f43a50..78e2e461 100644 --- a/src/Mindee/Http/IHttpApi.cs +++ b/src/Mindee/Http/IHttpApi.cs @@ -48,11 +48,11 @@ string jobId /// Send a document to a workflow. /// /// The ID of the workflow. - /// + /// /// Document type. Task> PostWorkflowExecution( string workflowId, - PredictParameter predictParameter) + WorkflowParameter workflowParameter) where TModel : class, new(); } } diff --git a/src/Mindee/Http/MindeeApi.cs b/src/Mindee/Http/MindeeApi.cs index 4a121988..4ddf9f6e 100644 --- a/src/Mindee/Http/MindeeApi.cs +++ b/src/Mindee/Http/MindeeApi.cs @@ -117,14 +117,14 @@ string jobId public async Task> PostWorkflowExecution( string workflowId, - PredictParameter predictParameter) + WorkflowParameter workflowParameter) where TModel : class, new() { var request = new RestRequest( $"v1/workflows/{workflowId}/executions" , Method.Post); - AddPredictRequestParameters(predictParameter, request); + AddWorkflowRequestParameters(workflowParameter, request); _logger?.LogInformation($"HTTP POST to {_baseUrl + request.Resource} ..."); @@ -132,6 +132,38 @@ public async Task> PostWorkflowExecution( return ResponseHandler>(response); } + private static void AddWorkflowRequestParameters(WorkflowParameter workflowParameter, RestRequest request) + { + if (workflowParameter.LocalSource != null) + { + request.AddFile( + "document", + workflowParameter.LocalSource.FileBytes, + workflowParameter.LocalSource.Filename); + } + else if (workflowParameter.UrlSource != null) + { + request.AddParameter( + "document", + workflowParameter.UrlSource.FileUrl.ToString()); + } + if (workflowParameter.FullText) + { + request.AddQueryParameter(name: "full_text_ocr", value: "true"); + } + + if (workflowParameter.Alias != null) + { + request.AddParameter(name: "alias", value: workflowParameter.Alias); + } + + if (workflowParameter.Priority != null) + { + request.AddParameter(name: "priority", value: workflowParameter.Priority); + } + + } + private static void AddPredictRequestParameters(PredictParameter predictParameter, RestRequest request) { if (predictParameter.LocalSource != null) diff --git a/src/Mindee/Http/PredictParameter.cs b/src/Mindee/Http/PredictParameter.cs index b0aa6ae3..3963cdce 100644 --- a/src/Mindee/Http/PredictParameter.cs +++ b/src/Mindee/Http/PredictParameter.cs @@ -1,4 +1,3 @@ -using Mindee.Exceptions; using Mindee.Input; namespace Mindee.Http @@ -6,31 +5,14 @@ namespace Mindee.Http /// /// Parameter required to use the predict feature. /// - public sealed class PredictParameter + public sealed class PredictParameter : GenericParameter { - /// - /// A local input source. - /// - public LocalInputSource LocalSource { get; } - - /// - /// A URL input source. - /// - public UrlInputSource UrlSource { get; } - /// /// Want an OCR result ? /// /// It is not available on all API. public bool AllWords { get; } - /// - /// Whether to include the full text data for async APIs. - /// This performs a full OCR operation on the server and will increase response time and payload size. - /// - /// It is not available on all API. - public bool FullText { get; } - /// /// Want the cropping result about the document? /// @@ -40,30 +22,19 @@ public sealed class PredictParameter /// /// Prediction parameters for requests. /// - /// Local input source containing the file. - /// Source URL to use. + /// Local input source containing the file. + /// Source URL to use. /// Whether to include the full OCR response in the payload (compatible APIs only). - /// Whether to include the full text in the payload (compatible APIs only) + /// Whether to include the full text in the payload (compatible APIs only) /// Whether to crop the document before enqueuing on the API. public PredictParameter( LocalInputSource localSource, UrlInputSource urlSource, bool allWords, bool fullText, - bool cropper) + bool cropper) : base(localSource, urlSource, fullText) { - if (localSource != null && urlSource != null) - { - throw new MindeeException("localSource and urlSource may not both be specified."); - } - if (localSource == null && urlSource == null) - { - throw new MindeeException("One of localSource or urlSource must be specified."); - } - LocalSource = localSource; - UrlSource = urlSource; AllWords = allWords; - FullText = fullText; Cropper = cropper; } } diff --git a/src/Mindee/Http/WorkflowParameter.cs b/src/Mindee/Http/WorkflowParameter.cs new file mode 100644 index 00000000..701a6052 --- /dev/null +++ b/src/Mindee/Http/WorkflowParameter.cs @@ -0,0 +1,39 @@ +using Mindee.Input; + +namespace Mindee.Http +{ + /// + /// Parameter required to use the workflow feature. + /// + public class WorkflowParameter : GenericParameter + { + /// + /// Alias to give to the file. + /// + public string Alias { get; } + + + /// + /// Priority to give to the execution. + /// + public string Priority { get; } + + /// + /// Workflow parameters. + /// + /// Local input source containing the file. + /// Source URL to use. + /// Whether to include the full text in the payload (compatible APIs only) + /// Alias to give to the document. + /// Priority to give to the document. + public WorkflowParameter( + LocalInputSource localSource, + UrlInputSource urlSource, bool fullText, + string alias, string priority) : base(localSource, urlSource, + fullText) + { + Alias = alias; + Priority = priority; + } + } +} diff --git a/src/Mindee/MindeeClient.cs b/src/Mindee/MindeeClient.cs index 701b5dbd..6cac60d2 100644 --- a/src/Mindee/MindeeClient.cs +++ b/src/Mindee/MindeeClient.cs @@ -614,19 +614,16 @@ LocalInputSource inputSource /// /// The workflow id. /// - /// + /// /// - /// Set the prediction model used to parse the document. - /// The response object will be instantiated based on this parameter. /// - public async Task> ExecuteWorkflowAsync( + public async Task> ExecuteWorkflowAsync( string workflowId, - LocalInputSource inputSource - , PredictOptions predictOptions = null - , PageOptions pageOptions = null) - where TInferenceModel : class, new() + LocalInputSource inputSource, + WorkflowOptions workflowOptions = null, + PageOptions pageOptions = null) { - _logger?.LogInformation("Asynchronous parsing of {} ...", typeof(TInferenceModel).Name); + _logger?.LogInformation("Workflow enqueing {} ...", inputSource.Filename); if (pageOptions != null && inputSource.IsPdf()) { @@ -634,19 +631,20 @@ LocalInputSource inputSource new SplitQuery(inputSource.FileBytes, pageOptions)).File; } - if (predictOptions == null) + if (workflowOptions == null) { - predictOptions = new PredictOptions(); + workflowOptions = new WorkflowOptions(); } - return await _mindeeApi.PostWorkflowExecution( + return await _mindeeApi.PostWorkflowExecution( workflowId, - new PredictParameter( + new WorkflowParameter( localSource: inputSource, urlSource: null, - allWords: predictOptions.AllWords, - fullText: predictOptions.FullText, - cropper: predictOptions.Cropper)); + alias: workflowOptions.Alias, + priority: workflowOptions.Priority, + fullText: workflowOptions.FullText + )); } /// @@ -654,31 +652,29 @@ LocalInputSource inputSource /// /// The workflow id. /// - /// - /// Set the prediction model used to parse the document. - /// The response object will be instantiated based on this parameter. + /// /// - public async Task> ExecuteWorkflowAsync( + public async Task> ExecuteWorkflowAsync( string workflowId, - UrlInputSource inputSource - , PredictOptions predictOptions = null) - where TInferenceModel : class, new() + UrlInputSource inputSource, + WorkflowOptions workflowOptions = null) { - _logger?.LogInformation("Asynchronous parsing of {} ...", typeof(TInferenceModel).Name); + _logger?.LogInformation("Asynchronous parsing of {} ...", inputSource.FileUrl); - if (predictOptions == null) + if (workflowOptions == null) { - predictOptions = new PredictOptions(); + workflowOptions = new WorkflowOptions(); } - return await _mindeeApi.PostWorkflowExecution( + return await _mindeeApi.PostWorkflowExecution( workflowId, - new PredictParameter( + new WorkflowParameter( localSource: null, urlSource: inputSource, - allWords: predictOptions.AllWords, - fullText: predictOptions.FullText, - cropper: predictOptions.Cropper)); + alias: workflowOptions.Alias, + priority: workflowOptions.Priority, + fullText: workflowOptions.FullText + )); } /// diff --git a/src/Mindee/MindeeClientOptions.cs b/src/Mindee/MindeeClientOptions.cs index bbd4eafc..6775c1d3 100644 --- a/src/Mindee/MindeeClientOptions.cs +++ b/src/Mindee/MindeeClientOptions.cs @@ -102,4 +102,42 @@ public AsyncPollingOptions(double initialDelaySec = 2.0, double intervalSec = 1. IntervalMilliSec = (int)Math.Floor(IntervalSec * 1000); } } + + /// + /// Options for workflow executions. + /// + public sealed class WorkflowOptions + { + + /// + /// Alias to give to the file. + /// + public string Alias { get; } + + + /// + /// Priority to give to the execution. + /// + public string Priority { get; } + + + /// + /// Whether to include the full text data for async APIs. + /// This performs a full OCR operation on the server and will increase response time and payload size. + /// + public bool FullText { get; } + + /// + /// Options for workflow executions. + /// + /// + /// + /// + public WorkflowOptions(string alias = null, string priority = null, bool fullText = false) + { + Alias = alias; + Priority = priority; + FullText = fullText; + } + } } diff --git a/tests/Mindee.UnitTests/Workflow/WorklowTest.cs b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs index 7e52fd84..de8542bb 100644 --- a/tests/Mindee.UnitTests/Workflow/WorklowTest.cs +++ b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs @@ -32,11 +32,11 @@ public async Task GivenAWorkflowMockFileShouldReturnAValidWorkflowObject() mindeeApi.Setup(api => api.PostWorkflowExecution( It.IsAny(), - It.IsAny())) + It.IsAny())) .ReturnsAsync(workflowResponse); // Act - var execution = await client.ExecuteWorkflowAsync( + var execution = await client.ExecuteWorkflowAsync( "", new LocalInputSource(file)); @@ -44,7 +44,7 @@ public async Task GivenAWorkflowMockFileShouldReturnAValidWorkflowObject() Assert.NotNull(execution); mindeeApi.Verify(api => api.PostWorkflowExecution( It.IsAny(), - It.IsAny()), Times.Once); + It.IsAny()), Times.Once); } [Fact] @@ -54,10 +54,10 @@ public async Task SendingADocumentToAnExecutionShouldDeserializeResponseCorrectl var jsonFile = File.ReadAllText("src/test/resources/workflows/success.json"); var mockResponse = JsonSerializer.Deserialize>(jsonFile); - mockedClient.Setup(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + mockedClient.Setup(mindeeClient => mindeeClient.ExecuteWorkflowAsync( It.IsAny(), It.IsAny(), - It.IsAny(), + It.IsAny(), It.IsAny())) .ReturnsAsync(mockResponse); @@ -66,7 +66,7 @@ public async Task SendingADocumentToAnExecutionShouldDeserializeResponseCorrectl var inputSource = new LocalInputSource(filePath); // Act - var response = await mockedClient.Object.ExecuteWorkflowAsync(workflowId, inputSource); + var response = await mockedClient.Object.ExecuteWorkflowAsync(workflowId, inputSource); // Assert Assert.NotNull(response); @@ -86,10 +86,10 @@ public async Task SendingADocumentToAnExecutionShouldDeserializeResponseCorrectl response.Execution.UploadedAt?.ToString("yyyy-MM-ddTHH:mm:ss.ffffff")); Assert.Equal(workflowId, response.Execution.WorkflowId); - mockedClient.Verify(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + mockedClient.Verify(mindeeClient => mindeeClient.ExecuteWorkflowAsync( workflowId, It.Is(source => source.Filename == inputSource.Filename), - It.IsAny(), + It.IsAny(), It.IsAny()), Times.Once); } @@ -100,10 +100,10 @@ public async Task SendingADocumentToAnExecutionWithPriorityAndAliasShouldDeseria var jsonFile = File.ReadAllText("src/test/resources/workflows/success_low_priority.json"); var mockResponse = JsonSerializer.Deserialize>(jsonFile); - mockedClient.Setup(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + mockedClient.Setup(mindeeClient => mindeeClient.ExecuteWorkflowAsync( It.IsAny(), It.IsAny(), - It.IsAny(), + It.IsAny(), It.IsAny())) .ReturnsAsync(mockResponse); @@ -112,7 +112,7 @@ public async Task SendingADocumentToAnExecutionWithPriorityAndAliasShouldDeseria var inputSource = new LocalInputSource(filePath); // Act - var response = await mockedClient.Object.ExecuteWorkflowAsync(workflowId, inputSource); + var response = await mockedClient.Object.ExecuteWorkflowAsync(workflowId, inputSource); // Assert Assert.NotNull(response); @@ -132,10 +132,10 @@ public async Task SendingADocumentToAnExecutionWithPriorityAndAliasShouldDeseria response.Execution.UploadedAt?.ToString("yyyy-MM-ddTHH:mm:ss.ffffff")); Assert.Equal(workflowId, response.Execution.WorkflowId); - mockedClient.Verify(mindeeClient => mindeeClient.ExecuteWorkflowAsync( + mockedClient.Verify(mindeeClient => mindeeClient.ExecuteWorkflowAsync( workflowId, It.Is(source => source.Filename == inputSource.Filename), - It.IsAny(), + It.IsAny(), It.IsAny()), Times.Once); } } From 798b65615be31188082226b9e87c2df28532b0a5 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Tue, 19 Nov 2024 10:58:31 +0100 Subject: [PATCH 09/11] fix priority syntax --- src/Mindee/Http/MindeeApi.cs | 5 +- src/Mindee/Http/WorkflowParameter.cs | 5 +- src/Mindee/Input/ExecutionPriority.cs | 60 +++++++++++++++++++ src/Mindee/MindeeClient.cs | 7 +-- src/Mindee/MindeeClientOptions.cs | 5 +- src/Mindee/Parsing/Common/Execution.cs | 4 +- .../Mindee.UnitTests/Workflow/WorklowTest.cs | 4 +- 7 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 src/Mindee/Input/ExecutionPriority.cs diff --git a/src/Mindee/Http/MindeeApi.cs b/src/Mindee/Http/MindeeApi.cs index 4ddf9f6e..2f1f5417 100644 --- a/src/Mindee/Http/MindeeApi.cs +++ b/src/Mindee/Http/MindeeApi.cs @@ -159,7 +159,10 @@ private static void AddWorkflowRequestParameters(WorkflowParameter workflowParam if (workflowParameter.Priority != null) { - request.AddParameter(name: "priority", value: workflowParameter.Priority); + request.AddParameter( + name: "priority", + value: workflowParameter.Priority != null ? + workflowParameter.Priority.ToString()?.ToLower() : null); } } diff --git a/src/Mindee/Http/WorkflowParameter.cs b/src/Mindee/Http/WorkflowParameter.cs index 701a6052..5668efdb 100644 --- a/src/Mindee/Http/WorkflowParameter.cs +++ b/src/Mindee/Http/WorkflowParameter.cs @@ -1,3 +1,4 @@ +using System; using Mindee.Input; namespace Mindee.Http @@ -16,7 +17,7 @@ public class WorkflowParameter : GenericParameter /// /// Priority to give to the execution. /// - public string Priority { get; } + public ExecutionPriority? Priority { get; } /// /// Workflow parameters. @@ -29,7 +30,7 @@ public class WorkflowParameter : GenericParameter public WorkflowParameter( LocalInputSource localSource, UrlInputSource urlSource, bool fullText, - string alias, string priority) : base(localSource, urlSource, + string alias, ExecutionPriority? priority) : base(localSource, urlSource, fullText) { Alias = alias; diff --git a/src/Mindee/Input/ExecutionPriority.cs b/src/Mindee/Input/ExecutionPriority.cs new file mode 100644 index 00000000..a36d48a3 --- /dev/null +++ b/src/Mindee/Input/ExecutionPriority.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel; +using System.Runtime.Serialization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Mindee.Input +{ + /// + /// Priority for a workflow execution. + /// + public enum ExecutionPriority + { + /// + /// Low priority. + /// + [EnumMember(Value = "low")] Low, + + /// + /// Medium priority. + /// + [EnumMember(Value = "medium")] Medium, + + /// + /// Hight priority. + /// + [EnumMember(Value = "high")] High + } + + /// + /// Deserializer for the ExecutionPriority enum. + /// + /// + public class StringEnumConverter : JsonConverter where T : struct, Enum + { + /// + /// Read a JSON value. + /// + /// + /// + /// + /// + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + string value = reader.GetString(); + return Enum.TryParse(value, true, out var result) ? result : default; + } + + /// + /// Retrieves a JSON value. + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString().ToLower()); + } + } +} diff --git a/src/Mindee/MindeeClient.cs b/src/Mindee/MindeeClient.cs index 6cac60d2..3011eb52 100644 --- a/src/Mindee/MindeeClient.cs +++ b/src/Mindee/MindeeClient.cs @@ -623,7 +623,7 @@ public async Task> ExecuteWorkflowAsync( WorkflowOptions workflowOptions = null, PageOptions pageOptions = null) { - _logger?.LogInformation("Workflow enqueing {} ...", inputSource.Filename); + _logger?.LogInformation("Sending '{}' to workflow '{}'...", inputSource.Filename, workflowId); if (pageOptions != null && inputSource.IsPdf()) { @@ -631,10 +631,7 @@ public async Task> ExecuteWorkflowAsync( new SplitQuery(inputSource.FileBytes, pageOptions)).File; } - if (workflowOptions == null) - { - workflowOptions = new WorkflowOptions(); - } + workflowOptions ??= new WorkflowOptions(); return await _mindeeApi.PostWorkflowExecution( workflowId, diff --git a/src/Mindee/MindeeClientOptions.cs b/src/Mindee/MindeeClientOptions.cs index 6775c1d3..3379054d 100644 --- a/src/Mindee/MindeeClientOptions.cs +++ b/src/Mindee/MindeeClientOptions.cs @@ -1,5 +1,6 @@ using System; using Mindee.Exceptions; +using Mindee.Input; namespace Mindee { @@ -118,7 +119,7 @@ public sealed class WorkflowOptions /// /// Priority to give to the execution. /// - public string Priority { get; } + public ExecutionPriority? Priority { get; } /// @@ -133,7 +134,7 @@ public sealed class WorkflowOptions /// /// /// - public WorkflowOptions(string alias = null, string priority = null, bool fullText = false) + public WorkflowOptions(string alias = null, ExecutionPriority? priority = null, bool fullText = false) { Alias = alias; Priority = priority; diff --git a/src/Mindee/Parsing/Common/Execution.cs b/src/Mindee/Parsing/Common/Execution.cs index 24248124..f634ed5f 100644 --- a/src/Mindee/Parsing/Common/Execution.cs +++ b/src/Mindee/Parsing/Common/Execution.cs @@ -1,5 +1,6 @@ using System; using System.Text.Json.Serialization; +using Mindee.Input; using Mindee.Product.Generated; namespace Mindee.Parsing.Common @@ -44,7 +45,8 @@ namespace Mindee.Parsing.Common /// Priority of the execution. /// [JsonPropertyName("priority")] - public string Priority { get; set; } + [JsonConverter(typeof(StringEnumConverter))] + public ExecutionPriority Priority { get; set; } /// /// The time at which the file was tagged as reviewed. diff --git a/tests/Mindee.UnitTests/Workflow/WorklowTest.cs b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs index de8542bb..5e508b6a 100644 --- a/tests/Mindee.UnitTests/Workflow/WorklowTest.cs +++ b/tests/Mindee.UnitTests/Workflow/WorklowTest.cs @@ -77,7 +77,7 @@ public async Task SendingADocumentToAnExecutionShouldDeserializeResponseCorrectl Assert.Equal("default_sample.jpg", response.Execution.File.Name); Assert.Equal("8c75c035-e083-4e77-ba3b-7c3598bd1d8a", response.Execution.Id); Assert.Null(response.Execution.Inference); - Assert.Equal("medium", response.Execution.Priority); + Assert.Equal(ExecutionPriority.Medium, response.Execution.Priority); Assert.Null(response.Execution.ReviewedAt); Assert.Null(response.Execution.ReviewedPrediction); Assert.Equal("processing", response.Execution.Status); @@ -123,7 +123,7 @@ public async Task SendingADocumentToAnExecutionWithPriorityAndAliasShouldDeseria Assert.Equal("default_sample.jpg", response.Execution.File.Name); Assert.Equal("b743e123-e18c-4b62-8a07-811a4f72afd3", response.Execution.Id); Assert.Null(response.Execution.Inference); - Assert.Equal("low", response.Execution.Priority); + Assert.Equal(ExecutionPriority.Low, response.Execution.Priority); Assert.Null(response.Execution.ReviewedAt); Assert.Null(response.Execution.ReviewedPrediction); Assert.Equal("processing", response.Execution.Status); From 82e8c5bc285df5085fd3f162be8dedf69c2bb30a Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Tue, 19 Nov 2024 11:01:37 +0100 Subject: [PATCH 10/11] move execution priority into different namespace --- src/Mindee/{Input => Parsing/Common}/ExecutionPriority.cs | 1 - 1 file changed, 1 deletion(-) rename src/Mindee/{Input => Parsing/Common}/ExecutionPriority.cs (98%) diff --git a/src/Mindee/Input/ExecutionPriority.cs b/src/Mindee/Parsing/Common/ExecutionPriority.cs similarity index 98% rename from src/Mindee/Input/ExecutionPriority.cs rename to src/Mindee/Parsing/Common/ExecutionPriority.cs index a36d48a3..78e749d9 100644 --- a/src/Mindee/Input/ExecutionPriority.cs +++ b/src/Mindee/Parsing/Common/ExecutionPriority.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using System.Runtime.Serialization; using System.Text.Json; using System.Text.Json.Serialization; From a90244d6d9152c330d4345dac576cf195f217465 Mon Sep 17 00:00:00 2001 From: sebastianMindee Date: Wed, 20 Nov 2024 16:38:24 +0100 Subject: [PATCH 11/11] add integration test --- .github/workflows/integration-tests.yml | 1 + .../Workflow/WorkflowTest.cs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/Mindee.IntegrationTests/Workflow/WorkflowTest.cs diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index eb01f93f..5ad4058a 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -10,6 +10,7 @@ on: env: Mindee__ApiKey: ${{ secrets.MINDEE_API_KEY_SE_TESTS }} + Workflow__ID: ${{ secrets.WORKFLOW_ID_SE_TESTS }} jobs: test-nix: diff --git a/tests/Mindee.IntegrationTests/Workflow/WorkflowTest.cs b/tests/Mindee.IntegrationTests/Workflow/WorkflowTest.cs new file mode 100644 index 00000000..3bc776e0 --- /dev/null +++ b/tests/Mindee.IntegrationTests/Workflow/WorkflowTest.cs @@ -0,0 +1,25 @@ +using Mindee.Input; + +namespace Mindee.IntegrationTests.Workflow +{ + [Trait("Category", "Integration tests")] + public class WorkflowTest + { + [Fact] + public async Task Given_AWorkflowIDShouldReturnACorrectWorkflowObject() + { + var apiKey = Environment.GetEnvironmentVariable("Mindee__ApiKey"); + var client = TestingUtilities.GetOrGenerateMindeeClient(apiKey); + var inputSource = new LocalInputSource("Resources/products/financial_document/default_sample.jpg"); + + string currentDateTime = DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss"); + var alias = "dotnet-" + currentDateTime; + WorkflowOptions options = new WorkflowOptions(alias, ExecutionPriority.Low); + var response = await client.ExecuteWorkflowAsync(Environment.GetEnvironmentVariable("Workflow__ID"), inputSource, options); + + Assert.Equal(ExecutionPriority.Low, response.Execution.Priority); + Assert.Equal(alias, response.Execution.File.Alias); + + } + } +}