Skip to content

Commit

Permalink
[ai-form-recognizer] 5.0.0 changes (Azure#26711)
Browse files Browse the repository at this point in the history
This PR makes several changes related to the impending 5.0.0 release of
Document Intelligence (f.k.a. Form Recognizer).

- The major version revision signals a breaking change in which
key-value pairs and extracted languages will not be returned unless a
special `feature` is provided when making the analysis request.
- Support for explicit API version was removed. This functionality never
worked very well in TypeScript, and the major version revision gives us
an opportunity to remove it and avoid its inherent complexity until a
better solution is available.

This also addresses some issues with the way that training data content
sources were represented and named. The new representation is stricter
about providing only one of the two possible source type fields:
`azureBlobSource` or `azureBlobFileListSource`.

---------

Co-authored-by: Will Temple <[email protected]>
  • Loading branch information
witemple-msft and willmtemple authored Aug 7, 2023
1 parent 1177c61 commit adf8bd0
Show file tree
Hide file tree
Showing 21 changed files with 201 additions and 311 deletions.
24 changes: 18 additions & 6 deletions sdk/formrecognizer/ai-form-recognizer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
# Release History

## 4.1.0 (Unreleased)
## 5.0.0 (2023-08-08)

### Features Added

- `AnalyzeDocumentOptions.features` allows three new features compared to the last beta version:
- Updated the SDK to use the latest Generally Available (GA) version of the Form Recognizer REST API: `2023-07-31`.
- `AnalyzeDocumentOptions.features` accepts three new features compared to the last beta version:
- `barcodes`: enables the detection of barcodes in the document.
- `keyValuePairs`: enable the detection of general key value pairs (form fields) in the document.
- `languages`: enables the detection of the text content language.
- `beginBuildDocumentModel` has a new overload that accepts a `DocumentModelContentSource` in place of a raw `containerUrl`. This allows training document models using the new Azure Blob file list source (that is already supported by document classifiers). The `DocumentModelContentSource` is an object that contains a `containerUrl` property, and if a `fileList` property is also provided it is interpreted as an Azure Blob file list source. Otherwise it is interpreted as an Azure Blob content source with an optional `prefix` property.
- `beginBuildDocumentModel` has a new overload that accepts a `DocumentModelSource` in place of a raw `containerUrl`. This allows training document models using the new Blob File List source (that is already supported by document classifiers). Like with classifiers, the source inputs are specified as an object containing an `azureFileListSource` property or an `azureBlobSource` property containing the respective details of each source type.

### Breaking Changes

- `DocumentAnalysisClient` and `DocumentModelAdministrationClient` now target service API version `2023-07-31` by default. Version `2023-02-28-preview` is not supported.
From the last stable release (4.0.0):

- Support for passing alternative API versions has been removed from the client. In practice, the client only supported
using a single API version, but types and options for specifying an API version were provided. In version 5.0.0, these options and their associated types were removed:
- The `apiVersion` option that was previously accepted by the `DocumentAnalysisClient` and `DocumentModelAdministrationClient` constructors was removed. This option previously only had one valid value in version 4.0.0, and supporting multiple API versions in a single package weakens the type constraints, so we have chosen to only support the latest Generally Available version of the service in this SDK package. Support for multiple API versions may be reintroduced in a future version.
- The `FormRecognizerApiVersion` type and enum were removed as they no longer serve any purpose.
- The type of `apiVersion` properties of result objects was changed from `FormRecognizerApiVersion` to `string`. This type is more accurate, as these fields reflect the API version used to create the model or start the analysis operation, and not necessarily an API version that the client instance is aware of.
- The `FormRecognizerCommonClientOptions` interface, which both `DocumentAnalysisClientOptions` and `DocumentModelAdministrationClientOptions` inherited from was removed, as it only carried the `apiVersion` option that no longer exists.
- The `languages` and `keyValuePairs` properties of `AnalyzeResult` that were previously returned when using the `prebuilt-document` model are no longer returned unless the corresponding `features` are specified when making the analysis request.

From the last beta release (4.1.0-beta.1):

- `AnalyzeDocumentOptions.features` changed the following feature names:
- `ocr.highResolution` renamed to `ocrHighResolution`.
- `ocr.formula` renamed to `formulas`.
- `ocr.font` renamed to `styleFont`.
- The following fields have been removed
- The following fields have been removed:
- `AnalyzeDocumentOptions.queryFields`
- `DocumentPage.kind` and `DocumentPage.images` (`DocumentPageKind` and `DocumentImage` types have been removed too.)
- `DocumentKeyValuePair.commonName`
- Changed how content sources are provided when creating document classifiers. The type of content source (`azureBlobContentSource` or `azureBlobFileListSource`) is no longer required in the content source input, and the type is now inferred automatically. If a `fileList` property is provided, it is interpreted as a file list source, and otherwise it is interpreted as a blob content source with optional `prefix`.
- The type of the `docTypes` parameter of `beginBuildDocumentClassifier` was refined slightly. The type will no longer accept _both_ `azureBlobSource` and `azureFileListSource`

## 4.1.0-beta.1 (2023-04-11)

Expand Down
2 changes: 1 addition & 1 deletion sdk/formrecognizer/ai-form-recognizer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"sdk-type": "client",
"author": "Microsoft Corporation",
"description": "An isomorphic client library for the Azure Form Recognizer service.",
"version": "4.1.0",
"version": "5.0.0",
"keywords": [
"node",
"azure",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export interface AnalyzedDocument {

// @public
export interface AnalyzeDocumentOptions<Result = AnalyzeResult<AnalyzedDocument>> extends OperationOptions, PollerOptions<DocumentAnalysisPollOperationState<Result>> {
features?: string[];
features?: FormRecognizerFeature[];
locale?: string;
pages?: string;
}
Expand All @@ -67,7 +67,7 @@ export interface AnalyzeResult<Document = AnalyzedDocument> extends AnalyzeResul

// @public
export interface AnalyzeResultCommon {
apiVersion: FormRecognizerApiVersion;
apiVersion: string;
content: string;
modelId: string;
}
Expand All @@ -76,17 +76,29 @@ export interface AnalyzeResultCommon {
export type AnalyzeResultOperationStatus = "notStarted" | "running" | "failed" | "succeeded";

// @public
export interface AzureBlobContentSource {
containerUrl: string;
prefix?: string;
export interface AzureBlobFileListSource {
azureBlobFileListSource: AzureBlobFileListSourceDetails;
azureBlobSource?: undefined;
}

// @public
export interface AzureBlobFileListContentSource {
export interface AzureBlobFileListSourceDetails {
containerUrl: string;
fileList: string;
}

// @public
export interface AzureBlobSource {
azureBlobFileListSource?: undefined;
azureBlobSource: AzureBlobSourceDetails;
}

// @public
export interface AzureBlobSourceDetails {
containerUrl: string;
prefix?: string;
}

export { AzureKeyCredential }

// @public
Expand All @@ -113,8 +125,8 @@ export interface BoundingRegion extends HasBoundingPolygon {

// @public
export interface ClassifierDocumentTypeDetails {
azureBlobFileListSource?: AzureBlobFileListContentSource;
azureBlobSource?: AzureBlobContentSource;
azureBlobFileListSource?: AzureBlobFileListSourceDetails;
azureBlobSource?: AzureBlobSourceDetails;
}

// @public
Expand Down Expand Up @@ -181,7 +193,7 @@ export class DocumentAnalysisClient {
}

// @public
export interface DocumentAnalysisClientOptions extends FormRecognizerCommonClientOptions {
export interface DocumentAnalysisClientOptions extends CommonClientOptions {
stringIndexType?: StringIndexType;
}

Expand Down Expand Up @@ -237,9 +249,6 @@ export interface DocumentClassifierBuildOperationDetails extends OperationDetail
result?: DocumentClassifierDetails;
}

// @public
export type DocumentClassifierContentSource = AzureBlobContentSource | AzureBlobFileListContentSource;

// @public
export interface DocumentClassifierDetails {
apiVersion: string;
Expand All @@ -252,13 +261,21 @@ export interface DocumentClassifierDetails {
expiresOn?: Date;
}

// @public
export interface DocumentClassifierDocumentTypeSources {
[docType: string]: DocumentClassifierSource;
}

// @public
export interface DocumentClassifierOperationState extends PollOperationState<DocumentClassifierDetails>, ModelAdministrationOperationStateCommon {
}

// @public
export type DocumentClassifierPoller = PollerLike<DocumentClassifierOperationState, DocumentClassifierDetails>;

// @public
export type DocumentClassifierSource = AzureBlobSource | AzureBlobFileListSource;

// @public
export interface DocumentCountryRegionField extends DocumentFieldCommon {
kind: "countryRegion";
Expand Down Expand Up @@ -354,7 +371,7 @@ export interface DocumentLine extends HasBoundingPolygon {

// @public
export interface DocumentModel<Result> {
apiVersion?: FormRecognizerApiVersion;
apiVersion?: string;
modelId: string;
transformResult: (input: AnalyzeResult) => Result;
}
Expand All @@ -364,11 +381,9 @@ export class DocumentModelAdministrationClient {
constructor(endpoint: string, credential: TokenCredential, options?: DocumentModelAdministrationClientOptions);
constructor(endpoint: string, credential: KeyCredential, options?: DocumentModelAdministrationClientOptions);
constructor(endpoint: string, credential: KeyCredential | TokenCredential, options?: DocumentModelAdministrationClientOptions);
beginBuildDocumentClassifier(classifierId: string, docTypes: {
[docType: string]: DocumentClassifierContentSource;
}, options?: BeginBuildDocumentClassifierOptions): Promise<DocumentClassifierPoller>;
beginBuildDocumentClassifier(classifierId: string, docTypeSources: DocumentClassifierDocumentTypeSources, options?: BeginBuildDocumentClassifierOptions): Promise<DocumentClassifierPoller>;
beginBuildDocumentModel(modelId: string, containerUrl: string, buildMode: DocumentModelBuildMode, options?: BeginBuildDocumentModelOptions): Promise<DocumentModelPoller>;
beginBuildDocumentModel(modelId: string, contentSource: DocumentModelContentSource, buildMode: DocumentModelBuildMode, options?: BeginBuildDocumentModelOptions): Promise<DocumentModelPoller>;
beginBuildDocumentModel(modelId: string, contentSource: DocumentModelSource, buildMode: DocumentModelBuildMode, options?: BeginBuildDocumentModelOptions): Promise<DocumentModelPoller>;
beginComposeDocumentModel(modelId: string, componentModelIds: Iterable<string>, options?: BeginComposeDocumentModelOptions): Promise<DocumentModelPoller>;
beginCopyModelTo(sourceModelId: string, authorization: CopyAuthorization, options?: BeginCopyModelOptions): Promise<DocumentModelPoller>;
deleteDocumentClassifier(classifierId: string, options?: OperationOptions): Promise<void>;
Expand All @@ -384,7 +399,7 @@ export class DocumentModelAdministrationClient {
}

// @public
export interface DocumentModelAdministrationClientOptions extends FormRecognizerCommonClientOptions {
export interface DocumentModelAdministrationClientOptions extends CommonClientOptions {
}

// @public
Expand All @@ -408,9 +423,6 @@ export interface DocumentModelComposeOperationDetails extends OperationDetails {
result?: DocumentModelDetails;
}

// @public
export type DocumentModelContentSource = AzureBlobContentSource | AzureBlobFileListContentSource;

// @public
export interface DocumentModelCopyToOperationDetails extends OperationDetails {
kind: "documentModelCopyTo";
Expand Down Expand Up @@ -439,6 +451,9 @@ export interface DocumentModelOperationState extends PollOperationState<Document
// @public
export type DocumentModelPoller = PollerLike<DocumentModelOperationState, DocumentModelDetails>;

// @public
export type DocumentModelSource = AzureBlobSource | AzureBlobFileListSource;

// @public
export interface DocumentModelSummary {
apiVersion?: string;
Expand Down Expand Up @@ -607,25 +622,10 @@ export type FontStyle = string;
// @public
export type FontWeight = string;

// @public
export type FormRecognizerApiVersion = (typeof FormRecognizerApiVersion)[keyof typeof FormRecognizerApiVersion];

// @public
export const FormRecognizerApiVersion: {
readonly Latest: "2023-07-31";
readonly Stable: "2023-07-31";
readonly "2022-08-31": "2022-08-31";
};

// @public
export interface FormRecognizerCommonClientOptions extends CommonClientOptions {
apiVersion?: FormRecognizerApiVersion;
}

// @public
export type FormRecognizerFeature = (typeof FormRecognizerFeature)[keyof typeof FormRecognizerFeature] | (string & {});

// @public (undocumented)
// @public
export const FormRecognizerFeature: {
readonly Fonts: "styleFont";
readonly OcrHighResolution: "ocrHighResolution";
Expand Down Expand Up @@ -813,7 +813,7 @@ export interface OperationDetails {
};
}

// @public (undocumented)
// @public
export type OperationDetailsUnion = OperationDetails | DocumentModelBuildOperationDetails | DocumentModelComposeOperationDetails | DocumentModelCopyToOperationDetails | DocumentClassifierBuildOperationDetails;

// @public
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ async function main() {
type1: {
// `azureBlobSource` isn't the only way to provide training data to the service. For more information, see
// the documentation of the `ClassifierDocumentTypeDetails` type.
containerUrl: trainingDataSasUrl1,
azureBlobSource: {
containerUrl: trainingDataSasUrl1,
},
},
type2: {
containerUrl: trainingDataSasUrl2,
azureBlobSource: {
containerUrl: trainingDataSasUrl2,
},
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ async function main() {

const poller = await client.beginBuildDocumentModel(
modelId,
trainingDataSasUrl,
{
azureBlobSource: {
containerUrl: trainingDataSasUrl,
},
},
DocumentModelBuildMode.Template
);
const model = await poller.pollUntilDone();
Expand Down
4 changes: 3 additions & 1 deletion sdk/formrecognizer/ai-form-recognizer/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ export const DEFAULT_COGNITIVE_SCOPE = "https://cognitiveservices.azure.com/.def
/**
* @internal
*/
export const SDK_VERSION = "4.1.0";
export const SDK_VERSION = "5.0.0";

export const FORM_RECOGNIZER_API_VERSION = "2023-07-31";
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { KeyCredential, TokenCredential } from "@azure/core-auth";
import { createTracingClient } from "@azure/core-tracing";
import { TracingClient } from "@azure/core-tracing";
import { SDK_VERSION } from "./constants";
import { FORM_RECOGNIZER_API_VERSION, SDK_VERSION } from "./constants";
import {
AnalyzeDocumentRequest,
AnalyzeResultOperation,
Expand All @@ -23,11 +23,7 @@ import {
} from "./lro/analysis";
import { OperationContext, lro } from "./lro/util/poller";
import { AnalyzeDocumentOptions } from "./options/AnalyzeDocumentOptions";
import {
DEFAULT_GENERATED_CLIENT_OPTIONS,
DocumentAnalysisClientOptions,
FormRecognizerApiVersion,
} from "./options/FormRecognizerClientOptions";
import { DocumentAnalysisClientOptions } from "./options/FormRecognizerClientOptions";
import { DocumentModel } from "./documentModel";
import { makeServiceClient, Mappers, SERIALIZER } from "./util";
import { AbortSignalLike } from "@azure/abort-controller";
Expand Down Expand Up @@ -66,7 +62,6 @@ import { ClassifyDocumentOptions } from "./options/ClassifyDocumentOptions";
export class DocumentAnalysisClient {
private _restClient: GeneratedClient;
private _tracing: TracingClient;
private _apiVersion: FormRecognizerApiVersion;

/**
* Create a `DocumentAnalysisClient` instance from a resource endpoint and a an Azure Identity `TokenCredential`.
Expand Down Expand Up @@ -137,8 +132,6 @@ export class DocumentAnalysisClient {
packageVersion: SDK_VERSION,
namespace: "Microsoft.CognitiveServices",
});

this._apiVersion = options.apiVersion ?? DEFAULT_GENERATED_CLIENT_OPTIONS.apiVersion;
}

// #region Analysis
Expand Down Expand Up @@ -418,12 +411,13 @@ export class DocumentAnalysisClient {
? { modelId: model, apiVersion: undefined, transformResult: (v: AnalyzeResult) => v }
: model;

if (requestApiVersion && requestApiVersion !== this._apiVersion) {
if (requestApiVersion && requestApiVersion !== FORM_RECOGNIZER_API_VERSION) {
throw new Error(
[
`API Version mismatch: the provided model wants version: ${requestApiVersion}, but the client is using ${this._apiVersion}.`,
`API Version mismatch: the provided model wants version: ${requestApiVersion},`,
`but the client is using ${FORM_RECOGNIZER_API_VERSION}.`,
"The API version of the model must match the client's API version.",
].join("\n")
].join(" ")
);
}

Expand Down
5 changes: 2 additions & 3 deletions sdk/formrecognizer/ai-form-recognizer/src/documentModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import { DocumentFieldSchema, DocumentModelDetails } from "./generated";
import { AnalyzedDocument, AnalyzeResult } from "./lro/analysis";
import { DocumentField } from "./models/fields";
import { FormRecognizerApiVersion } from "./options";
import { isAcronymic, uncapitalize } from "./util";

/**
Expand All @@ -21,7 +20,7 @@ export interface DocumentModel<Result> {
/**
* The API version of the model.
*/
apiVersion?: FormRecognizerApiVersion;
apiVersion?: string;
/**
* An associated transformation that is used to conver the base (weak) Result type to the strong version.
*/
Expand Down Expand Up @@ -94,7 +93,7 @@ export function createModelFromSchema(
): DocumentModel<AnalyzeResult<unknown>> {
return {
modelId: schema.modelId,
apiVersion: schema.apiVersion as FormRecognizerApiVersion,
apiVersion: schema.apiVersion,
transformResult(baseResult: AnalyzeResult): AnalyzeResult<unknown> {
const hasDocuments = Object.entries(schema.docTypes ?? {}).length > 0;

Expand Down
Loading

0 comments on commit adf8bd0

Please sign in to comment.