Skip to content

Commit 118feb8

Browse files
[ai-form-recognizer] Fix samples for release (Azure#20323)
* [ai-form-recognizer] Rename some items in readme and doc samples * Remove errant v4 samples (v4 is not stable) * Updated samples to work with min-node 12 * Fix dead link * Updated remaining imports to requires
1 parent 4bfe405 commit 118feb8

File tree

102 files changed

+903
-2356
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+903
-2356
lines changed

sdk/formrecognizer/ai-form-recognizer/MIGRATION-v3_v4.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ The previous `FormRecognizerClient` class and new `DocumentAnalysisClient` class
263263
- `beginRecognizeInvoices` and `beginRecognizeInvoicesFromUrl`
264264
- `beginRecognizeIdentityDocuments` and `beginRecognizeIdentityDocumentsFromUrl`
265265
- `beginExtractLayout`, which replaces `beginRecognizeContent` and `beginRecognizeContentFromUrl`
266-
- `beginExtractGenericDocument`, which is new, and provides similar functionality to unlabeled custom models from the previous SDK without the need to train a model. Please refer to [the `extractGenericDocument` sample for an example of using this new method](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/formrecognizer/ai-form-recognizer/samples/v4-beta/typescript/src/extractGenericDocument.ts), as it is not quite the same as using an unlabeled custom model.
266+
- `beginExtractGenericDocument`, which is new, and provides similar functionality to unlabeled custom models from the previous SDK without the need to train a model. Please refer to [the `extractGenericDocument` sample for an example of using this new method](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/formrecognizer/ai-form-recognizer/samples/v4-beta/typescript/src/extractGeneralDocument.ts), as it is not quite the same as using an unlabeled custom model.
267267

268268
All of these methods produce `AnalyzeResult`, `LayoutResult`, and `GenericDocumentResult` types respectively. Please see the section above about these types for more information.
269269

sdk/formrecognizer/ai-form-recognizer/README.md

Lines changed: 43 additions & 36 deletions
Large diffs are not rendered by default.

sdk/formrecognizer/ai-form-recognizer/samples-dev/analyzeBusinessCard.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import * as dotenv from "dotenv";
2323
dotenv.config();
2424

2525
async function main() {
26-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
27-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
26+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
27+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
2828

2929
const client = new DocumentAnalysisClient(endpoint, credential);
3030

@@ -45,14 +45,21 @@ async function main() {
4545

4646
// There are more fields than just these few, and the model allows for multiple contact & company names as well as
4747
// phone numbers, though we'll only show the first extracted values here.
48-
const [name] = businessCard.contactNames?.values ?? [];
49-
console.log("Name:", name?.properties.firstName?.value, name?.properties.lastName?.value);
48+
const name = businessCard.contactNames && businessCard.contactNames.values[0];
49+
if (name) {
50+
const { firstName, lastName } = name.properties;
51+
console.log("Name:", firstName && firstName.value, lastName && lastName.value);
52+
}
5053

51-
const [company] = businessCard.companyNames?.values ?? [];
52-
console.log("Company:", company?.value);
54+
const company = businessCard.companyNames && businessCard.companyNames.values[0];
55+
if (company) {
56+
console.log("Company:", company.value);
57+
}
5358

54-
const [address] = businessCard.addresses?.values ?? [];
55-
console.log("Address:", address?.value);
59+
const address = businessCard.addresses && businessCard.addresses.values[0];
60+
if (address) {
61+
console.log("Address:", address.value);
62+
}
5663
} else {
5764
throw new Error("Expected at least one business card in the result.");
5865
}

sdk/formrecognizer/ai-form-recognizer/samples-dev/analyzeDocumentByModelId.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import * as dotenv from "dotenv";
1414
dotenv.config();
1515

1616
async function main() {
17-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
18-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
17+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
18+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
1919
const client = new DocumentAnalysisClient(endpoint, credential);
2020

21-
const modelId = process.env.FORM_RECOGNIZER_CUSTOM_MODEL_ID ?? "<custom model ID>";
21+
const modelId = process.env.FORM_RECOGNIZER_CUSTOM_MODEL_ID || "<custom model ID>";
2222

2323
const poller = await client.beginAnalyzeDocument(
2424
modelId,
@@ -36,7 +36,7 @@ async function main() {
3636
console.log(
3737
"Extracted document:",
3838
document.docType,
39-
`(confidence: ${document.confidence ?? "<undefined>"})`
39+
`(confidence: ${document.confidence || "<undefined>"})`
4040
);
4141
console.log("Fields:", document.fields);
4242
}

sdk/formrecognizer/ai-form-recognizer/samples-dev/analyzeIdentityDocument.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import * as dotenv from "dotenv";
2323
dotenv.config();
2424

2525
async function main() {
26-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
27-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
26+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
27+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
2828

2929
const client = new DocumentAnalysisClient(endpoint, credential);
3030

@@ -43,26 +43,37 @@ async function main() {
4343
// The identity document model has multiple document types, so we need to know which document type was actually
4444
// extracted.
4545
if (result.docType === "idDocument.driverLicense") {
46-
const driverLicense = result.fields;
46+
const { firstName, lastName, documentNumber, dateOfBirth, dateOfExpiration } = result.fields;
4747

4848
// For the sake of the example, we'll only show a few of the fields that are produced.
4949
console.log("Extracted a Driver License:");
50-
console.log(" Name:", driverLicense.firstName?.value, driverLicense.lastName?.value);
51-
console.log(" License No.:", driverLicense.documentNumber?.value);
52-
console.log(" Date of Birth:", driverLicense.dateOfBirth?.value);
53-
console.log(" Expiration:", driverLicense.documentNumber?.value);
50+
console.log(" Name:", firstName && firstName.value, lastName && lastName.value);
51+
console.log(" License No.:", documentNumber && documentNumber.value);
52+
console.log(" Date of Birth:", dateOfBirth && dateOfBirth.value);
53+
console.log(" Expiration:", dateOfExpiration && dateOfExpiration.value);
5454
} else if (result.docType === "idDocument.passport") {
55-
const passport = result.fields;
56-
5755
// The passport document type extracts and parses the Passport's machine-readable zone
58-
const fields = passport.machineReadableZone?.properties;
56+
if (!result.fields.machineReadableZone) {
57+
throw new Error("No Machine Readable Zone extracted from passport.");
58+
}
59+
60+
const {
61+
firstName,
62+
lastName,
63+
dateOfBirth,
64+
nationality,
65+
documentNumber,
66+
countryRegion,
67+
dateOfExpiration,
68+
} = result.fields.machineReadableZone.properties;
69+
5970
console.log("Extracted a Passport:");
60-
console.log(" Name:", fields?.firstName?.value, fields?.lastName?.value);
61-
console.log(" Date of Birth:", fields?.dateOfBirth?.value);
62-
console.log(" Nationality:", fields?.nationality?.value);
63-
console.log(" Passport No.:", fields?.documentNumber?.value);
64-
console.log(" Issuer:", fields?.countryRegion?.value);
65-
console.log(" Expiration Date:", fields?.dateOfExpiration?.value);
71+
console.log(" Name:", firstName && firstName.value, lastName && lastName.value);
72+
console.log(" Date of Birth:", dateOfBirth && dateOfBirth.value);
73+
console.log(" Nationality:", nationality && nationality.value);
74+
console.log(" Passport No.:", documentNumber && documentNumber.value);
75+
console.log(" Issuer:", countryRegion && countryRegion.value);
76+
console.log(" Expiration Date:", dateOfExpiration && dateOfExpiration.value);
6677
} else {
6778
// The only reason this would happen is if the client library's schema for the prebuilt identity document model is
6879
// out of date, and a new document type has been introduced.

sdk/formrecognizer/ai-form-recognizer/samples-dev/analyzeInvoice.ts

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import * as dotenv from "dotenv";
2222
dotenv.config();
2323

2424
async function main() {
25-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
26-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
25+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
26+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
2727

2828
const client = new DocumentAnalysisClient(endpoint, credential);
2929

@@ -39,30 +39,43 @@ async function main() {
3939

4040
// Use of PrebuiltModels.Receipt above (rather than the raw model ID), adds strong typing of the model's output
4141
if (result) {
42-
const invoice = result.fields;
42+
const {
43+
vendorName,
44+
customerName,
45+
invoiceDate,
46+
dueDate,
47+
items,
48+
subTotal,
49+
previousUnpaidBalance,
50+
totalTax,
51+
amountDue,
52+
} = result.fields;
4353

4454
// The invoice model has many fields, and we will only show some of them for the sake of the example
45-
console.log("Vendor Name:", invoice.vendorName?.value);
46-
console.log("Customer Name:", invoice.customerName?.value);
47-
console.log("Invoice Date:", invoice.invoiceDate?.value);
48-
console.log("Due Date:", invoice.dueDate?.value);
55+
console.log("Vendor Name:", vendorName && vendorName.value);
56+
console.log("Customer Name:", customerName && customerName.value);
57+
console.log("Invoice Date:", invoiceDate && invoiceDate.value);
58+
console.log("Due Date:", dueDate && dueDate.value);
4959

5060
console.log("Items:");
51-
for (const { properties: item } of invoice.items?.values ?? []) {
52-
console.log("-", item.productCode?.value ?? "<no product code>");
53-
console.log(" Description:", item.description?.value);
54-
console.log(" Quantity:", item.quantity?.value);
55-
console.log(" Date:", item.date?.value);
56-
console.log(" Unit:", item.unit?.value);
57-
console.log(" Unit Price:", item.unitPrice?.value);
58-
console.log(" Tax:", item.tax?.value);
59-
console.log(" Amount:", item.amount?.value);
61+
for (const item of (items && items.values) || []) {
62+
const { productCode, description, quantity, date, unit, unitPrice, tax, amount } =
63+
item.properties;
64+
65+
console.log("-", (productCode && productCode.value) || "<no product code>");
66+
console.log(" Description:", description && description.value);
67+
console.log(" Quantity:", quantity && quantity.value);
68+
console.log(" Date:", date && date.value);
69+
console.log(" Unit:", unit && unit.value);
70+
console.log(" Unit Price:", unitPrice && unitPrice.value);
71+
console.log(" Tax:", tax && tax.value);
72+
console.log(" Amount:", amount && amount.value);
6073
}
6174

62-
console.log("Subtotal:", invoice.subTotal?.value);
63-
console.log("Previous Unpaid Balance:", invoice.previousUnpaidBalance?.value);
64-
console.log("Tax:", invoice.totalTax?.value);
65-
console.log("Amount Due:", invoice.amountDue?.value);
75+
console.log("Subtotal:", subTotal && subTotal.value);
76+
console.log("Previous Unpaid Balance:", previousUnpaidBalance && previousUnpaidBalance.value);
77+
console.log("Tax:", totalTax && totalTax.value);
78+
console.log("Amount Due:", amountDue && amountDue.value);
6679
} else {
6780
throw new Error("Expected at least one receipt in the result.");
6881
}

sdk/formrecognizer/ai-form-recognizer/samples-dev/analyzeReceipt.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import * as dotenv from "dotenv";
2222
dotenv.config();
2323

2424
async function main() {
25-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
26-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
25+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
26+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
2727

2828
const client = new DocumentAnalysisClient(endpoint, credential);
2929

@@ -39,18 +39,21 @@ async function main() {
3939

4040
// Use of PrebuiltModels.Receipt above (rather than the raw model ID), as it adds strong typing of the model's output
4141
if (result) {
42-
const receipt = result.fields;
42+
const { merchantName, items, total } = result.fields;
43+
4344
console.log("=== Receipt Information ===");
4445
console.log("Type:", result.docType);
45-
console.log("Merchant:", receipt.merchantName?.value);
46+
console.log("Merchant:", merchantName && merchantName.value);
4647

4748
console.log("Items:");
48-
for (const { properties: item } of receipt.items?.values ?? []) {
49-
console.log("- Description:", item.description?.value);
50-
console.log(" Total Price:", item.totalPrice?.value);
49+
for (const item of (items && items.values) || []) {
50+
const { description, totalPrice } = item.properties;
51+
52+
console.log("- Description:", description && description.value);
53+
console.log(" Total Price:", totalPrice && totalPrice.value);
5154
}
5255

53-
console.log("Total:", receipt.total?.value);
56+
console.log("Total:", total && total.value);
5457
} else {
5558
throw new Error("Expected at least one receipt in the result.");
5659
}

sdk/formrecognizer/ai-form-recognizer/samples-dev/analyzeReceiptByModelId.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import * as dotenv from "dotenv";
2626
dotenv.config();
2727

2828
async function main() {
29-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
30-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
29+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
30+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
3131

3232
const client = new DocumentAnalysisClient(endpoint, credential);
3333

@@ -49,7 +49,7 @@ async function main() {
4949
console.log("Merchant:", (receipt["MerchantName"] as DocumentStringField).value);
5050

5151
console.log("Items:");
52-
for (const { properties: item } of ((receipt["Items"] as DocumentArrayField).values ??
52+
for (const { properties: item } of ((receipt["Items"] as DocumentArrayField).values ||
5353
[]) as DocumentObjectField[]) {
5454
console.log("- Description:", (item["Description"] as DocumentStringField).value);
5555
console.log(" Total Price:", (item["TotalPrice"] as DocumentStringField).value);

sdk/formrecognizer/ai-form-recognizer/samples-dev/analyzeW2TaxForm.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import * as dotenv from "dotenv";
2525
dotenv.config();
2626

2727
async function main() {
28-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
29-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
28+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
29+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
3030

3131
const file = fs.readFileSync(path.join(".", "assets", "w2", "gold_simple_w2.png"));
3232

@@ -39,43 +39,42 @@ async function main() {
3939
} = await poller.pollUntilDone();
4040

4141
if (result) {
42-
const w2 = result.fields;
42+
const { employee, employer, controlNumber, taxYear, additionalInfo } = result.fields;
4343

44-
const employee = w2.employee?.properties;
4544
if (employee) {
45+
const { name, address, zipCode, socialSecurityNumber } = employee.properties;
4646
console.log("Employee:");
47-
console.log(" Name:", employee.name?.value);
48-
console.log(" Address:", employee.address?.value);
49-
console.log(" ZIP Code:", employee.zipCode?.value);
50-
console.log(" SSN/TIN:", employee.socialSecurityNumber?.value);
47+
console.log(" Name:", name && name.value);
48+
console.log(" Address:", address && address.value);
49+
console.log(" ZIP Code:", zipCode && zipCode.value);
50+
console.log(" SSN/TIN:", socialSecurityNumber && socialSecurityNumber.value);
5151
} else {
5252
console.log("No employee information extracted.");
5353
}
5454

55-
const employer = w2.employer?.properties;
5655
if (employer) {
56+
const { name, address, zipCode, idNumber } = employer.properties;
5757
console.log("Employer:");
58-
console.log(" Name:", employer.name?.value);
59-
console.log(" Address:", employer.address?.value);
60-
console.log(" ZIP Code:", employer.zipCode?.value);
61-
console.log(" ID (EIN):", employer.idNumber?.value);
58+
console.log(" Name:", name && name.value);
59+
console.log(" Address:", address && address.value);
60+
console.log(" ZIP Code:", zipCode && zipCode.value);
61+
console.log(" ID (EIN):", idNumber && idNumber.value);
6262
} else {
6363
console.log("No employer information extracted.");
6464
}
6565

66-
console.log("Control Number:", w2.controlNumber?.value);
67-
console.log("Tax Year:", w2.taxYear?.value);
66+
console.log("Control Number:", controlNumber && controlNumber.value);
67+
console.log("Tax Year:", taxYear && taxYear.value);
6868

6969
// The Prebuilt Model has many other fields for a variety of different scenarios. Please see the documentation of
7070
// the `TaxUsW2` type or refer to the following link: https://aka.ms/azsdk/formrecognizer/taxusw2fieldschema
7171

72-
if (w2.additionalInfo?.values) {
72+
if (additionalInfo) {
7373
console.log("Additional Info:");
7474

75-
for (const {
76-
properties: { amount, letterCode },
77-
} of w2.additionalInfo.values) {
78-
console.log(`- ${letterCode?.value}: ${amount?.value}`);
75+
for (const info of additionalInfo.values) {
76+
const { letterCode, amount } = info.properties;
77+
console.log(`- ${letterCode && letterCode.value}: ${amount && amount.value}`);
7978
}
8079
}
8180
} else {

sdk/formrecognizer/ai-form-recognizer/samples-dev/buildModel.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ import { DocumentModelBuildMode } from "../src/options/BuildModelOptions";
2020
dotenv.config();
2121

2222
async function main() {
23-
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT ?? "<endpoint>";
24-
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY ?? "<api key>");
23+
const endpoint = process.env.FORM_RECOGNIZER_ENDPOINT || "<endpoint>";
24+
const credential = new AzureKeyCredential(process.env.FORM_RECOGNIZER_API_KEY || "<api key>");
2525

2626
const random = Date.now().toString();
2727
const modelId =
28-
(process.env.CUSTOM_MODEL_ID ?? "<model id>") + random.substring(random.length - 6);
28+
(process.env.CUSTOM_MODEL_ID || "<model id>") + random.substring(random.length - 6);
2929
const trainingDataSasUrl =
30-
process.env.CUSTOM_MODEL_TRAINING_DATA_SAS_URL ?? "<training data container SAS url>";
30+
process.env.CUSTOM_MODEL_TRAINING_DATA_SAS_URL || "<training data container SAS url>";
3131

3232
const client = new DocumentModelAdministrationClient(endpoint, credential);
3333

@@ -47,7 +47,7 @@ async function main() {
4747

4848
console.log("Document Types:");
4949
for (const [docType, { description, fieldSchema: schema }] of Object.entries(
50-
model.docTypes ?? {}
50+
model.docTypes || {}
5151
)) {
5252
console.log(`- Name: "${docType}"`);
5353
console.log(` Description: "${description}"`);
@@ -57,7 +57,7 @@ async function main() {
5757

5858
for (const [fieldName, fieldSchema] of Object.entries(schema)) {
5959
console.log(` - "${fieldName}" (${fieldSchema.type})`);
60-
console.log(` ${fieldSchema.description ?? "<no description>"}`);
60+
console.log(` ${fieldSchema.description || "<no description>"}`);
6161
}
6262
}
6363
}

0 commit comments

Comments
 (0)