Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/Mindee/Parsing/V2/ErrorItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Text.Json.Serialization;

namespace Mindee.Parsing.V2
{
/// <summary>
/// Explicit details on a problem.
/// </summary>
public class ErrorItem
{
/// <summary>
/// A JSON Pointer to the location of the body property.
/// </summary>
[JsonPropertyName("pointer")]
public string Pointer { get; set; }

/// <summary>
/// Explicit information on the issue.
/// </summary>
[JsonPropertyName("detail")]
public string Detail { get; set; }
}
}
29 changes: 24 additions & 5 deletions src/Mindee/Parsing/V2/ErrorResponse.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Mindee.Parsing.V2
{
/// <summary>
/// Represent an error information from the API response.
/// Error response detailing a problem. The format adheres to RFC 9457.
/// </summary>
public class ErrorResponse
{
/// <summary>
/// Detail relevant to the error.
/// The HTTP status code returned by the server.
/// </summary>
[JsonPropertyName("status")]
public int Status { get; set; }

/// <summary>
/// A human-readable explanation specific to the occurrence of the problem.
/// </summary>
[JsonPropertyName("detail")]
public string Detail { get; set; }

/// <summary>
/// Http error code.
/// A short, human-readable summary of the problem.
/// </summary>
[JsonPropertyName("status")]
public int Status { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }

/// <summary>
/// A machine-readable code specific to the occurrence of the problem.
/// </summary>
[JsonPropertyName("code")]
public string Code { get; set; }

/// <summary>
/// A list of explicit details on the problem.
/// </summary>
[JsonPropertyName("errors")]
public List<ErrorItem> Errors { get; set; }

/// <summary>
/// To make the error prettier to display.
Expand Down
2 changes: 1 addition & 1 deletion src/Mindee/Parsing/V2/InferenceResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class InferenceResult
/// RAG metadata.
/// </summary>
[JsonPropertyName("rag")]
public RawText Rag { get; set; }
public RagMetadata Rag { get; set; }

/// <summary>
/// A prettier representation of the feature values.
Expand Down
20 changes: 10 additions & 10 deletions src/Mindee/Parsing/V2/Job.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
namespace Mindee.Parsing.V2
{
/// <summary>
/// Defines an enqueued job.
/// Information on the processing of a file sent to the Mindee API.
/// </summary>
public class Job
{
/// <summary>
/// Date and time the job was created at.
/// Date and time of the Job creation.
/// </summary>
[JsonPropertyName("created_at")]
[JsonConverter(typeof(DateTimeJsonConverter))]
public DateTime CreatedAt { get; set; }

/// <summary>
/// Unique identifier of the job.
/// UUID of the Job.
/// </summary>
[JsonPropertyName("id")]
public string Id { get; set; }
Expand All @@ -29,43 +29,43 @@ public class Job
public string Status { get; set; }

/// <summary>
/// An error encountered while processing the job.
/// If an error occurred during processing, contains the problem details.
/// </summary>
[JsonPropertyName("error")]
public ErrorResponse Error { get; set; }

/// <summary>
/// ID of the model.
/// UUID of the model to be used for the inference.
/// </summary>
[JsonPropertyName("model_id")]
public string ModelId { get; set; }

/// <summary>
/// Name of the file.
/// Name of the file sent.
/// </summary>
[JsonPropertyName("file_name")]
public string FileName { get; set; }

/// <summary>
/// Optional Alias for the file.
/// Optional alias sent for the file.
/// </summary>
[JsonPropertyName("file_alias")]
public string FileAlias { get; set; }

/// <summary>
/// URL to use for polling.
/// URL to poll for the Job status.
/// </summary>
[JsonPropertyName("polling_url")]
public string PollingUrl { get; set; }

/// <summary>
/// URL to follow for the final result.
/// URL to retrieve the inference results. Will be filled once the inference is ready.
/// </summary>
[JsonPropertyName("result_url")]
public string ResultUrl { get; set; }

/// <summary>
/// Webhooks to call.
/// List of responses from webhooks called. Empty until processing is finished.
/// </summary>
[JsonPropertyName("webhooks")]
public List<JobWebhook> Webhooks { get; set; }
Expand Down
12 changes: 12 additions & 0 deletions tests/Mindee.IntegrationTests/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Mindee.IntegrationTests
{
public static class Constants
{
public const string RootDir = "Resources/";

public const string V1RootDir = RootDir + "v1/";
public const string V1ProductDir = V1RootDir + "products/";

public const string V2RootDir = RootDir + "v2/";
}
}
10 changes: 5 additions & 5 deletions tests/Mindee.IntegrationTests/DependencyInjectionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,32 +50,32 @@ public void ShouldInitBothClients()
public async Task ShouldMaintainAuthenticationAcrossMultipleRequests()
{
MindeeClient instance1ClientV1 = _services.GetRequiredService<MindeeClient>();
var inputSource1 = new LocalInputSource(new FileInfo("Resources/file_types/pdf/blank_1.pdf"));
var inputSource1 = new LocalInputSource(new FileInfo(Constants.RootDir + "file_types/pdf/blank_1.pdf"));
var response1 = await instance1ClientV1.ParseAsync<InvoiceV4>(inputSource1);
Assert.NotNull(response1);
Assert.True(response1.Document != null, "First V1 request should return a valid document");

MindeeClient instance2ClientV1 = _services.GetRequiredService<MindeeClient>();
var inputSource2 = new LocalInputSource(new FileInfo("Resources/file_types/pdf/blank_1.pdf"));
var inputSource2 = new LocalInputSource(new FileInfo(Constants.RootDir + "file_types/pdf/blank_1.pdf"));
var response2 = await instance2ClientV1.ParseAsync<InvoiceV4>(inputSource2);
Assert.NotNull(response2);
Assert.True(response2.Document != null, "Second V1 request should return a valid document");

MindeeClientV2 instance1ClientV2 = _services.GetRequiredService<MindeeClientV2>();
var inputSource3 = new LocalInputSource(new FileInfo("Resources/file_types/pdf/blank_1.pdf"));
var inputSource3 = new LocalInputSource(new FileInfo(Constants.RootDir + "file_types/pdf/blank_1.pdf"));
var response3 = await instance1ClientV2.EnqueueInferenceAsync(
inputSource3,
new InferenceParameters(modelId: Environment.GetEnvironmentVariable("MindeeV2__Findoc__Model__Id")));
Assert.NotNull(response3);
Assert.True(response3.Job != null, "First V2 request should return a valid job");

var inputSource4 = new LocalInputSource(new FileInfo("Resources/file_types/pdf/blank_1.pdf"));
var inputSource4 = new LocalInputSource(new FileInfo(Constants.RootDir + "file_types/pdf/blank_1.pdf"));
var response4 = await instance1ClientV1.ParseAsync<InvoiceV4>(inputSource4);
Assert.NotNull(response4);
Assert.True(response4.Document != null, "Third V3 request should return a valid document");

MindeeClientV2 instance2ClientV2 = _services.GetRequiredService<MindeeClientV2>();
var inputSource5 = new LocalInputSource(new FileInfo("Resources/file_types/pdf/blank_1.pdf"));
var inputSource5 = new LocalInputSource(new FileInfo(Constants.RootDir + "file_types/pdf/blank_1.pdf"));
var response5 = await instance2ClientV2.EnqueueInferenceAsync(
inputSource5,
new InferenceParameters(modelId: Environment.GetEnvironmentVariable("MindeeV2__Findoc__Model__Id")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task GivenAPdf_ShouldExtractInvoicesStrict_MustSucceed()
{
var apiKey = Environment.GetEnvironmentVariable("Mindee__ApiKey");
var client = TestingUtilities.GetOrGenerateMindeeClient(apiKey);
var invoiceSplitterBytes = File.ReadAllBytes("Resources/v1/products/invoice_splitter/default_sample.pdf");
var invoiceSplitterBytes = File.ReadAllBytes(Constants.V1ProductDir + "invoice_splitter/default_sample.pdf");
var invoiceSplitterInputSource = new LocalInputSource(invoiceSplitterBytes, "default_sample.pdf");
var response = await client.EnqueueAndParseAsync<InvoiceSplitterV1>(invoiceSplitterInputSource);
InvoiceSplitterV1 inference = response.Document.Inference;
Expand All @@ -43,7 +43,7 @@ public async Task GivenAPdf_ShouldExtractInvoicesStrict_MustSucceed()
await client.ParseAsync<InvoiceV4>(extractedPdfsStrict[0].AsInputSource());

string testStringRstInvoice0 = PrepareInvoiceReturn(
"Resources/v1/products/invoices/response_v4/summary_full_invoice_p1.rst", invoice0.Document);
Constants.V1ProductDir + "invoices/response_v4/summary_full_invoice_p1.rst", invoice0.Document);

double ratio = TestingUtilities.LevenshteinRatio(testStringRstInvoice0, invoice0.Document.ToString());
Assert.True(ratio >= 0.90);
Expand Down
24 changes: 12 additions & 12 deletions tests/Mindee.IntegrationTests/V1/MindeeClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public MindeeClientTest()
[Fact]
public async Task Parse_File_Standard_MultiplePages_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/file_types/pdf/multipage_cut-2.pdf");
var inputSource = new LocalInputSource(Constants.RootDir + "file_types/pdf/multipage_cut-2.pdf");
var response = await _mindeeClient.ParseAsync<InvoiceV4>(inputSource);
Assert.NotNull(response);
Assert.Equal("success", response.ApiRequest.Status);
Expand All @@ -40,7 +40,7 @@ public async Task Parse_File_Standard_MultiplePages_MustSucceed()
[Fact]
public async Task Parse_File_Standard_SinglePage_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/file_types/receipt.jpg");
var inputSource = new LocalInputSource(Constants.RootDir + "file_types/receipt.jpg");
var response = await _mindeeClient.ParseAsync<ReceiptV5>(inputSource);
Assert.NotNull(response);
Assert.Equal("success", response.ApiRequest.Status);
Expand Down Expand Up @@ -80,7 +80,7 @@ await Assert.ThrowsAsync<Mindee400Exception>(
[Fact]
public async Task Parse_File_Cropper_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/file_types/receipt.jpg");
var inputSource = new LocalInputSource(Constants.RootDir + "file_types/receipt.jpg");
var predictOptions = new PredictOptions(cropper: true);
var response = await _mindeeClient.ParseAsync<ReceiptV5>(inputSource, predictOptions);
Assert.NotNull(response);
Expand All @@ -97,7 +97,7 @@ public async Task Parse_File_Cropper_MustSucceed()
[Fact]
public async Task Parse_File_Standard_AllWords_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/file_types/receipt.jpg");
var inputSource = new LocalInputSource(Constants.RootDir + "file_types/receipt.jpg");
var predictOptions = new PredictOptions(allWords: true);
var response = await _mindeeClient.ParseAsync<InvoiceV4>(inputSource, predictOptions);
Assert.NotNull(response);
Expand All @@ -115,7 +115,7 @@ public async Task Parse_File_Standard_AllWords_MustSucceed()
[Fact]
public async Task Parse_File_Standard_FullText_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/v1/products/international_id/default_sample.jpg");
var inputSource = new LocalInputSource(Constants.V1ProductDir + "international_id/default_sample.jpg");
var predictOptions = new PredictOptions(fullText: true);
var response = await _mindeeClient.EnqueueAndParseAsync<InternationalIdV2>(inputSource, predictOptions);
Assert.NotNull(response);
Expand All @@ -131,7 +131,7 @@ public async Task Parse_File_Standard_FullText_MustSucceed()
[Fact]
public async Task Parse_File_Standard_AllWords_And_Cropper_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/file_types/receipt.jpg");
var inputSource = new LocalInputSource(Constants.RootDir + "file_types/receipt.jpg");
var predictOptions = new PredictOptions(allWords: true, cropper: true);
var response = await _mindeeClient.ParseAsync<InvoiceV4>(
inputSource, predictOptions);
Expand All @@ -151,15 +151,15 @@ public async Task Parse_File_Standard_AllWords_And_Cropper_MustSucceed()
[Fact]
public async Task Enqueue_File_Standard_SyncOnly_Async_MustFail()
{
var inputSource = new LocalInputSource("Resources/v1/products/passport/default_sample.jpg");
var inputSource = new LocalInputSource(Constants.V1ProductDir + "passport/default_sample.jpg");
await Assert.ThrowsAsync<Mindee403Exception>(
() => _mindeeClient.EnqueueAsync<CropperV1>(inputSource));
}

[Fact]
public async Task Enqueue_File_Standard_AsyncOnly_Async_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/v1/products/invoice_splitter/default_sample.pdf");
var inputSource = new LocalInputSource(Constants.V1ProductDir + "invoice_splitter/default_sample.pdf");
var response = await _mindeeClient.EnqueueAsync<InvoiceSplitterV1>(inputSource);

Assert.NotNull(response);
Expand All @@ -178,15 +178,15 @@ public async Task Enqueue_File_Standard_AsyncOnly_Async_MustSucceed()
[Fact]
public async Task Enqueue_File_Standard_AsyncOnly_Sync_MustFail()
{
var inputSource = new LocalInputSource("Resources/v1/products/invoice_splitter/default_sample.pdf");
var inputSource = new LocalInputSource(Constants.V1ProductDir + "invoice_splitter/default_sample.pdf");
await Assert.ThrowsAsync<Mindee403Exception>(
() => _mindeeClient.ParseAsync<InvoiceSplitterV1>(inputSource));
}

[Fact]
public async Task EnqueueAndParse_File_Standard_AsyncOnly_Async_MustSucceed()
{
var inputSource = new LocalInputSource("Resources/v1/products/invoice_splitter/default_sample.pdf");
var inputSource = new LocalInputSource(Constants.V1ProductDir + "invoice_splitter/default_sample.pdf");
var pollingOptions = new AsyncPollingOptions();
var response = await _mindeeClient.EnqueueAndParseAsync<InvoiceSplitterV1>(
inputSource, pollingOptions: pollingOptions);
Expand Down Expand Up @@ -271,7 +271,7 @@ await Assert.ThrowsAsync<Mindee404Exception>(
public async Task Enqueue_File_Generated_AsyncOnly_Sync_MustFail()
{
var endpoint = new CustomEndpoint("international_id", "mindee", "2");
var inputSource = new LocalInputSource("Resources/v1/products/international_id/default_sample.jpg");
var inputSource = new LocalInputSource(Constants.V1ProductDir + "international_id/default_sample.jpg");
await Assert.ThrowsAsync<Mindee403Exception>(
() => _mindeeClient.ParseAsync<GeneratedV1>(inputSource, endpoint));
}
Expand All @@ -280,7 +280,7 @@ await Assert.ThrowsAsync<Mindee403Exception>(
public async Task EnqueueAndParse_File_Generated_AsyncOnly_Async_MustSucceed()
{
var endpoint = new CustomEndpoint("international_id", "mindee", "2");
var inputSource = new LocalInputSource("Resources/v1/products/international_id/default_sample.jpg");
var inputSource = new LocalInputSource(Constants.V1ProductDir + "international_id/default_sample.jpg");
var response = await _mindeeClient.EnqueueAndParseAsync<GeneratedV1>(inputSource, endpoint);

Assert.NotNull(response);
Expand Down
4 changes: 2 additions & 2 deletions tests/Mindee.IntegrationTests/V1/Workflow/WorkflowTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public WorkflowTest()
var apiKey1 = Environment.GetEnvironmentVariable("Mindee__ApiKey");
_client = TestingUtilities.GetOrGenerateMindeeClient(apiKey1);
_ragMatchInputSource = new LocalInputSource(
"Resources/v1/products/financial_document/default_sample.jpg");
Constants.V1ProductDir + "financial_document/default_sample.jpg");
_ragNoMatchInputSource = new LocalInputSource(
"Resources/v1/products/invoices/default_sample.jpg");
Constants.V1ProductDir + "invoices/default_sample.jpg");
_workflowId = Environment.GetEnvironmentVariable("Workflow__ID") ?? "";
}

Expand Down
8 changes: 4 additions & 4 deletions tests/Mindee.IntegrationTests/V2/MindeeClientV2Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public async Task Parse_File_Empty_MultiplePages_ParameterVariations_MustSucceed
bool rawText, bool polygon, bool confidence)
{
var inputSource = new LocalInputSource(
"Resources/file_types/pdf/multipage_cut-2.pdf");
Constants.RootDir + "file_types/pdf/multipage_cut-2.pdf");
var inferenceParams = new InferenceParameters(
modelId: _findocModelId,
rag: false,
Expand Down Expand Up @@ -107,7 +107,7 @@ public async Task Parse_File_Empty_MultiplePages_ParameterVariations_MustSucceed
public async Task Parse_File_Filled_SinglePage_MustSucceed()
{
var inputSource = new LocalInputSource(
"Resources/v1/products/financial_document/default_sample.jpg");
Constants.V1ProductDir + "financial_document/default_sample.jpg");
var inferenceParams = new InferenceParameters(
modelId: _findocModelId);

Expand Down Expand Up @@ -143,7 +143,7 @@ public async Task FailedWebhook_Retrieve_Job_MustSucceed()
{
string? webhookId = Environment.GetEnvironmentVariable("MindeeV2__Failure__Webhook__Id");

var inputSource = new LocalInputSource("Resources/file_types/pdf/multipage_cut-1.pdf");
var inputSource = new LocalInputSource(Constants.RootDir + "file_types/pdf/multipage_cut-1.pdf");
var inferenceParams = new InferenceParameters(
modelId: _findocModelId, webhookIds: new List<string?> { webhookId });

Expand Down Expand Up @@ -193,7 +193,7 @@ public async Task FailedWebhook_Retrieve_Job_MustSucceed()
[Fact]
public async Task Invalid_Model_MustThrowError()
{
var inputSource = new LocalInputSource("Resources/file_types/pdf/multipage_cut-2.pdf");
var inputSource = new LocalInputSource(Constants.RootDir + "file_types/pdf/multipage_cut-2.pdf");
var predictOptions = new InferenceParameters("INVALID MODEL ID");
var ex = await Assert.ThrowsAsync<MindeeHttpExceptionV2>(
() => _mindeeClientV2.EnqueueInferenceAsync(inputSource, predictOptions));
Expand Down
12 changes: 12 additions & 0 deletions tests/Mindee.UnitTests/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Mindee.UnitTests
{
public static class Constants
{
public const string RootDir = "Resources/";

public const string V1RootDir = RootDir + "v1/";
public const string V1ProductDir = V1RootDir + "products/";

public const string V2RootDir = RootDir + "v2/";
}
}
Loading
Loading