Skip to content
Merged
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
6 changes: 1 addition & 5 deletions src/v2/client/baseParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface BaseParametersConstructor {
}

/**
* Parameters accepted by the asynchronous **inference** v2 endpoint.
* Parameters accepted by all v2 products.
*
* All fields are optional except `modelId`.
*
Expand All @@ -22,10 +22,6 @@ export interface BaseParametersConstructor {
* rag: true,
* alias: "YOUR_ALIAS",
* webhookIds: ["YOUR_WEBHOOK_ID_1", "YOUR_WEBHOOK_ID_2"],
* pollingOptions: {
* initialDelaySec: 2,
* delaySec: 1.5,
* }
* };
*/
export abstract class BaseParameters {
Expand Down
5 changes: 4 additions & 1 deletion src/v2/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export { PollingOptions } from "./pollingOptions.js";
export type { PollingOptionsConstructor } from "./pollingOptions.js";
export type {
PollingOptionsConstructor,
TimerOptions,
} from "./pollingOptions.js";
export { BaseParameters } from "./baseParameters.js";
24 changes: 11 additions & 13 deletions src/v2/client/pollingOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ const minRetries = 2;
* Parameters for the internal polling loop in `enqueueAndGetInference()`.
*
* Default behavior:
* - `initialDelaySec` = 2s
* - `delaySec` = 1.5s
* - `initialDelaySec` = 2
* - `delaySec` = 1.5
* - `maxRetries` = 80
*
* Validation rules:
Expand All @@ -32,17 +32,21 @@ const minRetries = 2;
* - `maxRetries` >= 2
*
* The `initialTimerOptions` and `recurringTimerOptions` objects let you pass an
* `AbortSignal` or make the timer `unref`-ed to the `setTimeout()`.
* `AbortSignal` or make the timer `ref`-ed to the `setTimeout()`.
*
* @category ClientV2
* @example
* const params = {
* ```
* const pollingOptions = {
* initialDelaySec: 4,
* delaySec: 2,
* maxRetries: 50
* };
*
* const inference = await client.enqueueAndGetInference(inputDoc, params);
* const inference = await client.enqueueAndGetInference(
* inputDoc, params, pollingOptions
* );
* ```
*/
export class PollingOptions {
/** Number of seconds to wait *before the first poll*. */
Expand All @@ -52,15 +56,9 @@ export class PollingOptions {
/** Maximum number of polling attempts (including the first one). */
maxRetries: number;
/** Options passed to the initial `setTimeout()`. */
initialTimerOptions?: {
ref?: boolean,
signal?: AbortSignal
};
initialTimerOptions?: TimerOptions;
/** Options passed to every recurring `setTimeout()`. */
recurringTimerOptions?: {
ref?: boolean,
signal?: AbortSignal
};
recurringTimerOptions?: TimerOptions;

constructor(params?: PollingOptionsConstructor) {
if (!params) {
Expand Down
3 changes: 2 additions & 1 deletion src/v2/http/apiSettingsV2.ts → src/v2/http/apiSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const API_V2_KEY_ENVVAR_NAME: string = "MINDEE_V2_API_KEY";
const API_V2_HOST_ENVVAR_NAME: string = "MINDEE_V2_API_HOST";
const DEFAULT_MINDEE_API_HOST: string = "api-v2.mindee.net";

export class ApiSettingsV2 extends BaseSettings {
export class ApiSettings extends BaseSettings {
baseHeaders: Record<string, string>;

constructor({
Expand All @@ -25,6 +25,7 @@ export class ApiSettingsV2 extends BaseSettings {
"User-Agent": this.getUserAgent(),
Authorization: `${this.apiKey}`,
};
/* eslint-enable @typescript-eslint/naming-convention */
}

protected apiKeyFromEnv(): string {
Expand Down
3 changes: 3 additions & 0 deletions src/v2/http/errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ErrorDetails, ErrorItem, ErrorResponse } from "@/v2/parsing/index.js";
import { MindeeError } from "@/errors/index.js";

/**
* HTTP error returned by the API.
*/
export class MindeeHttpErrorV2 extends MindeeError implements ErrorDetails {
public status: number;
public detail: string;
Expand Down
15 changes: 10 additions & 5 deletions src/v2/http/mindeeApiV2.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApiSettingsV2 } from "./apiSettingsV2.js";
import { ApiSettings } from "./apiSettings.js";
import { Dispatcher } from "undici";
import { BaseParameters } from "@/v2/client/index.js";
import {
Expand All @@ -16,10 +16,10 @@ import { BaseProduct } from "@/v2/product/baseProduct.js";


export class MindeeApiV2 {
settings: ApiSettingsV2;
settings: ApiSettings;

constructor(dispatcher?: Dispatcher, apiKey?: string) {
this.settings = new ApiSettingsV2({ dispatcher: dispatcher, apiKey: apiKey });
this.settings = new ApiSettings({ dispatcher: dispatcher, apiKey: apiKey });
}

/**
Expand Down Expand Up @@ -80,7 +80,10 @@ export class MindeeApiV2 {
result: BaseHttpResponse,
responseClass: ResponseConstructor<T>,
): T {
if (result.messageObj?.statusCode && (result.messageObj?.statusCode > 399 || result.messageObj?.statusCode < 200)) {
if (
result.messageObj?.statusCode
&& (result.messageObj?.statusCode > 399 || result.messageObj?.statusCode < 200)
) {
if (result.data?.status !== null) {
throw new MindeeHttpErrorV2(new ErrorResponse(result.data));
}
Expand All @@ -98,7 +101,9 @@ export class MindeeApiV2 {
try {
return new responseClass(result.data);
} catch (e) {
logger.error(`Raised '${e}' Couldn't deserialize response object:\n${JSON.stringify(result.data)}`);
logger.error(
`Raised '${e}' Couldn't deserialize response object:\n${JSON.stringify(result.data)}`
);
throw new MindeeDeserializationError("Couldn't deserialize response object.");
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export {
ErrorResponse,
LocalResponse,
} from "./parsing/index.js";
export type { PollingOptions, BaseParameters } from "./client/index.js";
export type { BaseParameters, TimerOptions } from "./client/index.js";
export { PollingOptions } from "./client/index.js";
8 changes: 7 additions & 1 deletion src/v2/parsing/inference/baseInference.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { StringDict } from "@/parsing/index.js";
import { InferenceModel } from "./inferenceModel.js";
import { InferenceFile } from "./inferenceFile.js";
import { StringDict } from "@/parsing/index.js";
import { InferenceJob } from "./inferenceJob.js";

export abstract class BaseInference {
/**
* Model info for the inference.
*/
public model: InferenceModel;
/**
* Job the inference belongs to.
*/
public job: InferenceJob;
/**
* File info for the inference.
*/
Expand All @@ -18,6 +23,7 @@ export abstract class BaseInference {

protected constructor(serverResponse: StringDict) {
this.id = serverResponse["id"];
this.job = new InferenceJob(serverResponse["job"]);
this.model = new InferenceModel(serverResponse["model"]);
this.file = new InferenceFile(serverResponse["file"]);
}
Expand Down
20 changes: 20 additions & 0 deletions src/v2/parsing/inference/inferenceJob.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { StringDict } from "@/parsing/stringDict.js";

export class InferenceJob {
/**
* UUID of the Job.
*/
public id: string;

constructor(serverResponse: StringDict) {
this.id = serverResponse["id"];
}

toString () {
return(
"Job\n" +
"===\n" +
`:ID: ${this.id}\n`
);
}
}
5 changes: 5 additions & 0 deletions src/v2/product/baseProduct.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { BaseParameters } from "@/v2/client/index.js";
import { ResponseConstructor } from "@/v2/parsing/index.js";

/**
* Base class for all V2 product definitions.
*
* Child classes are passed to the Client when making requests.
*/
export abstract class BaseProduct {
static get parametersClass(): new (...args: any[]) => BaseParameters {
throw new Error("Must define static parameters property");
Expand Down
3 changes: 3 additions & 0 deletions src/v2/product/classification/classification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { ClassificationResponse } from "./classificationResponse.js";
import { ClassificationParameters } from "./params/index.js";
import { BaseProduct } from "@/v2/product/baseProduct.js";

/**
* Automatically sort any image or scanned document into categories.
*/
export class Classification extends BaseProduct {
static get parametersClass() {
return ClassificationParameters;
Expand Down
3 changes: 3 additions & 0 deletions src/v2/product/crop/crop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { CropResponse } from "./cropResponse.js";
import { CropParameters } from "./params/index.js";
import { BaseProduct } from "@/v2/product/baseProduct.js";

/**
* Identify the borders of documents on each page, matching each one to a category.
*/
export class Crop extends BaseProduct {
static get parametersClass() {
return CropParameters;
Expand Down
3 changes: 3 additions & 0 deletions src/v2/product/extraction/extraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { ExtractionResponse } from "./extractionResponse.js";
import { ExtractionParameters } from "./params/index.js";
import { BaseProduct } from "@/v2/product/baseProduct.js";

/**
* Automatically extract structured data from any image or scanned document.
*/
export class Extraction extends BaseProduct {
static get parametersClass() {
return ExtractionParameters;
Expand Down
3 changes: 3 additions & 0 deletions src/v2/product/ocr/ocr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { OcrResponse } from "./ocrResponse.js";
import { OcrParameters } from "./params/index.js";
import { BaseProduct } from "@/v2/product/baseProduct.js";

/**
* Extract raw text (OCR) from any image or scanned document.
*/
export class Ocr extends BaseProduct {
static get parametersClass() {
return OcrParameters;
Expand Down
3 changes: 3 additions & 0 deletions src/v2/product/split/split.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { SplitResponse } from "./splitResponse.js";
import { SplitParameters } from "./params/index.js";
import { BaseProduct } from "@/v2/product/baseProduct.js";

/**
* Break a multipage source file into separate documents, associating a class for each one.
*/
export class Split extends BaseProduct {
static get parametersClass() {
return SplitParameters;
Expand Down
7 changes: 6 additions & 1 deletion tests/v2/product/classification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ describe("MindeeV2 - Classification Response", async () => {
ClassificationResponse,
path.join(V2_PRODUCT_PATH, "classification", "classification_single.json")
);
const classification = response.inference.result.classification;
const inference = response.inference;

const model = inference.model;
assert.notStrictEqual(model, undefined);

const classification = inference.result.classification;
assert.strictEqual(classification.documentType, "invoice");
});
});
33 changes: 21 additions & 12 deletions tests/v2/product/crop.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,21 @@ describe("MindeeV2 - Crop Response", async () => {
crop.CropResponse,
path.join(V2_PRODUCT_PATH, "crop", "crop_single.json")
);
const inference = response.inference;

// Validate inference metadata
assert.strictEqual(response.inference.id, "12345678-1234-1234-1234-123456789abc");
assert.strictEqual(response.inference.model.id, "test-model-id");
assert.strictEqual(inference.id, "12345678-1234-1234-1234-123456789abc");
assert.strictEqual(inference.model.id, "test-model-id");

assert.strictEqual(inference.job.id, "12345678-1234-1234-1234-jobid1234567");

// Validate file metadata
assert.strictEqual(response.inference.file.name, "sample.jpeg");
assert.strictEqual(response.inference.file.pageCount, 1);
assert.strictEqual(response.inference.file.mimeType, "image/jpeg");
assert.strictEqual(inference.file.name, "sample.jpeg");
assert.strictEqual(inference.file.pageCount, 1);
assert.strictEqual(inference.file.mimeType, "image/jpeg");

// Validate crops
const crops: crop.CropItem[] = response.inference.result.crops;
const crops: crop.CropItem[] = inference.result.crops;
assert.ok(Array.isArray(crops));
assert.strictEqual(crops.length, 1);

Expand All @@ -49,16 +53,21 @@ describe("MindeeV2 - Crop Response", async () => {
crop.CropResponse,
path.join(V2_PRODUCT_PATH, "crop", "crop_multiple.json")
);
const inference = response.inference;

const job = inference.job;
assert.strictEqual(job.id, "12345678-1234-1234-1234-jobid1234567");

// Validate inference metadata
assert.strictEqual(response.inference.id, "12345678-1234-1234-1234-123456789abc");
assert.strictEqual(response.inference.model.id, "test-model-id");
assert.strictEqual(inference.id, "12345678-1234-1234-1234-123456789abc");
assert.strictEqual(inference.model.id, "test-model-id");

// Validate file metadata
assert.strictEqual(response.inference.file.name, "default_sample.jpg");
assert.strictEqual(response.inference.file.pageCount, 1);
assert.strictEqual(response.inference.file.mimeType, "image/jpeg");
assert.strictEqual(inference.file.name, "default_sample.jpg");
assert.strictEqual(inference.file.pageCount, 1);
assert.strictEqual(inference.file.mimeType, "image/jpeg");

const crops: crop.CropItem[] = response.inference.result.crops;
const crops: crop.CropItem[] = inference.result.crops;
assert.ok(Array.isArray(crops));
assert.strictEqual(crops.length, 2);

Expand Down
7 changes: 7 additions & 0 deletions tests/v2/product/extraction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ describe("MindeeV2 - Extraction Response", async () => {
assert.notStrictEqual(inference, undefined);
assert.strictEqual(inference.model.id, "12345678-1234-1234-1234-123456789abc");

const job = inference.job;
assert.strictEqual(job.id, "12345678-1234-1234-1234-jobid1234567");

const model = inference.model;
assert.notStrictEqual(model, undefined);
assert.strictEqual(model.id, "12345678-1234-1234-1234-123456789abc");
Expand Down Expand Up @@ -169,6 +172,10 @@ describe("MindeeV2 - Extraction Response", async () => {
const response = await loadV2Response(
ExtractionResponse, standardFieldPath
);

const job = response.inference.job;
assert.strictEqual(job.id, "12345678-1234-1234-1234-jobid1234567");

const fields = response.inference.result.fields;

assert.ok(fields.get("field_simple_string") instanceof SimpleField);
Expand Down
Loading