Ejemplo n.º 1
0
        public async Task CheckFormTypeinSubmodelAndRecognizedForm(bool labeled)
        {
            var client     = CreateFormTrainingClient();
            var formClient = client.GetFormRecognizerClient();

            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            TrainingOperation trainingOperation = await client.StartTrainingAsync(trainingFilesUri, labeled);

            await trainingOperation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(trainingOperation.HasValue);

            CustomFormModel model = trainingOperation.Value;

            Assert.IsNotNull(model.Submodels.FirstOrDefault().FormType);

            var uri = FormRecognizerTestEnvironment.CreateUri(TestFile.Form1);
            RecognizeCustomFormsOperation recognizeOperation = await formClient.StartRecognizeCustomFormsFromUriAsync(model.ModelId, uri);

            await recognizeOperation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(recognizeOperation.HasValue);

            RecognizedForm form = recognizeOperation.Value.Single();

            Assert.IsNotNull(form.FormType);
            Assert.AreEqual(form.FormType, model.Submodels.FirstOrDefault().FormType);
        }
Ejemplo n.º 2
0
        public async Task TrainingOperationCreatesDiagnosticScopeOnUpdate()
        {
            using var testListener = new ClientDiagnosticListener(DiagnosticNamespace);
            using var stream       = new MemoryStream(Encoding.UTF8.GetBytes(@"
                {
                    ""modelInfo"": {
                        ""status"": ""creating"",
                        ""modelId"": ""00000000-0000-0000-0000-000000000000""
                    }
                }"));

            var mockResponse = new MockResponse(200);

            mockResponse.ContentStream = stream;

            var mockTransport = new MockTransport(new[] { mockResponse, mockResponse });
            var options       = new FormRecognizerClientOptions()
            {
                Transport = mockTransport
            };
            var client = CreateFormTrainingClient(options);

            var operation = new TrainingOperation("00000000-0000-0000-0000-000000000000", client);

            if (IsAsync)
            {
                await operation.UpdateStatusAsync();
            }
            else
            {
                operation.UpdateStatus();
            }

            testListener.AssertScope($"{nameof(CreateCustomFormModelOperation)}.{nameof(CreateCustomFormModelOperation.UpdateStatus)}");
        }
Ejemplo n.º 3
0
        private static async Task CreateModel(string endpoint, string apiKey, string trainingSetUrl, string modelName)
        {
            // Create a new model to store in the account
            Uri trainingSetUri = new Uri(trainingSetUrl);

            FormTrainingClient         client            = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));
            TrainingOperation          operation         = client.StartTraining(trainingSetUri, useTrainingLabels: true, modelName);
            Response <CustomFormModel> operationResponse = await operation.WaitForCompletionAsync();

            CustomFormModel model = operationResponse.Value;

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

            Console.WriteLine($"Custom Model with Id {modelCopy.ModelId}  and name {modelCopy.ModelName} 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.
            //client.DeleteModel(model.ModelId);
        }
Ejemplo n.º 4
0
        public async Task TrainModelWithFormsAndLabels()
        {
            string endpoint = TestEnvironment.Endpoint;
            string apiKey   = TestEnvironment.ApiKey;

            #region 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. Note
            // that a container URI without SAS is accepted only when the container is public or has a
            // managed identity configured.
            //
            // For instructions to set up forms for training in an Azure Blob Storage Container, please see:
            // https://docs.microsoft.com/azure/cognitive-services/form-recognizer/build-training-data-set#upload-your-training-data

            // For instructions to create a label file for your training forms, please see:
            // https://docs.microsoft.com/azure/cognitive-services/form-recognizer/label-tool?tabs=v2-1

#if SNIPPET
            Uri trainingFileUri = new Uri("<trainingFileUri>");
#else
            Uri trainingFileUri = new Uri(TestEnvironment.BlobContainerSasUrlV2);
#endif
            string             modelName = "My Model with labels";
            FormTrainingClient client    = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

            TrainingOperation operation = await client.StartTrainingAsync(trainingFileUri, useTrainingLabels : true, modelName);

            Response <CustomFormModel> operationResponse = await operation.WaitForCompletionAsync();

            CustomFormModel model = operationResponse.Value;

            Console.WriteLine($"Custom Model Info:");
            Console.WriteLine($"  Model Id: {model.ModelId}");
            Console.WriteLine($"  Model name: {model.ModelName}");
            Console.WriteLine($"  Model Status: {model.Status}");
            Console.WriteLine($"  Is composed model: {model.Properties.IsComposedModel}");
            Console.WriteLine($"  Training model started on: {model.TrainingStartedOn}");
            Console.WriteLine($"  Training model completed on: {model.TrainingCompletedOn}");

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

            // Delete the model on completion to clean environment.
            await client.DeleteModelAsync(model.ModelId);
        }
        public async Task CopyModel()
        {
            string endpoint        = TestEnvironment.Endpoint;
            string apiKey          = TestEnvironment.ApiKey;
            Uri    trainingFileUri = new Uri(TestEnvironment.BlobContainerSasUrl);
            string resourceId      = TestEnvironment.TargetResourceId;
            string resourceRegion  = TestEnvironment.TargetResourceRegion;

            #region Snippet:FormRecognizerSampleCreateCopySourceClient
            //@@ string endpoint = "<source_endpoint>";
            //@@ string apiKey = "<source_apiKey>";
            var sourcecredential = new AzureKeyCredential(apiKey);
            var sourceClient     = new FormTrainingClient(new Uri(endpoint), sourcecredential);
            #endregion

            // For the purpose of this sample, we are going to create a trained model to copy. Please note that
            // if you already have a model, this is not necessary.
            //@@ Uri trainingFileUri = <trainingFileUri>;
            TrainingOperation operation = await sourceClient.StartTrainingAsync(trainingFileUri, useTrainingLabels : false);

            Response <CustomFormModel> operationResponse = await operation.WaitForCompletionAsync();

            CustomFormModel model = operationResponse.Value;

            string modelId = model.ModelId;

            #region Snippet:FormRecognizerSampleCreateCopyTargetClient
            //@@ string endpoint = "<target_endpoint>";
            //@@ string apiKey = "<target_apiKey>";
            var targetCredential = new AzureKeyCredential(apiKey);
            var targetClient     = new FormTrainingClient(new Uri(endpoint), targetCredential);
            #endregion

            #region Snippet:FormRecognizerSampleGetCopyAuthorization
            //@@ string resourceId = "<resourceId>";
            //@@ string resourceRegion = "<region>";
            CopyAuthorization targetAuth = await targetClient.GetCopyAuthorizationAsync(resourceId, resourceRegion);

            #endregion

            #region Snippet:FormRecognizerSampleToJson
            string jsonTargetAuth = targetAuth.ToJson();
            #endregion

            #region Snippet:FormRecognizerSampleFromJson
            CopyAuthorization targetCopyAuth = CopyAuthorization.FromJson(jsonTargetAuth);
            #endregion

            #region Snippet:FormRecognizerSampleCopyModel
            //@@ string modelId = "<source_modelId>";
            CustomFormModelInfo newModel = await sourceClient.StartCopyModelAsync(modelId, targetCopyAuth).WaitForCompletionAsync();

            Console.WriteLine($"Original model ID => {modelId}");
            Console.WriteLine($"Copied model ID => {newModel.ModelId}");
            #endregion
        }
        /// <summary>
        ///  For testing purposes, we are training our models using the client library functionalities.
        ///  Please note that models can also be trained using a graphical user interface
        ///  such as the Form Recognizer Labeling Tool found here:
        ///  <a href="https://docs.microsoft.com/azure/cognitive-services/form-recognizer/quickstarts/label-tool"/>.
        /// </summary>
        private async Task <string> GetModelIdAsync(bool useLabels = false)
        {
            FormTrainingClient trainingClient = InstrumentClient(new FormTrainingClient(_endpoint, _credential));
            TrainingOperation  trainedModel   = await trainingClient.StartTrainingAsync(_containerUri, useLabels);

            await trainedModel.WaitForCompletionAsync();

            Assert.IsTrue(trainedModel.HasValue);

            return(trainedModel.Value.ModelId);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Trains a model using the specified <see cref="FormTrainingClient"/> and the specified set of training files. A
        /// <see cref="DisposableTrainedModel"/> instance is returned, from which the model ID can be obtained. Upon disposal,
        /// the associated model will be deleted.
        /// </summary>
        /// <param name="trainingClient">The client to use for training and for deleting the model upon disposal.</param>
        /// <param name="trainingFilesUri">An externally accessible Azure storage blob container Uri.</param>
        /// <param name="useTrainingLabels">If <c>true</c>, use a label file created in the &lt;link-to-label-tool-doc&gt; to provide training-time labels for training a model. If <c>false</c>, the model will be trained from forms only.</param>
        /// <param name="modelName">Optional model name.</param>
        /// <returns>A <see cref="DisposableTrainedModel"/> instance from which the trained model ID can be obtained.</returns>
        public static async Task <DisposableTrainedModel> TrainModelAsync(FormTrainingClient trainingClient, Uri trainingFilesUri, bool useTrainingLabels, string modelName = default)
        {
            TrainingOperation operation = await trainingClient.StartTrainingAsync(trainingFilesUri, useTrainingLabels, modelName);

            await operation.WaitForCompletionAsync();

            Assert.IsTrue(operation.HasValue);
            Assert.AreEqual(CustomFormModelStatus.Ready, operation.Value.Status);

            return(new DisposableTrainedModel(trainingClient, operation.Value.ModelId));
        }
        public async Task StartTrainingFailsWithInvalidPrefix()
        {
            var client           = CreateFormTrainingClient();
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            var filter = new TrainingFileFilter {
                IncludeSubFolders = true, Prefix = "invalidPrefix"
            };
            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : false, filter);

            Assert.ThrowsAsync <RequestFailedException>(async() => await operation.WaitForCompletionAsync(PollingInterval));
        }
Ejemplo n.º 9
0
        public async Task TrainingOperationCanPollFromNewObject()
        {
            var client           = CreateFormTrainingClient(out var nonInstrumentedClient);
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            var operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : false);

            var sameOperation = new TrainingOperation(operation.Id, nonInstrumentedClient);
            await sameOperation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(sameOperation.HasValue);
            Assert.AreEqual(CustomFormModelStatus.Ready, sameOperation.Value.Status);
        }
Ejemplo n.º 10
0
        public async Task StartTrainingWithNoLabelsModelName()
        {
            var client           = CreateFormTrainingClient();
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);
            var modelName        = "My training";

            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : false, modelName);

            await operation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(operation.HasValue);
            Assert.AreEqual(modelName, operation.Value.ModelName);
        }
Ejemplo n.º 11
0
        public async Task StartTrainingError()
        {
            var client = CreateInstrumentedFormTrainingClient();

            var containerUrl = new Uri("https://someUrl");

            TrainingOperation operation = await client.StartTrainingAsync(containerUrl, useTrainingLabels : false);

            Assert.ThrowsAsync <RequestFailedException>(async() => await operation.WaitForCompletionAsync(PollingInterval));

            Assert.False(operation.HasValue);
            Assert.Throws <RequestFailedException>(() => operation.Value.GetType());
        }
Ejemplo n.º 12
0
        public async Task StartTraining(bool singlePage, bool labeled)
        {
            var client           = CreateFormTrainingClient();
            var trainingFilesUri = new Uri(singlePage ? TestEnvironment.BlobContainerSasUrlV2 : TestEnvironment.MultipageBlobContainerSasUrlV2);

            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, labeled);

            await operation.WaitForCompletionAsync();

            Assert.IsTrue(operation.HasValue);

            CustomFormModel model = operation.Value;

            Assert.IsNotNull(model.ModelId);
            Assert.IsNull(model.ModelName);
            Assert.IsNotNull(model.Properties);
            Assert.IsFalse(model.Properties.IsComposedModel);
            Assert.IsNotNull(model.TrainingStartedOn);
            Assert.IsNotNull(model.TrainingCompletedOn);
            Assert.AreEqual(CustomFormModelStatus.Ready, model.Status);
            Assert.IsNotNull(model.Errors);
            Assert.AreEqual(0, model.Errors.Count);

            foreach (TrainingDocumentInfo doc in model.TrainingDocuments)
            {
                Assert.IsNotNull(doc.Name);
                Assert.IsNotNull(doc.ModelId);
                Assert.IsNotNull(doc.PageCount);
                Assert.AreEqual(TrainingStatus.Succeeded, doc.Status);
                Assert.IsNotNull(doc.Errors);
                Assert.AreEqual(0, doc.Errors.Count);
            }

            foreach (var submodel in model.Submodels)
            {
                Assert.IsNotNull(submodel.FormType);
                Assert.IsNotNull(submodel.ModelId);
                foreach (var fields in submodel.Fields)
                {
                    Assert.IsNotNull(fields.Value.Name);
                    if (labeled)
                    {
                        Assert.IsNotNull(fields.Value.Accuracy);
                    }
                    else
                    {
                        Assert.IsNotNull(fields.Value.Label);
                    }
                }
            }
        }
        public async Task TrainModelWithForms()
        {
            string endpoint = TestEnvironment.Endpoint;
            string apiKey   = TestEnvironment.ApiKey;

            #region 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
            // https://docs.microsoft.com/azure/cognitive-services/form-recognizer/build-training-data-set#upload-your-training-data

#if SNIPPET
            Uri trainingFileUri = < trainingFileUri >;
#else
            Uri trainingFileUri = new Uri(TestEnvironment.BlobContainerSasUrlV2);
#endif
            FormTrainingClient client = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

            TrainingOperation operation = await client.StartTrainingAsync(trainingFileUri, useTrainingLabels : false, "My Model");

            Response <CustomFormModel> operationResponse = await operation.WaitForCompletionAsync();

            CustomFormModel model = operationResponse.Value;

            Console.WriteLine($"Custom Model Info:");
            Console.WriteLine($"  Model Id: {model.ModelId}");
            Console.WriteLine($"  Model name: {model.ModelName}");
            Console.WriteLine($"  Model Status: {model.Status}");
            Console.WriteLine($"  Is composed model: {model.Properties.IsComposedModel}");
            Console.WriteLine($"  Training model started on: {model.TrainingStartedOn}");
            Console.WriteLine($"  Training model completed on: {model.TrainingCompletedOn}");

            foreach (CustomFormSubmodel submodel in model.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("");
                }
            }
            #endregion

            // Delete the model on completion to clean environment.
            await client.DeleteModelAsync(model.ModelId);
        }
        public async Task StartTrainingSucceedsWithValidPrefix()
        {
            var client           = CreateFormTrainingClient();
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            var filter = new TrainingFileFilter {
                IncludeSubFolders = true, Prefix = "subfolder"
            };
            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : false, filter);

            await operation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(operation.HasValue);
            Assert.AreEqual(CustomFormModelStatus.Ready, operation.Value.Status);
        }
        public async Task FormTrainingClientCanAuthenticateWithTokenCredential()
        {
            var client           = CreateFormTrainingClient(useTokenCredential: true);
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : false);

            CustomFormModel model = await operation.WaitForCompletionAsync(PollingInterval);

            // Sanity check to make sure we got an actual response back from the service.
            Assert.IsNotNull(model.ModelId);
            Assert.AreEqual(CustomFormModelStatus.Ready, model.Status);
            Assert.IsNotNull(model.Errors);
            Assert.AreEqual(0, model.Errors.Count);
        }
Ejemplo n.º 16
0
        public async Task StartTrainingWithLabelsDisplayName()
        {
            var client           = CreateFormTrainingClient();
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);
            var displayName      = "My training";

            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : true, new TrainingOptions()
            {
                ModelDisplayName = displayName
            });

            await operation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(operation.HasValue);
            Assert.AreEqual(displayName, operation.Value.DisplayName);
        }
Ejemplo n.º 17
0
        public async Task TrainingOperationCanPollFromNewObject()
        {
            // Skip instrumenting here because the internal service client passed to the operation object would be made null otherwise,
            // making the test fail.

            var client           = CreateFormTrainingClient(skipInstrumenting: true);
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            var operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : false);

            var sameOperation = new TrainingOperation(operation.Id, client);
            await sameOperation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(sameOperation.HasValue);
            Assert.AreEqual(CustomFormModelStatus.Ready, sameOperation.Value.Status);
        }
Ejemplo n.º 18
0
        public async Task StartTraining(bool labeled)
        {
            var client = CreateInstrumentedClient();

            TrainingOperation operation = await client.StartTrainingAsync(_containerUri, labeled);

            await operation.WaitForCompletionAsync();

            Assert.IsTrue(operation.HasValue);

            CustomFormModel model = operation.Value;

            Assert.IsNotNull(model.ModelId);
            Assert.IsNotNull(model.CreatedOn);
            Assert.IsNotNull(model.LastModified);
            Assert.IsNotNull(model.Status);
            Assert.AreEqual(CustomFormModelStatus.Ready, model.Status);
            Assert.IsNotNull(model.Errors);
            Assert.AreEqual(0, model.Errors.Count);

            foreach (TrainingDocumentInfo doc in model.TrainingDocuments)
            {
                Assert.IsNotNull(doc.DocumentName);
                Assert.IsNotNull(doc.PageCount);
                Assert.AreEqual(TrainingStatus.Succeeded, doc.Status);
                Assert.IsNotNull(doc.Errors);
                Assert.AreEqual(0, doc.Errors.Count);
            }

            foreach (var subModel in model.Models)
            {
                Assert.IsNotNull(subModel.FormType);
                foreach (var fields in subModel.Fields)
                {
                    Assert.IsNotNull(fields.Value.Name);
                    if (labeled)
                    {
                        Assert.IsNotNull(fields.Value.Accuracy);
                    }
                    else
                    {
                        Assert.IsNotNull(fields.Value.Label);
                    }
                }
            }
        }
Ejemplo n.º 19
0
        public async Task StartTrainingFailsWithInvalidPrefix()
        {
            var client           = CreateFormTrainingClient();
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrlV2);

            var filter = new TrainingFileFilter {
                IncludeSubfolders = true, Prefix = "invalidPrefix"
            };
            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, useTrainingLabels : false, new TrainingOptions()
            {
                TrainingFileFilter = filter
            });

            RequestFailedException ex = Assert.ThrowsAsync <RequestFailedException>(async() => await operation.WaitForCompletionAsync());

            Assert.AreEqual("2014", ex.ErrorCode);
        }
        public async Task StartTrainingError()
        {
            var client = CreateInstrumentedClient();

            var containerUrl = new Uri("https://someUrl");

            TrainingOperation operation = await client.StartTrainingAsync(containerUrl);

            await operation.WaitForCompletionAsync();

            Assert.IsTrue(operation.HasValue);

            CustomFormModel model = operation.Value;

            Assert.IsNotNull(model.ModelId);
            Assert.IsNotNull(model.CreatedOn);
            Assert.IsNotNull(model.LastModified);
            Assert.IsNotNull(model.Status);
            Assert.AreEqual(CustomFormModelStatus.Invalid, model.Status);
            Assert.IsNotNull(model.Errors);
            Assert.AreEqual(1, model.Errors.Count);
            Assert.IsNotNull(model.Errors.FirstOrDefault().Code);
            Assert.IsNotNull(model.Errors.FirstOrDefault().Message);
        }
        public async Task ManageCustomModels()
        {
            string endpoint        = TestEnvironment.Endpoint;
            string apiKey          = TestEnvironment.ApiKey;
            Uri    trainingFileUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            #region 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.
            AccountProperties accountProperties = client.GetAccountProperties();
            Console.WriteLine($"Account has {accountProperties.CustomModelCount} models.");
            Console.WriteLine($"It can have at most {accountProperties.CustomModelLimit} models.");

            // List the first ten or fewer models currently stored in the account.
            Pageable <CustomFormModelInfo> models = client.GetCustomModels();

            foreach (CustomFormModelInfo modelInfo in models.Take(10))
            {
                Console.WriteLine($"Custom Model Info:");
                Console.WriteLine($"  Model Id: {modelInfo.ModelId}");
                Console.WriteLine($"  Model name: {modelInfo.ModelName}");
                Console.WriteLine($"  Is composed model: {modelInfo.Properties.IsComposedModel}");
                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

            //@@ Uri trainingFileUri = <trainingFileUri>;
            TrainingOperation          operation         = client.StartTraining(trainingFileUri, useTrainingLabels: false, "My new model");
            Response <CustomFormModel> operationResponse = await operation.WaitForCompletionAsync();

            CustomFormModel model = operationResponse.Value;

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

            Console.WriteLine($"Custom Model with Id {modelCopy.ModelId}  and name {modelCopy.ModelName} 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.
            client.DeleteModel(model.ModelId);

            #endregion
        }
        public async Task TrainingOps(bool labeled)
        {
            var client           = CreateFormTrainingClient();
            var trainingFilesUri = new Uri(TestEnvironment.BlobContainerSasUrl);

            TrainingOperation operation = await client.StartTrainingAsync(trainingFilesUri, labeled);

            await operation.WaitForCompletionAsync(PollingInterval);

            Assert.IsTrue(operation.HasValue);

            CustomFormModel trainedModel = operation.Value;

            CustomFormModel resultModel = await client.GetCustomModelAsync(trainedModel.ModelId);

            Assert.AreEqual(trainedModel.ModelId, resultModel.ModelId);
            Assert.AreEqual(trainedModel.TrainingStartedOn, resultModel.TrainingStartedOn);
            Assert.AreEqual(trainedModel.TrainingCompletedOn, resultModel.TrainingCompletedOn);
            Assert.AreEqual(CustomFormModelStatus.Ready, resultModel.Status);
            Assert.AreEqual(trainedModel.Status, resultModel.Status);
            Assert.AreEqual(trainedModel.Errors.Count, resultModel.Errors.Count);

            for (int i = 0; i < resultModel.TrainingDocuments.Count; i++)
            {
                var tm = trainedModel.TrainingDocuments[i];
                var rm = resultModel.TrainingDocuments[i];

                Assert.AreEqual(tm.Name, rm.Name);
                Assert.AreEqual(tm.PageCount, rm.PageCount);
                Assert.AreEqual(TrainingStatus.Succeeded, rm.Status);
                Assert.AreEqual(tm.Status, rm.Status);
                Assert.AreEqual(tm.Errors.Count, rm.Errors.Count);
            }

            for (int i = 0; i < resultModel.Submodels.Count; i++)
            {
                Assert.AreEqual(trainedModel.Submodels[i].FormType, resultModel.Submodels[i].FormType);

                foreach (var fields in resultModel.Submodels[i].Fields)
                {
                    Assert.AreEqual(trainedModel.Submodels[i].Fields[fields.Key].Name, fields.Value.Name);
                    if (labeled)
                    {
                        Assert.AreEqual(trainedModel.Submodels[i].Fields[fields.Key].Accuracy, fields.Value.Accuracy);
                    }
                    else
                    {
                        Assert.AreEqual(trainedModel.Submodels[i].Fields[fields.Key].Label, fields.Value.Label);
                    }
                }
            }

            CustomFormModelInfo modelInfo = client.GetCustomModelsAsync().ToEnumerableAsync().Result.FirstOrDefault();

            Assert.IsNotNull(modelInfo.ModelId);
            Assert.IsNotNull(modelInfo.TrainingStartedOn);
            Assert.IsNotNull(modelInfo.TrainingCompletedOn);
            Assert.IsNotNull(modelInfo.Status);

            AccountProperties accountP = await client.GetAccountPropertiesAsync();

            Assert.IsNotNull(accountP.CustomModelCount);
            Assert.IsNotNull(accountP.CustomModelLimit);

            await client.DeleteModelAsync(trainedModel.ModelId);

            RequestFailedException ex = Assert.ThrowsAsync <RequestFailedException>(() => client.GetCustomModelAsync(trainedModel.ModelId));

            Assert.AreEqual("1022", ex.ErrorCode);
        }
        public async Task CreateComposedModel()
        {
            string endpoint        = TestEnvironment.Endpoint;
            string apiKey          = TestEnvironment.ApiKey;
            string trainingFileUrl = TestEnvironment.BlobContainerSasUrlV2;

            FormTrainingClient client = new FormTrainingClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

            #region Snippet:FormRecognizerSampleTrainVariousModels
            // 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
            // https://docs.microsoft.com/azure/cognitive-services/form-recognizer/build-training-data-set#upload-your-training-data

            bool useLabels = true;

#if SNIPPET
            Uri officeSuppliesUri = new Uri("<purchaseOrderOfficeSuppliesUri>");
#else
            Uri officeSuppliesUri = new Uri(trainingFileUrl);
#endif
            string suppliesModelName = "Purchase order - Office supplies";

            TrainingOperation suppliesOperation = await client.StartTrainingAsync(officeSuppliesUri, useLabels, suppliesModelName);

            Response <CustomFormModel> suppliesOperationResponse = await suppliesOperation.WaitForCompletionAsync();

            CustomFormModel officeSuppliesModel = suppliesOperationResponse.Value;

#if SNIPPET
            Uri officeEquipmentUri = new Uri("<purchaseOrderOfficeEquipmentUri>");
#else
            Uri officeEquipmentUri = new Uri(trainingFileUrl);
#endif
            string equipmentModelName = "Purchase order - Office Equipment";

            TrainingOperation equipmentOperation = await client.StartTrainingAsync(officeEquipmentUri, useLabels, equipmentModelName);

            Response <CustomFormModel> equipmentOperationResponse = await equipmentOperation.WaitForCompletionAsync();

            CustomFormModel officeEquipmentModel = equipmentOperationResponse.Value;

#if SNIPPET
            Uri furnitureUri = new Uri("<purchaseOrderFurnitureUri>");
#else
            Uri furnitureUri = new Uri(trainingFileUrl);
#endif
            string furnitureModelName = "Purchase order - Furniture";

            TrainingOperation furnitureOperation = await client.StartTrainingAsync(furnitureUri, useLabels, furnitureModelName);

            Response <CustomFormModel> furnitureOperationResponse = await furnitureOperation.WaitForCompletionAsync();

            CustomFormModel furnitureModel = furnitureOperationResponse.Value;

#if SNIPPET
            Uri cleaningSuppliesUri = new Uri("<purchaseOrderCleaningSuppliesUri>");
#else
            Uri cleaningSuppliesUri = new Uri(trainingFileUrl);
#endif
            string cleaningModelName = "Purchase order - Cleaning Supplies";

            TrainingOperation cleaningOperation = await client.StartTrainingAsync(cleaningSuppliesUri, useLabels, cleaningModelName);

            Response <CustomFormModel> cleaningOperationResponse = await cleaningOperation.WaitForCompletionAsync();

            CustomFormModel cleaningSuppliesModel = cleaningOperationResponse.Value;

            #endregion

            #region Snippet:FormRecognizerSampleCreateComposedModelV3

            List <string> modelIds = new List <string>()
            {
                officeSuppliesModel.ModelId,
                officeEquipmentModel.ModelId,
                furnitureModel.ModelId,
                cleaningSuppliesModel.ModelId
            };

            string purchaseModelName = "Composed Purchase order";
            CreateComposedModelOperation operation = await client.StartCreateComposedModelAsync(modelIds, purchaseModelName);

            Response <CustomFormModel> operationResponse = await operation.WaitForCompletionAsync();

            CustomFormModel purchaseOrderModel = operationResponse.Value;

            Console.WriteLine($"Purchase Order Model Info:");
            Console.WriteLine($"  Is composed model: {purchaseOrderModel.Properties.IsComposedModel}");
            Console.WriteLine($"  Model Id: {purchaseOrderModel.ModelId}");
            Console.WriteLine($"  Model name: {purchaseOrderModel.ModelName}");
            Console.WriteLine($"  Model Status: {purchaseOrderModel.Status}");
            Console.WriteLine($"  Create model started on: {purchaseOrderModel.TrainingStartedOn}");
            Console.WriteLine($"  Create model completed on: {purchaseOrderModel.TrainingCompletedOn}");

            #endregion

            #region Snippet:FormRecognizerSampleSubmodelsInComposedModel

            Dictionary <string, List <TrainingDocumentInfo> > trainingDocsPerModel;
            trainingDocsPerModel = purchaseOrderModel.TrainingDocuments.GroupBy(doc => doc.ModelId).ToDictionary(g => g.Key, g => g.ToList());

            Console.WriteLine($"The purchase order model is based on {purchaseOrderModel.Submodels.Count} models");

            foreach (CustomFormSubmodel model in purchaseOrderModel.Submodels)
            {
                Console.WriteLine($"  Model Id: {model.ModelId}");
                Console.WriteLine("  The documents used to trained the model are: ");
                foreach (var doc in trainingDocsPerModel[model.ModelId])
                {
                    Console.WriteLine($"    {doc.Name}");
                }
            }

            #endregion

            #region Snippet:FormRecognizerSampleRecognizeCustomFormWithComposedModel

#if SNIPPET
            string purchaseOrderFilePath = "<purchaseOrderFilePath>";
#else
            string purchaseOrderFilePath = FormRecognizerTestEnvironment.CreatePath("Form_1.jpg");
#endif
            FormRecognizerClient recognizeClient = client.GetFormRecognizerClient();
            using var stream = new FileStream(purchaseOrderFilePath, FileMode.Open);

            RecognizeCustomFormsOperation recognizeOperation = await recognizeClient.StartRecognizeCustomFormsAsync(purchaseOrderModel.ModelId, stream);

            Response <RecognizedFormCollection> recognizeOperationResponse = await recognizeOperation.WaitForCompletionAsync();

            RecognizedFormCollection forms = recognizeOperationResponse.Value;

            // Find labeled field.
            foreach (RecognizedForm form in forms)
            {
                // Setting an arbitrary confidence level
                if (form.FormTypeConfidence.Value > 0.9)
                {
                    if (form.Fields.TryGetValue("Total", out FormField field))
                    {
                        Console.WriteLine($"Total value in the form `{form.FormType}` is `{field.ValueData.Text}`");
                    }
                }
                else
                {
                    Console.WriteLine("Unable to recognize form.");
                }
            }

            #endregion

            // Delete the models on completion to clean environment.
            await client.DeleteModelAsync(officeSuppliesModel.ModelId).ConfigureAwait(false);

            await client.DeleteModelAsync(officeEquipmentModel.ModelId).ConfigureAwait(false);

            await client.DeleteModelAsync(furnitureModel.ModelId).ConfigureAwait(false);

            await client.DeleteModelAsync(cleaningSuppliesModel.ModelId).ConfigureAwait(false);

            await client.DeleteModelAsync(purchaseOrderModel.ModelId).ConfigureAwait(false);
        }