< Summary

Class:Azure.AI.FormRecognizer.FormRecognizerClient
Assembly:Azure.AI.FormRecognizer
File(s):C:\Git\azure-sdk-for-net\sdk\formrecognizer\Azure.AI.FormRecognizer\src\FormRecognizerClient.cs
Covered lines:181
Uncovered lines:4
Coverable lines:185
Total lines:563
Line coverage:97.8% (181 of 185)
Covered branches:39
Total branches:42
Branch coverage:92.8% (39 of 42)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor(...)-100%100%
.ctor(...)-100%100%
.ctor(...)-50%100%
.ctor(...)-100%100%
.ctor(...)-100%100%
.ctor()-100%100%
StartRecognizeContent(...)-100%100%
StartRecognizeContentAsync()-100%100%
StartRecognizeContentFromUri(...)-100%100%
StartRecognizeContentFromUriAsync()-100%100%
StartRecognizeReceiptsAsync()-100%100%
StartRecognizeReceipts(...)-100%100%
StartRecognizeReceiptsFromUriAsync()-100%100%
StartRecognizeReceiptsFromUri(...)-100%100%
StartRecognizeCustomForms(...)-100%100%
StartRecognizeCustomFormsFromUri(...)-100%100%
StartRecognizeCustomFormsAsync()-100%100%
StartRecognizeCustomFormsFromUriAsync()-100%100%
DetectContentType(...)-57.14%50%

File(s)

C:\Git\azure-sdk-for-net\sdk\formrecognizer\Azure.AI.FormRecognizer\src\FormRecognizerClient.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.IO;
 6using System.Threading;
 7using System.Threading.Tasks;
 8using Azure.AI.FormRecognizer.Models;
 9using Azure.Core;
 10using Azure.Core.Pipeline;
 11
 12namespace Azure.AI.FormRecognizer
 13{
 14    /// <summary>
 15    /// The client to use to connect to the Form Recognizer Azure Cognitive Service to recognize
 16    /// information from forms and images and extract it into structured data. It provides the ability to analyze receip
 17    /// to recognize form content, and to extract fields from custom forms with models trained on custom form types.
 18    /// </summary>
 19    public class FormRecognizerClient
 20    {
 21        /// <summary>Provides communication with the Form Recognizer Azure Cognitive Service through its REST API.</summ
 22        internal readonly ServiceRestClient ServiceClient;
 23
 24        /// <summary>Provides tools for exception creation in case of failure.</summary>
 25        internal readonly ClientDiagnostics Diagnostics;
 26
 27        /// <summary>
 28        /// Initializes a new instance of the <see cref="FormRecognizerClient"/> class.
 29        /// </summary>
 30        /// <param name="endpoint">The endpoint to use for connecting to the Form Recognizer Azure Cognitive Service.</p
 31        /// <param name="credential">A credential used to authenticate to an Azure Service.</param>
 32        /// <remarks>
 33        /// Both the <paramref name="endpoint"/> URI string and the <paramref name="credential"/> <c>string</c> key
 34        /// can be found in the Azure Portal.
 35        /// </remarks>
 36        /// <seealso href="https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/formrecognizer/Azure.AI.FormRecogn
 37        public FormRecognizerClient(Uri endpoint, AzureKeyCredential credential)
 8838            : this(endpoint, credential, new FormRecognizerClientOptions())
 39        {
 7640        }
 41
 42        /// <summary>
 43        /// Initializes a new instance of the <see cref="FormRecognizerClient"/> class.
 44        /// </summary>
 45        /// <param name="endpoint">The endpoint to use for connecting to the Form Recognizer Azure Cognitive Service.</p
 46        /// <param name="credential">A credential used to authenticate to an Azure Service.</param>
 47        /// <param name="options">A set of options to apply when configuring the client.</param>
 48        /// <remarks>
 49        /// Both the <paramref name="endpoint"/> URI string and the <paramref name="credential"/> <c>string</c> key
 50        /// can be found in the Azure Portal.
 51        /// </remarks>
 52        /// <seealso href="https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/formrecognizer/Azure.AI.FormRecogn
 33253        public FormRecognizerClient(Uri endpoint, AzureKeyCredential credential, FormRecognizerClientOptions options)
 54        {
 33255            Argument.AssertNotNull(endpoint, nameof(endpoint));
 32456            Argument.AssertNotNull(credential, nameof(credential));
 30857            Argument.AssertNotNull(options, nameof(options));
 58
 30059            Diagnostics = new ClientDiagnostics(options);
 30060            var pipeline = HttpPipelineBuilder.Build(options, new AzureKeyCredentialPolicy(credential, Constants.Authori
 30061            ServiceClient = new ServiceRestClient(Diagnostics, pipeline, endpoint.AbsoluteUri);
 30062        }
 63
 64        /// <summary>
 65        /// Initializes a new instance of the <see cref="FormRecognizerClient"/> class.
 66        /// </summary>
 67        /// <param name="endpoint">The endpoint to use for connecting to the Form Recognizer Azure Cognitive Service.</p
 68        /// <param name="credential">A credential used to authenticate to an Azure Service.</param>
 69        /// <remarks>
 70        /// The <paramref name="endpoint"/> URI string can be found in the Azure Portal.
 71        /// </remarks>
 72        /// <seealso href="https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/formrecognizer/Azure.AI.FormRecogn
 73        public FormRecognizerClient(Uri endpoint, TokenCredential credential)
 874            : this(endpoint, credential, new FormRecognizerClientOptions())
 75        {
 076        }
 77
 78        /// <summary>
 79        /// Initializes a new instance of the <see cref="FormRecognizerClient"/> class.
 80        /// </summary>
 81        /// <param name="endpoint">The endpoint to use for connecting to the Form Recognizer Azure Cognitive Service.</p
 82        /// <param name="credential">A credential used to authenticate to an Azure Service.</param>
 83        /// <param name="options">A set of options to apply when configuring the client.</param>
 84        /// <remarks>
 85        /// The <paramref name="endpoint"/> URI string can be found in the Azure Portal.
 86        /// </remarks>
 87        /// <seealso href="https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/formrecognizer/Azure.AI.FormRecogn
 2888        public FormRecognizerClient(Uri endpoint, TokenCredential credential, FormRecognizerClientOptions options)
 89        {
 2890            Argument.AssertNotNull(endpoint, nameof(endpoint));
 2091            Argument.AssertNotNull(credential, nameof(credential));
 1292            Argument.AssertNotNull(options, nameof(options));
 93
 494            Diagnostics = new ClientDiagnostics(options);
 495            var pipeline = HttpPipelineBuilder.Build(options, new BearerTokenAuthenticationPolicy(credential, Constants.
 496            ServiceClient = new ServiceRestClient(Diagnostics, pipeline, endpoint.AbsoluteUri);
 497        }
 98
 99        /// <summary>
 100        /// Initializes a new instance of the <see cref="FormRecognizerClient"/> class.
 101        /// </summary>
 102        /// <param name="diagnostics">Provides tools for exception creation in case of failure.</param>
 103        /// <param name="serviceClient">Provides communication with the Form Recognizer Azure Cognitive Service through 
 4104        internal FormRecognizerClient(ClientDiagnostics diagnostics, ServiceRestClient serviceClient)
 105        {
 4106            Diagnostics = diagnostics;
 4107            ServiceClient = serviceClient;
 4108        }
 109
 110        /// <summary>
 111        /// Initializes a new instance of the <see cref="FormRecognizerClient"/> class.
 112        /// </summary>
 272113        protected FormRecognizerClient()
 114        {
 272115        }
 116
 117        #region Content
 118
 119        /// <summary>
 120        /// Recognizes layout elements from one or more passed-in forms.
 121        /// </summary>
 122        /// <param name="form">The stream containing one or more forms to recognize elements from.</param>
 123        /// <param name="recognizeContentOptions">A set of options available for configuring the recognize request.</par
 124        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 125        /// <returns>A <see cref="RecognizeContentOperation"/> to wait on this long-running operation.  Its <see cref="R
 126        /// completion will contain layout elements extracted from the form.</returns>
 127        public virtual RecognizeContentOperation StartRecognizeContent(Stream form, RecognizeContentOptions recognizeCon
 128        {
 24129            Argument.AssertNotNull(form, nameof(form));
 130
 22131            recognizeContentOptions ??= new RecognizeContentOptions();
 132
 22133            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 22134            scope.Start();
 135
 136            try
 137            {
 22138                FormContentType contentType = recognizeContentOptions.ContentType ?? DetectContentType(form, nameof(form
 139
 22140                Response response = ServiceClient.AnalyzeLayoutAsync(contentType, form, cancellationToken);
 16141                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 142
 16143                return new RecognizeContentOperation(ServiceClient, Diagnostics, location);
 144            }
 6145            catch (Exception e)
 146            {
 6147                scope.Failed(e);
 6148                throw;
 149            }
 16150        }
 151
 152        /// <summary>
 153        /// Recognizes layout elements from one or more passed-in forms.
 154        /// </summary>
 155        /// <param name="form">The stream containing one or more forms to recognize elements from.</param>
 156        /// <param name="recognizeContentOptions">A set of options available for configuring the recognize request.</par
 157        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 158        /// <returns>A <see cref="RecognizeContentOperation"/> to wait on this long-running operation.  Its <see cref="R
 159        /// completion will contain layout elements extracted from the form.</returns>
 160        public virtual async Task<RecognizeContentOperation> StartRecognizeContentAsync(Stream form, RecognizeContentOpt
 161        {
 24162            Argument.AssertNotNull(form, nameof(form));
 163
 22164            recognizeContentOptions ??= new RecognizeContentOptions();
 165
 22166            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 22167            scope.Start();
 168
 169            try
 170            {
 22171                FormContentType contentType = recognizeContentOptions.ContentType ?? DetectContentType(form, nameof(form
 172
 22173                Response response = await ServiceClient.AnalyzeLayoutAsyncAsync(contentType, form, cancellationToken).Co
 16174                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 175
 16176                return new RecognizeContentOperation(ServiceClient, Diagnostics, location);
 177            }
 6178            catch (Exception e)
 179            {
 6180                scope.Failed(e);
 6181                throw;
 182            }
 16183        }
 184
 185        /// <summary>
 186        /// Recognizes layout elements from one or more passed-in forms.
 187        /// </summary>
 188        /// <param name="formUri">The absolute URI of the remote file to recognize elements from.</param>
 189        /// <param name="recognizeContentOptions">A set of options available for configuring the recognize request.</par
 190        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 191        /// <returns>A <see cref="RecognizeContentOperation"/> to wait on this long-running operation.  Its <see cref="R
 192        /// completion will contain layout elements extracted from the form.</returns>
 193        public virtual RecognizeContentOperation StartRecognizeContentFromUri(Uri formUri, RecognizeContentOptions recog
 194        {
 18195            Argument.AssertNotNull(formUri, nameof(formUri));
 196
 16197            recognizeContentOptions ??= new RecognizeContentOptions();
 198
 16199            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 16200            scope.Start();
 201
 202            try
 203            {
 16204                SourcePath sourcePath = new SourcePath() { Source = formUri.AbsoluteUri };
 16205                Response response = ServiceClient.AnalyzeLayoutAsync(sourcePath, cancellationToken);
 10206                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 207
 10208                return new RecognizeContentOperation(ServiceClient, Diagnostics, location);
 209            }
 6210            catch (Exception e)
 211            {
 6212                scope.Failed(e);
 6213                throw;
 214            }
 10215        }
 216
 217        /// <summary>
 218        /// Recognizes layout elements from one or more passed-in forms.
 219        /// </summary>
 220        /// <param name="formUri">The absolute URI of the remote file to recognize elements from.</param>
 221        /// <param name="recognizeContentOptions">A set of options available for configuring the recognize request.</par
 222        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 223        /// <returns>A <see cref="RecognizeContentOperation"/> to wait on this long-running operation.  Its <see cref="R
 224        /// completion will contain layout elements extracted from the form.</returns>
 225        public virtual async Task<RecognizeContentOperation> StartRecognizeContentFromUriAsync(Uri formUri, RecognizeCon
 226        {
 22227            Argument.AssertNotNull(formUri, nameof(formUri));
 228
 20229            recognizeContentOptions ??= new RecognizeContentOptions();
 230
 20231            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 20232            scope.Start();
 233
 234            try
 235            {
 20236                SourcePath sourcePath = new SourcePath() { Source = formUri.AbsoluteUri };
 20237                Response response = await ServiceClient.AnalyzeLayoutAsyncAsync(sourcePath, cancellationToken).Configure
 14238                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 239
 14240                return new RecognizeContentOperation(ServiceClient, Diagnostics, location);
 241            }
 6242            catch (Exception e)
 243            {
 6244                scope.Failed(e);
 6245                throw;
 246            }
 14247        }
 248
 249        #endregion
 250
 251        #region Receipts
 252
 253        /// <summary>
 254        /// Recognizes values from one or more receipts.
 255        /// </summary>
 256        /// <param name="receipt">The stream containing the one or more receipts to recognize values from.</param>
 257        /// <param name="recognizeReceiptsOptions">A set of options available for configuring the recognize request.</pa
 258        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 259        /// <returns>A <see cref="RecognizeReceiptsOperation"/> to wait on this long-running operation.  Its <see cref="
 260        /// completion will contain the extracted receipt.</returns>
 261        public virtual async Task<RecognizeReceiptsOperation> StartRecognizeReceiptsAsync(Stream receipt, RecognizeRecei
 262        {
 20263            Argument.AssertNotNull(receipt, nameof(receipt));
 264
 18265            recognizeReceiptsOptions ??= new RecognizeReceiptsOptions();
 266
 18267            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 18268            scope.Start();
 269
 270            try
 271            {
 18272                FormContentType contentType = recognizeReceiptsOptions.ContentType ?? DetectContentType(receipt, nameof(
 273
 18274                Response response = await ServiceClient.AnalyzeReceiptAsyncAsync(contentType, receipt, includeTextDetail
 14275                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 276
 14277                return new RecognizeReceiptsOperation(ServiceClient, Diagnostics, location);
 278            }
 4279            catch (Exception e)
 280            {
 4281                scope.Failed(e);
 4282                throw;
 283            }
 14284        }
 285
 286        /// <summary>
 287        /// Recognizes values from one or more receipts.
 288        /// </summary>
 289        /// <param name="receipt">The stream containing the one or more receipts to recognize values from.</param>
 290        /// <param name="recognizeReceiptsOptions">A set of options available for configuring the recognize request.</pa
 291        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 292        /// <returns>A <see cref="RecognizeReceiptsOperation"/> to wait on this long-running operation.  Its <see cref="
 293        /// completion will contain the extracted receipt.</returns>
 294        public virtual RecognizeReceiptsOperation StartRecognizeReceipts(Stream receipt, RecognizeReceiptsOptions recogn
 295        {
 20296            Argument.AssertNotNull(receipt, nameof(receipt));
 297
 18298            recognizeReceiptsOptions ??= new RecognizeReceiptsOptions();
 299
 18300            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 18301            scope.Start();
 302
 303            try
 304            {
 18305                FormContentType contentType = recognizeReceiptsOptions.ContentType ?? DetectContentType(receipt, nameof(
 306
 18307                Response response = ServiceClient.AnalyzeReceiptAsync(contentType, receipt, includeTextDetails: recogniz
 14308                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 309
 14310                return new RecognizeReceiptsOperation(ServiceClient, Diagnostics, location);
 311            }
 4312            catch (Exception e)
 313            {
 4314                scope.Failed(e);
 4315                throw;
 316            }
 14317        }
 318
 319        /// <summary>
 320        /// Recognizes values from one or more receipts.
 321        /// </summary>
 322        /// <param name="receiptUri">The absolute URI of the remote file to recognize values from.</param>
 323        /// <param name="recognizeReceiptsOptions">A set of options available for configuring the recognize request.</pa
 324        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 325        /// <returns>A <see cref="RecognizeReceiptsOperation"/> to wait on this long-running operation.  Its <see cref="
 326        /// completion will contain the extracted receipt.</returns>
 327        public virtual async Task<RecognizeReceiptsOperation> StartRecognizeReceiptsFromUriAsync(Uri receiptUri, Recogni
 328        {
 20329            Argument.AssertNotNull(receiptUri, nameof(receiptUri));
 330
 18331            recognizeReceiptsOptions ??= new RecognizeReceiptsOptions();
 332
 18333            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 18334            scope.Start();
 335
 336            try
 337            {
 18338                SourcePath sourcePath = new SourcePath() { Source = receiptUri.AbsoluteUri };
 18339                Response response = await ServiceClient.AnalyzeReceiptAsyncAsync(includeTextDetails: recognizeReceiptsOp
 14340                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 341
 14342                return new RecognizeReceiptsOperation(ServiceClient, Diagnostics, location);
 343            }
 4344            catch (Exception e)
 345            {
 4346                scope.Failed(e);
 4347                throw;
 348            }
 14349        }
 350
 351        /// <summary>
 352        /// Recognizes values from one or more receipts.
 353        /// </summary>
 354        /// <param name="receiptUri">The absolute URI of the remote file to recognize values from.</param>
 355        /// <param name="recognizeReceiptsOptions">A set of options available for configuring the recognize request.</pa
 356        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 357        /// <returns>A <see cref="RecognizeReceiptsOperation"/> to wait on this long-running operation.  Its <see cref="
 358        /// completion will contain the extracted receipt.</returns>
 359        public virtual RecognizeReceiptsOperation StartRecognizeReceiptsFromUri(Uri receiptUri, RecognizeReceiptsOptions
 360        {
 16361            Argument.AssertNotNull(receiptUri, nameof(receiptUri));
 362
 14363            recognizeReceiptsOptions ??= new RecognizeReceiptsOptions();
 364
 14365            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 14366            scope.Start();
 367
 368            try
 369            {
 14370                SourcePath sourcePath = new SourcePath() { Source = receiptUri.AbsoluteUri };
 14371                Response response = ServiceClient.AnalyzeReceiptAsync(includeTextDetails: recognizeReceiptsOptions.Inclu
 10372                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 373
 10374                return new RecognizeReceiptsOperation(ServiceClient, Diagnostics, location);
 375            }
 4376            catch (Exception e)
 377            {
 4378                scope.Failed(e);
 4379                throw;
 380            }
 10381        }
 382
 383        #endregion
 384
 385        #region Custom Forms
 386
 387        /// <summary>
 388        /// Recognizes pages from one or more forms, using a model trained with custom forms.
 389        /// </summary>
 390        /// <param name="modelId">The ID of the model to use for recognizing form values.</param>
 391        /// <param name="form">The stream containing one or more forms to recognize elements from.</param>
 392        /// <param name="recognizeCustomFormsOptions">A set of options available for configuring the recognize request.<
 393        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 394        /// <returns>A <see cref="RecognizeCustomFormsOperation"/> to wait on this long-running operation.  Its <see cre
 395        /// completion will contain recognized pages from the input document.</returns>
 396        public virtual RecognizeCustomFormsOperation StartRecognizeCustomForms(string modelId, Stream form, RecognizeCus
 397        {
 38398            Argument.AssertNotNullOrEmpty(modelId, nameof(modelId));
 34399            Argument.AssertNotNull(form, nameof(form));
 400
 32401            recognizeCustomFormsOptions ??= new RecognizeCustomFormsOptions();
 402
 32403            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 32404            scope.Start();
 405
 406            try
 407            {
 32408                Guid guid = ClientCommon.ValidateModelId(modelId, nameof(modelId));
 32409                FormContentType contentType = recognizeCustomFormsOptions.ContentType ?? DetectContentType(form, nameof(
 410
 32411                Response response = ServiceClient.AnalyzeWithCustomModel(guid, contentType, form, includeTextDetails: re
 30412                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 413
 30414                return new RecognizeCustomFormsOperation(ServiceClient, Diagnostics, location);
 415            }
 2416            catch (Exception e)
 417            {
 2418                scope.Failed(e);
 2419                throw;
 420            }
 30421        }
 422
 423        /// <summary>
 424        /// Recognizes pages from one or more forms, using a model trained with custom forms.
 425        /// </summary>
 426        /// <param name="modelId">The ID of the model to use for recognizing form values.</param>
 427        /// <param name="formUri">The absolute URI of the remote file to recognize elements from.</param>
 428        /// <param name="recognizeCustomFormsOptions">A set of options available for configuring the recognize request.<
 429        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 430        /// <returns>A <see cref="RecognizeCustomFormsOperation"/> to wait on this long-running operation.  Its <see cre
 431        /// completion will contain recognized pages from the input document.</returns>
 432        public virtual RecognizeCustomFormsOperation StartRecognizeCustomFormsFromUri(string modelId, Uri formUri, Recog
 433        {
 26434            Argument.AssertNotNullOrEmpty(modelId, nameof(modelId));
 22435            Argument.AssertNotNull(formUri, nameof(formUri));
 436
 20437            recognizeCustomFormsOptions ??= new RecognizeCustomFormsOptions();
 438
 20439            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 20440            scope.Start();
 441
 442            try
 443            {
 20444                Guid guid = ClientCommon.ValidateModelId(modelId, nameof(modelId));
 445
 20446                SourcePath sourcePath = new SourcePath() { Source = formUri.AbsoluteUri };
 20447                Response response = ServiceClient.AnalyzeWithCustomModel(guid, includeTextDetails: recognizeCustomFormsO
 18448                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 449
 18450                return new RecognizeCustomFormsOperation(ServiceClient, Diagnostics, location);
 451            }
 2452            catch (Exception e)
 453            {
 2454                scope.Failed(e);
 2455                throw;
 456            }
 18457        }
 458
 459        /// <summary>
 460        /// Recognizes pages from one or more forms, using a model trained with custom forms.
 461        /// </summary>
 462        /// <param name="modelId">The ID of the model to use for recognizing form values.</param>
 463        /// <param name="form">The stream containing one or more forms to recognize elements from.</param>
 464        /// <param name="recognizeCustomFormsOptions">A set of options available for configuring the recognize request.<
 465        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 466        /// <returns>A <see cref="RecognizeCustomFormsOperation"/> to wait on this long-running operation.  Its <see cre
 467        /// completion will contain recognized pages from the input document.</returns>
 468        public virtual async Task<RecognizeCustomFormsOperation> StartRecognizeCustomFormsAsync(string modelId, Stream f
 469        {
 46470            Argument.AssertNotNullOrEmpty(modelId, nameof(modelId));
 42471            Argument.AssertNotNull(form, nameof(form));
 472
 40473            recognizeCustomFormsOptions ??= new RecognizeCustomFormsOptions();
 474
 40475            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 40476            scope.Start();
 477
 478            try
 479            {
 40480                Guid guid = ClientCommon.ValidateModelId(modelId, nameof(modelId));
 36481                FormContentType contentType = recognizeCustomFormsOptions.ContentType ?? DetectContentType(form, nameof(
 482
 36483                Response response = await ServiceClient.AnalyzeWithCustomModelAsync(guid, contentType, form, includeText
 34484                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 485
 34486                return new RecognizeCustomFormsOperation(ServiceClient, Diagnostics, location);
 487            }
 6488            catch (Exception e)
 489            {
 6490                scope.Failed(e);
 6491                throw;
 492            }
 34493        }
 494
 495        /// <summary>
 496        /// Recognizes pages from one or more forms, using a model trained with custom forms.
 497        /// </summary>
 498        /// <param name="modelId">The ID of the model to use for recognizing form values.</param>
 499        /// <param name="formUri">The absolute URI of the remote file to recognize elements from.</param>
 500        /// <param name="recognizeCustomFormsOptions">A set of options available for configuring the recognize request.<
 501        /// <param name="cancellationToken">A <see cref="CancellationToken"/> controlling the request lifetime.</param>
 502        /// <returns>A <see cref="RecognizeCustomFormsOperation"/> to wait on this long-running operation.  Its <see cre
 503        /// completion will contain recognized pages from the input document.</returns>
 504        public virtual async Task<RecognizeCustomFormsOperation> StartRecognizeCustomFormsFromUriAsync(string modelId, U
 505        {
 30506            Argument.AssertNotNullOrEmpty(modelId, nameof(modelId));
 26507            Argument.AssertNotNull(formUri, nameof(formUri));
 508
 24509            recognizeCustomFormsOptions ??= new RecognizeCustomFormsOptions();
 510
 24511            using DiagnosticScope scope = Diagnostics.CreateScope($"{nameof(FormRecognizerClient)}.{nameof(StartRecogniz
 24512            scope.Start();
 513
 514            try
 515            {
 24516                Guid guid = ClientCommon.ValidateModelId(modelId, nameof(modelId));
 517
 20518                SourcePath sourcePath = new SourcePath() { Source = formUri.AbsoluteUri };
 20519                Response response = await ServiceClient.AnalyzeWithCustomModelAsync(guid, includeTextDetails: recognizeC
 18520                string location = ClientCommon.GetResponseHeader(response.Headers, Constants.OperationLocationHeader);
 521
 18522                return new RecognizeCustomFormsOperation(ServiceClient, Diagnostics, location);
 523            }
 6524            catch (Exception e)
 525            {
 6526                scope.Failed(e);
 6527                throw;
 528            }
 18529        }
 530
 531        #endregion
 532
 533        /// <summary>
 534        /// Used as part of argument validation. Detects the <see cref="FormContentType"/> of a stream and
 535        /// throws an <see cref="ArgumentException"/> in case of failure.
 536        /// </summary>
 537        /// <param name="stream">The stream to which the content type detection attempt will be performed.</param>
 538        /// <param name="paramName">The original parameter name of the <paramref name="stream"/>. Used to create excepti
 539        /// <returns>The detected <see cref="FormContentType"/>.</returns>
 540        /// <exception cref="ArgumentException">Thrown when detection fails or cannot be performed.</exception>
 541        private static FormContentType DetectContentType(Stream stream, string paramName)
 542        {
 543            FormContentType contentType;
 544
 124545            if (!stream.CanSeek)
 546            {
 0547                throw new ArgumentException($"Content type cannot be detected because stream is not seekable. It can be 
 548            }
 549
 124550            if (!stream.CanRead)
 551            {
 0552                throw new ArgumentException($"Content type cannot be detected because stream is not readable. It can be 
 553            }
 554
 124555            if (!stream.TryGetContentType(out contentType))
 556            {
 0557                throw new ArgumentException($"Content type of the stream could not be detected. It can be manually set i
 558            }
 559
 124560            return contentType;
 561        }
 562    }
 563}