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
71 changes: 62 additions & 9 deletions sdk/formrecognizer/Azure.AI.FormRecognizer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,26 @@ Please note that models can also be trained using a graphical user interface suc

Because analyzing and training form documents takes time, these operations are implemented as [**long-running operations**][dotnet_lro_guidelines]. Long-running operations consist of an initial request sent to the service to start an operation, followed by polling the service at intervals to determine whether the operation has completed or failed, and if it has succeeded, to get the result.

For long running operations in the Azure SDK, the client exposes a `Start<operation-name>` method that returns an `Operation<T>`. You can use the extension method `WaitForCompletionAsync()` to wait for the operation to complete and obtain its result. A sample code snippet is provided to illustrate using long-running operations [below](#recognize-receipts).
For long running operations in the Azure SDK, the client exposes a `Start<operation-name>` method that returns an `Operation<T>`. You can use the extension method `WaitForCompletionAsync()` to wait for the operation to complete and obtain its result. A sample code snippet is provided to illustrate using long-running operations [below](#recognize-content).

## Examples
The following section provides several code snippets illustrating common patterns used in the Form Recognizer .NET API.
The following section provides several code snippets illustrating common patterns used in the Form Recognizer .NET API. Most of the snippets below make use of asynchronous service calls, but keep in mind that the Azure.AI.FormRecognizer package supports both synchronous and asynchronous APIs.

### Async examples
* [Recognize Content](#recognize-content)
* [Recognize Custom Forms](#recognize-custom-forms)
* [Recognize Receipts](#recognize-receipts)
* [Train a Model](#train-a-model)
* [Manage Custom Models](#manage-custom-models)

### Sync examples
* [Manage Custom Models Synchronously](#manage-custom-models-synchronously)

### Recognize Content
Recognize text and table data, along with their bounding box coordinates, from documents.

```C# Snippet:FormRecognizerSampleRecognizeContentFromUri
FormPageCollection formPages = await client.StartRecognizeContentFromUri(invoiceUri).WaitForCompletionAsync();
FormPageCollection formPages = await client.StartRecognizeContentFromUriAsync(invoiceUri).WaitForCompletionAsync();
foreach (FormPage page in formPages)
{
Console.WriteLine($"Form Page {page.PageNumber} has {page.Lines.Count} lines.");
Expand All @@ -162,10 +166,10 @@ foreach (FormPage page in formPages)
### Recognize Custom Forms
Recognize and extract form fields and other content from your custom forms, using models you train with your own form types.

```C# Snippet:FormRecognizerSample3RecognizeCustomFormsFromUri
```C# Snippet:FormRecognizerSampleRecognizeCustomFormsFromUri
string modelId = "<modelId>";

RecognizedFormCollection forms = await client.StartRecognizeCustomFormsFromUri(modelId, formUri).WaitForCompletionAsync();
RecognizedFormCollection forms = await client.StartRecognizeCustomFormsFromUriAsync(modelId, formUri).WaitForCompletionAsync();
foreach (RecognizedForm form in forms)
{
Console.WriteLine($"Form of type: {form.FormType}");
Expand All @@ -190,7 +194,7 @@ Recognize data from US sales receipts using a prebuilt model.
```C# Snippet:FormRecognizerSampleRecognizeReceiptFileStream
using (FileStream stream = new FileStream(receiptPath, FileMode.Open))
{
RecognizedFormCollection receipts = await client.StartRecognizeReceipts(stream).WaitForCompletionAsync();
RecognizedFormCollection receipts = await client.StartRecognizeReceiptsAsync(stream).WaitForCompletionAsync();

// To see the list of the supported fields returned by service and its corresponding types, consult:
// https://westus2.dev.cognitive.microsoft.com/docs/services/form-recognizer-api-v2-preview/operations/GetAnalyzeReceiptResult
Expand Down Expand Up @@ -275,7 +279,7 @@ using (FileStream stream = new FileStream(receiptPath, FileMode.Open))
### Train a Model
Train a machine-learned model on your own form types. The resulting model will be able to recognize values from the types of forms it was trained on.

```C# Snippet:FormRecognizerSample4TrainModelWithForms
```C# Snippet:FormRecognizerSampleTrainModelWithForms
// For this sample, you can use the training forms found in the `trainingFiles` folder.
// Upload the forms to your storage container and then generate a container SAS URL.
// For instructions on setting up forms for training in an Azure Storage Blob Container, see
Expand Down Expand Up @@ -308,7 +312,56 @@ foreach (CustomFormSubmodel submodel in model.Submodels)
### Manage Custom Models
Manage the custom models stored in your account.

```C# Snippet:FormRecognizerSample6ManageCustomModels
```C# Snippet:FormRecognizerSampleManageCustomModelsAsync
FormTrainingClient client = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Check number of models in the FormRecognizer account, and the maximum number of models that can be stored.
AccountProperties accountProperties = await client.GetAccountPropertiesAsync();
Console.WriteLine($"Account has {accountProperties.CustomModelCount} models.");
Console.WriteLine($"It can have at most {accountProperties.CustomModelLimit} models.");

// List the models currently stored in the account.
AsyncPageable<CustomFormModelInfo> models = client.GetCustomModelsAsync();

await foreach (CustomFormModelInfo modelInfo in models)
{
Console.WriteLine($"Custom Model Info:");
Console.WriteLine($" Model Id: {modelInfo.ModelId}");
Console.WriteLine($" Model Status: {modelInfo.Status}");
Console.WriteLine($" Training model started on: {modelInfo.TrainingStartedOn}");
Console.WriteLine($" Training model completed on: : {modelInfo.TrainingCompletedOn}");
}

// Create a new model to store in the account
CustomFormModel model = await client.StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();

// Get the model that was just created
CustomFormModel modelCopy = await client.GetCustomModelAsync(model.ModelId);

Console.WriteLine($"Custom Model {modelCopy.ModelId} recognizes the following form types:");

foreach (CustomFormSubmodel submodel in modelCopy.Submodels)
{
Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
foreach (CustomFormModelField field in submodel.Fields.Values)
{
Console.Write($" FieldName: {field.Name}");
if (field.Label != null)
{
Console.Write($", FieldLabel: {field.Label}");
}
Console.WriteLine("");
}
}

// Delete the model from the account.
await client.DeleteModelAsync(model.ModelId);
```

### Manage Custom Models Synchronously
Manage the custom models stored in your account with a synchronous API. Note that we are still making an asynchronous call to `WaitForCompletionAsync` for training, since this method does not have a synchronous counterpart. For more information on long-running operations, see [Long-Running Operations](#long-running-operations).

```C# Snippet:FormRecognizerSampleManageCustomModels
FormTrainingClient client = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Check number of models in the FormRecognizer account, and the maximum number of models that can be stored.
Expand All @@ -329,7 +382,7 @@ foreach (CustomFormModelInfo modelInfo in models.Take(10))
}

// Create a new model to store in the account
CustomFormModel model = await client.StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();
CustomFormModel model = await client.StartTraining(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();

// Get the model that was just created
CustomFormModel modelCopy = client.GetCustomModel(model.ModelId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var client = new FormRecognizerClient(new Uri(endpoint), credential);
To recognize the content from a given file at a URI, use the `StartRecognizeContentFromUri` method. The returned value is a collection of `FormPage` objects -- one for each page in the submitted document.

```C# Snippet:FormRecognizerSampleRecognizeContentFromUri
FormPageCollection formPages = await client.StartRecognizeContentFromUri(invoiceUri).WaitForCompletionAsync();
FormPageCollection formPages = await client.StartRecognizeContentFromUriAsync(invoiceUri).WaitForCompletionAsync();
foreach (FormPage page in formPages)
{
Console.WriteLine($"Form Page {page.PageNumber} has {page.Lines.Count} lines.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ var client = new FormRecognizerClient(new Uri(endpoint), credential);

To recognize form fields and other content from your custom forms from a given file at a URI, use the `StartRecognizeCustomFormsFromUri` method. The returned value is a collection of `RecognizedForm` objects -- one for each page in the submitted document.

```C# Snippet:FormRecognizerSample3RecognizeCustomFormsFromUri
```C# Snippet:FormRecognizerSampleRecognizeCustomFormsFromUri
string modelId = "<modelId>";

RecognizedFormCollection forms = await client.StartRecognizeCustomFormsFromUri(modelId, formUri).WaitForCompletionAsync();
RecognizedFormCollection forms = await client.StartRecognizeCustomFormsFromUriAsync(modelId, formUri).WaitForCompletionAsync();
foreach (RecognizedForm form in forms)
{
Console.WriteLine($"Form of type: {form.FormType}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var client = new FormRecognizerClient(new Uri(endpoint), credential);
To recognize receipts from a URI, use the `StartRecognizeReceiptsFromUri` method. The returned value is a collection of `RecognizedForm` objects -- one for each page in the submitted document.

```C# Snippet:FormRecognizerSampleRecognizeReceiptFileFromUri
RecognizedFormCollection receipts = await client.StartRecognizeReceiptsFromUri(receiptUri).WaitForCompletionAsync();
RecognizedFormCollection receipts = await client.StartRecognizeReceiptsFromUriAsync(receiptUri).WaitForCompletionAsync();

// To see the list of the supported fields returned by service and its corresponding types, consult:
// https://westus2.dev.cognitive.microsoft.com/docs/services/form-recognizer-api-v2-preview/operations/GetAnalyzeReceiptResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public Receipt(RecognizedForm recognizedForm)
Here we illustrate how to use the `Receipt` wrapper class described above.

```C# Snippet:FormRecognizerSampleStronglyTypingARecognizedForm
RecognizedFormCollection recognizedForms = await client.StartRecognizeReceiptsFromUri(receiptUri).WaitForCompletionAsync();
RecognizedFormCollection recognizedForms = await client.StartRecognizeReceiptsFromUriAsync(receiptUri).WaitForCompletionAsync();

foreach (RecognizedForm recognizedForm in recognizedForms)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var client = new FormTrainingClient(new Uri(endpoint), credential);

Train custom models to recognize all fields and values found in your custom forms. A `CustomFormModel` is returned indicating the form types the model will recognize, and the fields it will extract from each form type.

```C# Snippet:FormRecognizerSample4TrainModelWithForms
```C# Snippet:FormRecognizerSampleTrainModelWithForms
// For this sample, you can use the training forms found in the `trainingFiles` folder.
// Upload the forms to your storage container and then generate a container SAS URL.
// For instructions on setting up forms for training in an Azure Storage Blob Container, see
Expand Down Expand Up @@ -57,7 +57,7 @@ foreach (CustomFormSubmodel submodel in model.Submodels)

Train custom models to recognize specific fields and values you specify by labeling your custom forms. A `CustomFormModel` is returned indicating the fields the model will extract, as well as the estimated accuracy for each field.

```C# Snippet:FormRecognizerSample5TrainModelWithFormsAndLabels
```C# Snippet:FormRecognizerSampleTrainModelWithFormsAndLabels
// For this sample, you can use the training forms found in the `trainingFiles` folder.
// Upload the forms to your storage container and then generate a container SAS URL.
// For instructions to set up forms for training in an Azure Storage Blob Container, please see:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,59 @@ Operations that can be executed are:
- Get a specific model using the model's Id.
- Delete a model from the resource account.

```C# Snippet:FormRecognizerSample6ManageCustomModels
## Manage Custom Models Asynchronously

```C# Snippet:FormRecognizerSampleManageCustomModelsAsync
FormTrainingClient client = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Check number of models in the FormRecognizer account, and the maximum number of models that can be stored.
AccountProperties accountProperties = await client.GetAccountPropertiesAsync();
Console.WriteLine($"Account has {accountProperties.CustomModelCount} models.");
Console.WriteLine($"It can have at most {accountProperties.CustomModelLimit} models.");

// List the models currently stored in the account.
AsyncPageable<CustomFormModelInfo> models = client.GetCustomModelsAsync();

await foreach (CustomFormModelInfo modelInfo in models)
{
Console.WriteLine($"Custom Model Info:");
Console.WriteLine($" Model Id: {modelInfo.ModelId}");
Console.WriteLine($" Model Status: {modelInfo.Status}");
Console.WriteLine($" Training model started on: {modelInfo.TrainingStartedOn}");
Console.WriteLine($" Training model completed on: : {modelInfo.TrainingCompletedOn}");
}

// Create a new model to store in the account
CustomFormModel model = await client.StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();

// Get the model that was just created
CustomFormModel modelCopy = await client.GetCustomModelAsync(model.ModelId);

Console.WriteLine($"Custom Model {modelCopy.ModelId} recognizes the following form types:");

foreach (CustomFormSubmodel submodel in modelCopy.Submodels)
{
Console.WriteLine($"Submodel Form Type: {submodel.FormType}");
foreach (CustomFormModelField field in submodel.Fields.Values)
{
Console.Write($" FieldName: {field.Name}");
if (field.Label != null)
{
Console.Write($", FieldLabel: {field.Label}");
}
Console.WriteLine("");
}
}

// Delete the model from the account.
await client.DeleteModelAsync(model.ModelId);
```

## Manage Custom Models Synchronously

Note that we are still making an asynchronous call to `WaitForCompletionAsync` for training, since this method does not have a synchronous counterpart.

```C# Snippet:FormRecognizerSampleManageCustomModels
FormTrainingClient client = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Check number of models in the FormRecognizer account, and the maximum number of models that can be stored.
Expand All @@ -46,7 +98,7 @@ foreach (CustomFormModelInfo modelInfo in models.Take(10))
}

// Create a new model to store in the account
CustomFormModel model = await client.StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();
CustomFormModel model = await client.StartTraining(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();

// Get the model that was just created
CustomFormModel modelCopy = client.GetCustomModel(model.ModelId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ You can set `endpoint` and `apiKey` based on an environment variable, a configur
### Source client
The source client that contains the custom model we want to copy.

```C# Snippet:FormRecognizerSample6CreateCopySourceClient
```C# Snippet:FormRecognizerSampleCreateCopySourceClient
string endpoint = "<source_endpoint>";
string apiKey = "<source_apiKey>";
var sourcecredential = new AzureKeyCredential(apiKey);
Expand All @@ -30,7 +30,7 @@ var sourceClient = new FormTrainingClient(new Uri(endpoint), sourcecredential);
### Target client
The target client where we want to copy the custom model to.

```C# Snippet:FormRecognizerSample6CreateCopyTargetClient
```C# Snippet:FormRecognizerSampleCreateCopyTargetClient
string endpoint = "<target_endpoint>";
string apiKey = "<target_apiKey>";
var targetCredential = new AzureKeyCredential(apiKey);
Expand All @@ -39,26 +39,26 @@ var targetClient = new FormTrainingClient(new Uri(endpoint), targetCredential);

### Authorize the copy
Before starting the copy, we need to get a `CopyAuthorization` from the target Form Recognizer resource that will give us permission to execute the copy.
```C# Snippet:FormRecognizerSample6GetCopyAuthorization
```C# Snippet:FormRecognizerSampleGetCopyAuthorization
string resourceId = "<resourceId>";
string resourceRegion = "<region>";
CopyAuthorization targetAuth = await targetClient.GetCopyAuthorizationAsync(resourceId, resourceRegion);
```

`CopyAuthorization` provides the convenience method `ToJson` that will serialize the authorization properties into a json format string.
```C# Snippet:FormRecognizerSample6ToJson
```C# Snippet:FormRecognizerSampleToJson
string jsonTargetAuth = targetAuth.ToJson();
```

To deserealize a string that contains authorizaiton information, use the `FromJson` method from `CopyAuthorization`.
```C# Snippet:FormRecognizerSample6FromJson
```C# Snippet:FormRecognizerSampleFromJson
CopyAuthorization targetCopyAuth = CopyAuthorization.FromJson(jsonTargetAuth);
```

### Execute the copy
Now that we have authorization from the target Form Recognizer resource, we execute the copy from the `sourceClient` where the model to copy lives.

```C# Snippet:FormRecognizerSample6CopyModel
```C# Snippet:FormRecognizerSampleCopyModel
string modelId = "<source_modelId>";
CustomFormModelInfo newModel = await sourceClient.StartCopyModelAsync(modelId, targetCopyAuth).WaitForCompletionAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ public async Task OutputModelsTrainedWithLabels()
FormTrainingClient trainingClient = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Model trained with labels
CustomFormModel modelTrainedWithLabels = await trainingClient.StartTraining(new Uri(trainingFileUrl), useTrainingLabels: true).WaitForCompletionAsync();
CustomFormModel modelTrainedWithLabels = await trainingClient.StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: true).WaitForCompletionAsync();

using (FileStream stream = new FileStream(formFilePath, FileMode.Open))
{
RecognizedFormCollection forms = await client.StartRecognizeCustomForms(modelTrainedWithLabels.ModelId, stream).WaitForCompletionAsync();
RecognizedFormCollection forms = await client.StartRecognizeCustomFormsAsync(modelTrainedWithLabels.ModelId, stream).WaitForCompletionAsync();

// With a form recognized by a model trained with labels, the 'field.Name' key will be the label
// that you gave it at training time.
Expand Down Expand Up @@ -88,11 +88,11 @@ public async Task OutputModelsTrainedWithoutLabels()
FormTrainingClient trainingClient = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

// Model trained without labels
CustomFormModel modelTrainedWithoutLabels = await trainingClient.StartTraining(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();
CustomFormModel modelTrainedWithoutLabels = await trainingClient.StartTrainingAsync(new Uri(trainingFileUrl), useTrainingLabels: false).WaitForCompletionAsync();

using (FileStream stream = new FileStream(formFilePath, FileMode.Open))
{
RecognizedFormCollection forms = await client.StartRecognizeCustomForms(modelTrainedWithoutLabels.ModelId, stream).WaitForCompletionAsync();
RecognizedFormCollection forms = await client.StartRecognizeCustomFormsAsync(modelTrainedWithoutLabels.ModelId, stream).WaitForCompletionAsync();

// With a form recognized by a model trained without labels, the 'field.Name' property will be denoted
// by a numeric index. To look for the labels identified during the training step,
Expand Down
Loading