From 406a59e3bb461594ac0ffcc9f3a67f77ca7e8969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ianar=C3=A9=20S=C3=A9vi?= Date: Wed, 27 May 2026 16:16:51 +0200 Subject: [PATCH] :sparkles: Add support for extraction in crop, split, and classify --- .../ClassificationClassifier.cs | 7 +++ src/Mindee/V2/Product/Crop/CropItem.cs | 7 +++ src/Mindee/V2/Product/Split/SplitRange.cs | 7 +++ .../V2/Product/ClassificationTest.cs | 4 +- .../V2/Product/ClassificationTest.cs | 30 ++++++++++++- tests/Mindee.UnitTests/V2/Product/CropTest.cs | 44 +++++++++++++++++++ .../Mindee.UnitTests/V2/Product/SplitTest.cs | 42 ++++++++++++++++++ tests/resources | 2 +- 8 files changed, 139 insertions(+), 4 deletions(-) diff --git a/src/Mindee/V2/Product/Classification/ClassificationClassifier.cs b/src/Mindee/V2/Product/Classification/ClassificationClassifier.cs index fdc64354..43603f10 100644 --- a/src/Mindee/V2/Product/Classification/ClassificationClassifier.cs +++ b/src/Mindee/V2/Product/Classification/ClassificationClassifier.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using Mindee.V2.Product.Extraction; namespace Mindee.V2.Product.Classification { @@ -13,6 +14,12 @@ public class ClassificationClassifier [JsonPropertyName("document_type")] public string DocumentType { get; set; } + /// + /// The extraction response associated with the classification. + /// + [JsonPropertyName("extraction_response")] + public ExtractionResponse ExtractionResponse { get; set; } + /// /// A prettier representation of the feature values. /// diff --git a/src/Mindee/V2/Product/Crop/CropItem.cs b/src/Mindee/V2/Product/Crop/CropItem.cs index d703f28e..b8e9499b 100644 --- a/src/Mindee/V2/Product/Crop/CropItem.cs +++ b/src/Mindee/V2/Product/Crop/CropItem.cs @@ -5,6 +5,7 @@ using Mindee.Image; using Mindee.Input; using Mindee.V2.Parsing.Inference.Field; +using Mindee.V2.Product.Extraction; namespace Mindee.V2.Product.Crop { @@ -25,6 +26,12 @@ public class CropItem [JsonPropertyName("location")] public FieldLocation Location { get; set; } + /// + /// The extraction response associated with the crop. + /// + [JsonPropertyName("extraction_response")] + public ExtractionResponse ExtractionResponse { get; set; } + /// /// String representation of the crop item. /// diff --git a/src/Mindee/V2/Product/Split/SplitRange.cs b/src/Mindee/V2/Product/Split/SplitRange.cs index 7b93519d..e021123d 100644 --- a/src/Mindee/V2/Product/Split/SplitRange.cs +++ b/src/Mindee/V2/Product/Split/SplitRange.cs @@ -2,6 +2,7 @@ using System.Text.Json.Serialization; using Mindee.Input; using Mindee.Pdf; +using Mindee.V2.Product.Extraction; namespace Mindee.V2.Product.Split { @@ -22,6 +23,12 @@ public class SplitRange [JsonPropertyName("document_type")] public string DocumentType { get; set; } + /// + /// The extraction response associated with the split. + /// + [JsonPropertyName("extraction_response")] + public ExtractionResponse ExtractionResponse { get; set; } + /// /// String representation of the split item. /// diff --git a/tests/Mindee.IntegrationTests/V2/Product/ClassificationTest.cs b/tests/Mindee.IntegrationTests/V2/Product/ClassificationTest.cs index 8750da7d..def8a19f 100644 --- a/tests/Mindee.IntegrationTests/V2/Product/ClassificationTest.cs +++ b/tests/Mindee.IntegrationTests/V2/Product/ClassificationTest.cs @@ -23,7 +23,7 @@ public ClassificationTest() public async Task Classification_DefaultSample_MustSucceed() { var inputSource = new LocalInputSource( - Constants.V2ProductDir + "classification/default_invoice.jpg"); + Constants.V2ProductDir + "classification/default_sample.jpg"); var productParams = new ClassificationParameters(_classificationModelId); var response = await _client.EnqueueAndGetResultAsync( @@ -34,7 +34,7 @@ public async Task Classification_DefaultSample_MustSucceed() var file = response.Inference.File; Assert.NotNull(file); - Assert.Equal("default_invoice.jpg", file.Name); + Assert.Equal("default_sample.jpg", file.Name); var result = response.Inference.Result; Assert.NotNull(result); diff --git a/tests/Mindee.UnitTests/V2/Product/ClassificationTest.cs b/tests/Mindee.UnitTests/V2/Product/ClassificationTest.cs index d94858ae..c31bcbff 100644 --- a/tests/Mindee.UnitTests/V2/Product/ClassificationTest.cs +++ b/tests/Mindee.UnitTests/V2/Product/ClassificationTest.cs @@ -3,6 +3,7 @@ using Mindee.V2.Product; using Mindee.V2.Product.Classification; using Mindee.V2.Product.Classification.Params; +using Mindee.V2.Product.Extraction; namespace Mindee.UnitTests.V2.Product { @@ -23,7 +24,7 @@ public void Parameters_MustInit() [Fact] public void Classification_WhenSingle_MustHaveValidProperties() { - var response = GetInference("classification/classification_single.json"); + var response = GetInference("classification/default_sample.json"); AssertInferenceResponse(response); var inference = response.Inference; @@ -40,6 +41,33 @@ public void Classification_WhenSingle_MustHaveValidProperties() Assert.Equal("invoice", classification.DocumentType); } + [Fact] + public void Classification_WithExtraction_MustHaveValidProperties() + { + var response = GetInference("classification/default_sample_extraction.json"); + Assert.NotNull(response.Inference); + Assert.Equal( + "invoice", + response.Inference.Result.Classification.DocumentType + ); + + ExtractionResponse extractionResponse = response + .Inference + .Result + .Classification + .ExtractionResponse; + Assert.NotNull(extractionResponse); + Assert.Equal( + "Jiro Doi", + extractionResponse + .Inference + .Result + .Fields["customer_name"] + .SimpleField + .Value + ); + } + private static ClassificationResponse GetInference(string path) { var localResponse = new LocalResponse( diff --git a/tests/Mindee.UnitTests/V2/Product/CropTest.cs b/tests/Mindee.UnitTests/V2/Product/CropTest.cs index 3a5471f6..5b13d30f 100644 --- a/tests/Mindee.UnitTests/V2/Product/CropTest.cs +++ b/tests/Mindee.UnitTests/V2/Product/CropTest.cs @@ -98,6 +98,50 @@ public void Crop_WhenMultiple_MustHaveValidProperties() Assert.Equal(new Point(0.547, 0.97), secondPolygon[3]); } + [Fact(DisplayName = "extraction properties must be valid")] + public void Crop_WithExtraction_MustHaveValidProperties() + { + var response = GetInference("crop/default_sample_extraction.json"); + Assert.NotNull(response.Inference); + + var crops = response.Inference.Result.Crops; + Assert.Equal(2, crops.Count); + + var crop0 = crops[0]; + Assert.Equal("receipt", crop0.ObjectType); + Assert.NotNull(crop0.Location.Polygon); + Assert.Equal(0, crop0.Location.Page); + + var extractionResponse0 = crop0.ExtractionResponse; + Assert.NotNull(extractionResponse0); + Assert.Equal( + "CHEZ ALAIN MIAM MIAM", + extractionResponse0 + .Inference + .Result + .Fields["supplier_name"] + .SimpleField + .Value + ); + + var crop1 = crops[1]; + Assert.Equal("receipt", crop1.ObjectType); + Assert.NotNull(crop1.Location.Polygon); + Assert.Equal(0, crop1.Location.Page); + + var extractionResponse1 = crop1.ExtractionResponse; + Assert.NotNull(extractionResponse1); + Assert.Equal( + "La cerise sur la pizza", + extractionResponse1 + .Inference + .Result + .Fields["supplier_name"] + .SimpleField + .Value + ); + } + [Fact(DisplayName = "crop_single.rst – RST display must be parsed and exposed")] public void RstDisplay_MustBeAccessible() { diff --git a/tests/Mindee.UnitTests/V2/Product/SplitTest.cs b/tests/Mindee.UnitTests/V2/Product/SplitTest.cs index ee70e791..608ff595 100644 --- a/tests/Mindee.UnitTests/V2/Product/SplitTest.cs +++ b/tests/Mindee.UnitTests/V2/Product/SplitTest.cs @@ -76,6 +76,48 @@ public void Split_WhenMultiple_MustHaveValidProperties() Assert.Equal(3, secondSplit.PageRange[1]); } + [Fact] + public void Split_WithExtraction_MustHaveValidProperties() + { + var response = GetInference("split/default_sample_extraction.json"); + Assert.NotNull(response.Inference); + + var splits = response.Inference.Result.Splits; + Assert.Equal(2, splits.Count); + + var split0 = splits[0]; + Assert.Equal("invoice", split0.DocumentType); + Assert.Equal(0, split0.PageRange[0]); + + var extractionResponse0 = split0.ExtractionResponse; + Assert.NotNull(extractionResponse0); + Assert.Equal( + "05 05 44 44 90", + extractionResponse0 + .Inference + .Result + .Fields["supplier_phone_number"] + .SimpleField + .Value + ); + + var split1 = splits[1]; + Assert.Equal("invoice", split1.DocumentType); + Assert.Equal(1, split1.PageRange[0]); + + var extractionResponse1 = split1.ExtractionResponse; + Assert.NotNull(extractionResponse1); + Assert.Equal( + "416-555-1212", + extractionResponse1 + .Inference + .Result + .Fields["supplier_phone_number"] + .SimpleField + .Value + ); + } + private static SplitResponse GetInference(string path) { var localResponse = new LocalResponse( diff --git a/tests/resources b/tests/resources index 53f0efbc..13093f3a 160000 --- a/tests/resources +++ b/tests/resources @@ -1 +1 @@ -Subproject commit 53f0efbc08c77c2c085aadd27de9d2d6c359276e +Subproject commit 13093f3a48de212ef26889df71199c1a2a9d1478