azure-ai-formrecognizer 3.3.3
Microsoft Azure Form Recognizer Client Library for Python
License: MIT License
Requires Python: >=3.8
Keywords: azure, form recognizer, cognitive services, document analyzer, document analysis, applied ai, azure sdk

# Azure Form Recognizer client library for Python

Azure Document Intelligence ([previously known as Form Recognizer][service-rename]) is a cloud service that uses machine learning to analyze text and structured data from your documents. It includes the following main features:

- Layout - Extract content and structure (ex. words, selection marks, tables) from documents.
- Document - Analyze key-value pairs in addition to general layout from documents.
- Read - Read page information from documents.
- Prebuilt - Extract common field values from select document types (ex. receipts, invoices, business cards, ID documents, U.S. W-2 tax documents, among others) using prebuilt models.
- Custom - Build custom models from your own data to extract tailored field values in addition to general layout from documents.
- Classifiers - Build custom classification models that combine layout and language features to accurately detect and identify documents you process within your application.
- Add-on capabilities - Extract barcodes/QR codes, formulas, font/style, etc. or enable high resolution mode for large documents with optional parameters.

[Source code][python-fr-src]
| [Package (PyPI)][python-fr-pypi]
| [Package (Conda)](https://anaconda.org/microsoft/azure-ai-formrecognizer/)
| [API reference documentation][python-fr-ref-docs]
| [Product documentation][python-fr-product-docs]
| [Samples][python-fr-samples]


## _Disclaimer_

_This package supports the following service API versions: 2.0, 2.1, 2022-08-31 and 2023-07-31. Service API version 2023-10-31-preview and later are supported in package `azure-ai-documentintelligence`. Please refer this [doc][fr_to_di_migration_guideline] for migration details._


## Getting started

### Prerequisites

* Python 3.8 or later is required to use this package.
* You must have an [Azure subscription][azure_subscription] and a
[Cognitive Services or Form Recognizer resource][FR_or_CS_resource] to use this package.

### Install the package

Install the Azure Form Recognizer client library for Python with [pip][pip]:

```bash
pip install azure-ai-formrecognizer
```

> Note: This version of the client library defaults to the `2023-07-31` version of the service.

This table shows the relationship between SDK versions and supported API versions of the service:

|SDK version|Supported API version of service
|-|-
|3.3.X - Latest GA release | 2.0, 2.1, 2022-08-31, 2023-07-31 (default)
|3.2.X | 2.0, 2.1, 2022-08-31 (default)
|3.1.X| 2.0, 2.1 (default)
|3.0.0| 2.0

> Note: Starting with version `3.2.X`, a new set of clients were introduced to leverage the newest features
> of the Document Intelligence service. Please see the [Migration Guide][migration-guide] for detailed instructions on how to update application
> code from client library version `3.1.X` or lower to the latest version. Additionally, see the [Changelog][changelog] for more detailed information.
> The below table describes the relationship of each client and its supported API version(s):

|API version|Supported clients
|-|-
|2023-07-31 | DocumentAnalysisClient and DocumentModelAdministrationClient
|2022-08-31 | DocumentAnalysisClient and DocumentModelAdministrationClient
|2.1 | FormRecognizerClient and FormTrainingClient
|2.0 | FormRecognizerClient and FormTrainingClient

#### Create a Cognitive Services or Form Recognizer resource

Document Intelligence supports both [multi-service and single-service access][cognitive_resource_portal]. Create a Cognitive Services resource if you plan to access multiple cognitive services under a single endpoint/key. For Document Intelligence access only, create a Form Recognizer resource. Please note that you will need a single-service resource if you intend to use [Azure Active Directory authentication](#create-the-client-with-an-azure-active-directory-credential).

You can create either resource using: 

* Option 1: [Azure Portal][cognitive_resource_portal].
* Option 2: [Azure CLI][cognitive_resource_cli].

Below is an example of how you can create a Form Recognizer resource using the CLI:

```PowerShell
# Create a new resource group to hold the Form Recognizer resource
# if using an existing resource group, skip this step
az group create --name <your-resource-name> --location <location>
```

```PowerShell
# Create form recognizer
az cognitiveservices account create \
    --name <your-resource-name> \
    --resource-group <your-resource-group-name> \
    --kind FormRecognizer \
    --sku <sku> \
    --location <location> \
    --yes
```

For more information about creating the resource or how to get the location and sku information see [here][cognitive_resource_cli].

### Authenticate the client

In order to interact with the Document Intelligence service, you will need to create an instance of a client.
An **endpoint** and **credential** are necessary to instantiate the client object.

#### Get the endpoint

You can find the endpoint for your Form Recognizer resource using the
[Azure Portal][azure_portal_get_endpoint]
or [Azure CLI][azure_cli_endpoint_lookup]:

```bash
# Get the endpoint for the Form Recognizer resource
az cognitiveservices account show --name "resource-name" --resource-group "resource-group-name" --query "properties.endpoint"
```

Either a regional endpoint or a custom subdomain can be used for authentication. They are formatted as follows:

```
Regional endpoint: https://<region>.api.cognitive.microsoft.com/
Custom subdomain: https://<resource-name>.cognitiveservices.azure.com/
```

A regional endpoint is the same for every resource in a region. A complete list of supported regional endpoints can be consulted [here][regional_endpoints]. Please note that regional endpoints do not support AAD authentication.

A custom subdomain, on the other hand, is a name that is unique to the Form Recognizer resource. They can only be used by [single-service resources][cognitive_resource_portal].

#### Get the API key

The API key can be found in the [Azure Portal][azure_portal] or by running the following Azure CLI command:

```bash
az cognitiveservices account keys list --name "<resource-name>" --resource-group "<resource-group-name>"
```

#### Create the client with AzureKeyCredential

To use an [API key][cognitive_authentication_api_key] as the `credential` parameter,
pass the key as a string into an instance of [AzureKeyCredential][azure-key-credential].

```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.formrecognizer import DocumentAnalysisClient

endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/"
credential = AzureKeyCredential("<api_key>")
document_analysis_client = DocumentAnalysisClient(endpoint, credential)
```

#### Create the client with an Azure Active Directory credential

`AzureKeyCredential` authentication is used in the examples in this getting started guide, but you can also
authenticate with Azure Active Directory using the [azure-identity][azure_identity] library.
Note that regional endpoints do not support AAD authentication. Create a [custom subdomain][custom_subdomain]
name for your resource in order to use this type of authentication.

To use the [DefaultAzureCredential][default_azure_credential] type shown below, or other credential types provided
with the Azure SDK, please install the `azure-identity` package:

```pip install azure-identity```

You will also need to [register a new AAD application and grant access][register_aad_app] to Document Intelligence by assigning the `"Cognitive Services User"` role to your service principal.

Once completed, set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables:
`AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_SECRET`.

<!-- SNIPPET:sample_authentication.create_da_client_with_aad -->

```python
"""DefaultAzureCredential will use the values from these environment
variables: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET
"""
from azure.ai.formrecognizer import DocumentAnalysisClient
from azure.identity import DefaultAzureCredential

endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
credential = DefaultAzureCredential()

document_analysis_client = DocumentAnalysisClient(endpoint, credential)
```

<!-- END SNIPPET -->

## Key concepts

### DocumentAnalysisClient

`DocumentAnalysisClient` provides operations for analyzing input documents using prebuilt and custom models through the `begin_analyze_document` and `begin_analyze_document_from_url` APIs.
Use the `model_id` parameter to select the type of model for analysis. See a full list of supported models [here][fr-models]. 
The `DocumentAnalysisClient` also provides operations for classifying documents through the `begin_classify_document` and `begin_classify_document_from_url` APIs. 
Custom classification models can classify each page in an input file to identify the document(s) within and can also identify multiple documents or multiple instances of a single document within an input file.

Sample code snippets are provided to illustrate using a DocumentAnalysisClient [here](#examples "Examples").
More information about analyzing documents, including supported features, locales, and document types can be found in the [service documentation][fr-models].

### DocumentModelAdministrationClient

`DocumentModelAdministrationClient` provides operations for:

- Building custom models to analyze specific fields you specify by labeling your custom documents. A `DocumentModelDetails` is returned indicating the document type(s) the model can analyze, as well as the estimated confidence for each field. See the [service documentation][fr-build-model] for a more detailed explanation.
- Creating a composed model from a collection of existing models.
- Managing models created in your account.
- Listing operations or getting a specific model operation created within the last 24 hours.
- Copying a custom model from one Form Recognizer resource to another.
- Build and manage a custom classification model to classify the documents you process within your application.

Please note that models can also be built using a graphical user interface such as [Document Intelligence Studio][fr-studio].

Sample code snippets are provided to illustrate using a DocumentModelAdministrationClient [here](#examples "Examples").

### Long-running operations

Long-running operations are operations which 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.

Methods that analyze documents, build models, or copy/compose models are modeled as long-running operations.
The client exposes a `begin_<method-name>` method that returns an `LROPoller` or `AsyncLROPoller`. Callers should wait
for the operation to complete by calling `result()` on the poller object returned from the `begin_<method-name>` method.
Sample code snippets are provided to illustrate using long-running operations [below](#examples "Examples").

## Examples

The following section provides several code snippets covering some of the most common Document Intelligence tasks, including:

* [Extract Layout](#extract-layout "Extract Layout")
* [Using the General Document Model](#using-the-general-document-model "Using the General Document Model")
* [Using Prebuilt Models](#using-prebuilt-models "Using Prebuilt Models")
* [Build a Custom Model](#build-a-custom-model "Build a custom model")
* [Analyze Documents Using a Custom Model](#analyze-documents-using-a-custom-model "Analyze Documents Using a Custom Model")
* [Manage Your Models](#manage-your-models "Manage Your Models")
* [Classify Documents][classify_sample]
* [Add-on capabilities](#add-on-capabilities "Add-on Capabilities")

### Extract Layout

Extract text, selection marks, text styles, and table structures, along with their bounding region coordinates, from documents.

```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.formrecognizer import DocumentAnalysisClient

endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
key = os.environ["AZURE_FORM_RECOGNIZER_KEY"]

document_analysis_client = DocumentAnalysisClient(
    endpoint=endpoint, credential=AzureKeyCredential(key)
)
with open(path_to_sample_documents, "rb") as f:
    poller = document_analysis_client.begin_analyze_document(
        "prebuilt-layout", document=f
    )
result = poller.result()

for idx, style in enumerate(result.styles):
    print(
        "Document contains {} content".format(
            "handwritten" if style.is_handwritten else "no handwritten"
        )
    )

for page in result.pages:
    print("----Analyzing layout from page #{}----".format(page.page_number))
    print(
        "Page has width: {} and height: {}, measured with unit: {}".format(
            page.width, page.height, page.unit
        )
    )

    for line_idx, line in enumerate(page.lines):
        words = line.get_words()
        print(
            "...Line # {} has word count {} and text '{}' within bounding polygon '{}'".format(
                line_idx,
                len(words),
                line.content,
                line.polygon,
            )
        )

        for word in words:
            print(
                "......Word '{}' has a confidence of {}".format(
                    word.content, word.confidence
                )
            )

    for selection_mark in page.selection_marks:
        print(
            "...Selection mark is '{}' within bounding polygon '{}' and has a confidence of {}".format(
                selection_mark.state,
                selection_mark.polygon,
                selection_mark.confidence,
            )
        )

for table_idx, table in enumerate(result.tables):
    print(
        "Table # {} has {} rows and {} columns".format(
            table_idx, table.row_count, table.column_count
        )
    )
    for region in table.bounding_regions:
        print(
            "Table # {} location on page: {} is {}".format(
                table_idx,
                region.page_number,
                region.polygon,
            )
        )
    for cell in table.cells:
        print(
            "...Cell[{}][{}] has content '{}'".format(
                cell.row_index,
                cell.column_index,
                cell.content,
            )
        )
        for region in cell.bounding_regions:
            print(
                "...content on page {} is within bounding polygon '{}'".format(
                    region.page_number,
                    region.polygon,
                )
            )

print("----------------------------------------")
```

### Using the General Document Model

Analyze key-value pairs, tables, styles, and selection marks from documents using the general document model provided by the Document Intelligence service.
Select the General Document Model by passing `model_id="prebuilt-document"` into the `begin_analyze_document` method:

```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.formrecognizer import DocumentAnalysisClient

endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
key = os.environ["AZURE_FORM_RECOGNIZER_KEY"]

document_analysis_client = DocumentAnalysisClient(
    endpoint=endpoint, credential=AzureKeyCredential(key)
)
with open(path_to_sample_documents, "rb") as f:
    poller = document_analysis_client.begin_analyze_document(
        "prebuilt-document", document=f
    )
result = poller.result()

for style in result.styles:
    if style.is_handwritten:
        print("Document contains handwritten content: ")
        print(",".join([result.content[span.offset:span.offset + span.length] for span in style.spans]))

print("----Key-value pairs found in document----")
for kv_pair in result.key_value_pairs:
    if kv_pair.key:
        print(
                "Key '{}' found within '{}' bounding regions".format(
                    kv_pair.key.content,
                    kv_pair.key.bounding_regions,
                )
            )
    if kv_pair.value:
        print(
                "Value '{}' found within '{}' bounding regions\n".format(
                    kv_pair.value.content,
                    kv_pair.value.bounding_regions,
                )
            )

for page in result.pages:
    print("----Analyzing document from page #{}----".format(page.page_number))
    print(
        "Page has width: {} and height: {}, measured with unit: {}".format(
            page.width, page.height, page.unit
        )
    )

    for line_idx, line in enumerate(page.lines):
        words = line.get_words()
        print(
            "...Line # {} has {} words and text '{}' within bounding polygon '{}'".format(
                line_idx,
                len(words),
                line.content,
                line.polygon,
            )
        )

        for word in words:
            print(
                "......Word '{}' has a confidence of {}".format(
                    word.content, word.confidence
                )
            )

    for selection_mark in page.selection_marks:
        print(
            "...Selection mark is '{}' within bounding polygon '{}' and has a confidence of {}".format(
                selection_mark.state,
                selection_mark.polygon,
                selection_mark.confidence,
            )
        )

for table_idx, table in enumerate(result.tables):
    print(
        "Table # {} has {} rows and {} columns".format(
            table_idx, table.row_count, table.column_count
        )
    )
    for region in table.bounding_regions:
        print(
            "Table # {} location on page: {} is {}".format(
                table_idx,
                region.page_number,
                region.polygon,
            )
        )
    for cell in table.cells:
        print(
            "...Cell[{}][{}] has content '{}'".format(
                cell.row_index,
                cell.column_index,
                cell.content,
            )
        )
        for region in cell.bounding_regions:
            print(
                "...content on page {} is within bounding polygon '{}'\n".format(
                    region.page_number,
                    region.polygon,
                )
            )
print("----------------------------------------")
```

- Read more about the features provided by the `prebuilt-document` model [here][service_prebuilt_document].

### Using Prebuilt Models

Extract fields from select document types such as receipts, invoices, business cards, identity documents, and U.S. W-2 tax documents using prebuilt models provided by the Document Intelligence service.

For example, to analyze fields from a sales receipt, use the prebuilt receipt model provided by passing `model_id="prebuilt-receipt"` into the `begin_analyze_document` method:

<!-- SNIPPET:sample_analyze_receipts.analyze_receipts -->

```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.formrecognizer import DocumentAnalysisClient

endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
key = os.environ["AZURE_FORM_RECOGNIZER_KEY"]

document_analysis_client = DocumentAnalysisClient(
    endpoint=endpoint, credential=AzureKeyCredential(key)
)
with open(path_to_sample_documents, "rb") as f:
    poller = document_analysis_client.begin_analyze_document(
        "prebuilt-receipt", document=f, locale="en-US"
    )
receipts = poller.result()

for idx, receipt in enumerate(receipts.documents):
    print(f"--------Analysis of receipt #{idx + 1}--------")
    print(f"Receipt type: {receipt.doc_type if receipt.doc_type else 'N/A'}")
    merchant_name = receipt.fields.get("MerchantName")
    if merchant_name:
        print(
            f"Merchant Name: {merchant_name.value} has confidence: "
            f"{merchant_name.confidence}"
        )
    transaction_date = receipt.fields.get("TransactionDate")
    if transaction_date:
        print(
            f"Transaction Date: {transaction_date.value} has confidence: "
            f"{transaction_date.confidence}"
        )
    if receipt.fields.get("Items"):
        print("Receipt items:")
        for idx, item in enumerate(receipt.fields.get("Items").value):
            print(f"...Item #{idx + 1}")
            item_description = item.value.get("Description")
            if item_description:
                print(
                    f"......Item Description: {item_description.value} has confidence: "
                    f"{item_description.confidence}"
                )
            item_quantity = item.value.get("Quantity")
            if item_quantity:
                print(
                    f"......Item Quantity: {item_quantity.value} has confidence: "
                    f"{item_quantity.confidence}"
                )
            item_price = item.value.get("Price")
            if item_price:
                print(
                    f"......Individual Item Price: {item_price.value} has confidence: "
                    f"{item_price.confidence}"
                )
            item_total_price = item.value.get("TotalPrice")
            if item_total_price:
                print(
                    f"......Total Item Price: {item_total_price.value} has confidence: "
                    f"{item_total_price.confidence}"
                )
    subtotal = receipt.fields.get("Subtotal")
    if subtotal:
        print(f"Subtotal: {subtotal.value} has confidence: {subtotal.confidence}")
    tax = receipt.fields.get("TotalTax")
    if tax:
        print(f"Total tax: {tax.value} has confidence: {tax.confidence}")
    tip = receipt.fields.get("Tip")
    if tip:
        print(f"Tip: {tip.value} has confidence: {tip.confidence}")
    total = receipt.fields.get("Total")
    if total:
        print(f"Total: {total.value} has confidence: {total.confidence}")
    print("--------------------------------------")
```

<!-- END SNIPPET -->

You are not limited to receipts! There are a few prebuilt models to choose from, each of which has its own set of supported fields. See other supported prebuilt models [here][fr-models].

### Build a Custom Model

Build a custom model on your own document type. The resulting model can be used to analyze values from the types of documents it was trained on.
Provide a container SAS URL to your Azure Storage Blob container where you're storing the training documents.

More details on setting up a container and required file structure can be found in the [service documentation][fr-build-training-set].

<!-- SNIPPET:sample_build_model.build_model -->

```python
from azure.ai.formrecognizer import (
    DocumentModelAdministrationClient,
    ModelBuildMode,
)
from azure.core.credentials import AzureKeyCredential

endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
key = os.environ["AZURE_FORM_RECOGNIZER_KEY"]
container_sas_url = os.environ["CONTAINER_SAS_URL"]

document_model_admin_client = DocumentModelAdministrationClient(
    endpoint, AzureKeyCredential(key)
)
poller = document_model_admin_client.begin_build_document_model(
    ModelBuildMode.TEMPLATE,
    blob_container_url=container_sas_url,
    description="my model description",
)
model = poller.result()

print(f"Model ID: {model.model_id}")
print(f"Description: {model.description}")
print(f"Model created on: {model.created_on}")
print(f"Model expires on: {model.expires_on}")
print("Doc types the model can recognize:")
for name, doc_type in model.doc_types.items():
    print(
        f"Doc Type: '{name}' built with '{doc_type.build_mode}' mode which has the following fields:"
    )
    for field_name, field in doc_type.field_schema.items():
        print(
            f"Field: '{field_name}' has type '{field['type']}' and confidence score "
            f"{doc_type.field_confidence[field_name]}"
        )
```

<!-- END SNIPPET -->

### Analyze Documents Using a Custom Model

Analyze document fields, tables, selection marks, and more. These models are trained with your own data, so they're tailored to your documents.
For best results, you should only analyze documents of the same document type that the custom model was built with.

<!-- SNIPPET:sample_analyze_custom_documents.analyze_custom_documents -->

```python
from azure.core.credentials import AzureKeyCredential
from azure.ai.formrecognizer import DocumentAnalysisClient

endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
key = os.environ["AZURE_FORM_RECOGNIZER_KEY"]
model_id = os.getenv("CUSTOM_BUILT_MODEL_ID", custom_model_id)

document_analysis_client = DocumentAnalysisClient(
    endpoint=endpoint, credential=AzureKeyCredential(key)
)

# Make sure your document's type is included in the list of document types the custom model can analyze
with open(path_to_sample_documents, "rb") as f:
    poller = document_analysis_client.begin_analyze_document(
        model_id=model_id, document=f
    )
result = poller.result()

for idx, document in enumerate(result.documents):
    print(f"--------Analyzing document #{idx + 1}--------")
    print(f"Document has type {document.doc_type}")
    print(f"Document has document type confidence {document.confidence}")
    print(f"Document was analyzed with model with ID {result.model_id}")
    for name, field in document.fields.items():
        field_value = field.value if field.value else field.content
        print(
            f"......found field of type '{field.value_type}' with value '{field_value}' and with confidence {field.confidence}"
        )

# iterate over tables, lines, and selection marks on each page
for page in result.pages:
    print(f"\nLines found on page {page.page_number}")
    for line in page.lines:
        print(f"...Line '{line.content}'")
    for word in page.words:
        print(f"...Word '{word.content}' has a confidence of {word.confidence}")
    if page.selection_marks:
        print(f"\nSelection marks found on page {page.page_number}")
        for selection_mark in page.selection_marks:
            print(
                f"...Selection mark is '{selection_mark.state}' and has a confidence of {selection_mark.confidence}"
            )

for i, table in enumerate(result.tables):
    print(f"\nTable {i + 1} can be found on page:")
    for region in table.bounding_regions:
        print(f"...{region.page_number}")
    for cell in table.cells:
        print(
            f"...Cell[{cell.row_index}][{cell.column_index}] has text '{cell.content}'"
        )
print("-----------------------------------")
```

<!-- END SNIPPET -->

Alternatively, a document URL can also be used to analyze documents using the `begin_analyze_document_from_url` method.

```python
document_url = "<url_of_the_document>"
poller = document_analysis_client.begin_analyze_document_from_url(model_id=model_id, document_url=document_url)
result = poller.result()
```

### Manage Your Models

Manage the custom models attached to your account.

```python
from azure.ai.formrecognizer import DocumentModelAdministrationClient
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import ResourceNotFoundError

endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/"
credential = AzureKeyCredential("<api_key>")

document_model_admin_client = DocumentModelAdministrationClient(endpoint, credential)

account_details = document_model_admin_client.get_resource_details()
print("Our account has {} custom models, and we can have at most {} custom models".format(
    account_details.custom_document_models.count, account_details.custom_document_models.limit
))

# Here we get a paged list of all of our models
models = document_model_admin_client.list_document_models()
print("We have models with the following ids: {}".format(
    ", ".join([m.model_id for m in models])
))

# Replace with the custom model ID from the "Build a model" sample
model_id = "<model_id from the Build a Model sample>"

custom_model = document_model_admin_client.get_document_model(model_id=model_id)
print("Model ID: {}".format(custom_model.model_id))
print("Description: {}".format(custom_model.description))
print("Model created on: {}\n".format(custom_model.created_on))

# Finally, we will delete this model by ID
document_model_admin_client.delete_document_model(model_id=custom_model.model_id)

try:
    document_model_admin_client.get_document_model(model_id=custom_model.model_id)
except ResourceNotFoundError:
    print("Successfully deleted model with id {}".format(custom_model.model_id))
```

### Add-on Capabilities
Document Intelligence supports more sophisticated analysis capabilities. These optional features can be enabled and disabled depending on the scenario of the document extraction.

The following add-on capabilities are available for 2023-07-31 (GA) and later releases:
- [barcode/QR code][addon_barcodes_sample]
- [formula][addon_formulas_sample]
- [font/style][addon_fonts_sample]
- [high resolution mode][addon_highres_sample]
- [language][addon_languages_sample]

Note that some add-on capabilities will incur additional charges. See pricing: https://azure.microsoft.com/pricing/details/ai-document-intelligence/.

## Troubleshooting

### General

Form Recognizer client library will raise exceptions defined in [Azure Core][azure_core_exceptions].
Error codes and messages raised by the Document Intelligence service can be found in the [service documentation][fr-errors].

### Logging

This library uses the standard
[logging][python_logging] library for logging.

Basic information about HTTP sessions (URLs, headers, etc.) is logged at `INFO` level.

Detailed `DEBUG` level logging, including request/response bodies and **unredacted**
headers, can be enabled on the client or per-operation with the `logging_enable` keyword argument.

See full SDK logging documentation with examples [here][sdk_logging_docs].

### Optional Configuration

Optional keyword arguments can be passed in at the client and per-operation level.
The azure-core [reference documentation][azure_core_ref_docs]
describes available configurations for retries, logging, transport protocols, and more.

## Next steps

### More sample code

See the [Sample README][sample_readme] for several code snippets illustrating common patterns used in the Form Recognizer Python API.

### Additional documentation

For more extensive documentation on Azure AI Document Intelligence, see the [Document Intelligence documentation][python-fr-product-docs] on docs.microsoft.com.

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit [cla.microsoft.com][cla].

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct][code_of_conduct]. For more information see the [Code of Conduct FAQ][coc_faq] or contact [opencode@microsoft.com][coc_contact] with any additional questions or comments.

<!-- LINKS -->

[python-fr-src]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer
[python-fr-pypi]: https://pypi.org/project/azure-ai-formrecognizer/
[python-fr-product-docs]: https://learn.microsoft.com/azure/applied-ai-services/form-recognizer/overview?view=form-recog-3.0.0
[python-fr-ref-docs]: https://aka.ms/azsdk/python/formrecognizer/docs
[python-fr-samples]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples

[azure_subscription]: https://azure.microsoft.com/free/
[azure_portal]: https://ms.portal.azure.com/
[regional_endpoints]: https://azure.microsoft.com/global-infrastructure/services/?products=form-recognizer
[FR_or_CS_resource]: https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account?tabs=multiservice%2Cwindows
[pip]: https://pypi.org/project/pip/
[cognitive_resource_portal]: https://ms.portal.azure.com/#create/Microsoft.CognitiveServicesFormRecognizer
[cognitive_resource_cli]: https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account-cli?tabs=windows
[azure-key-credential]: https://aka.ms/azsdk/python/core/azurekeycredential
[labeling-tool]: https://aka.ms/azsdk/formrecognizer/labelingtool
[fr-studio]: https://aka.ms/azsdk/formrecognizer/formrecognizerstudio
[fr-build-model]: https://aka.ms/azsdk/formrecognizer/buildmodel
[fr-build-training-set]: https://aka.ms/azsdk/formrecognizer/buildtrainingset
[fr-models]: https://aka.ms/azsdk/formrecognizer/models
[fr-errors]: https://aka.ms/azsdk/formrecognizer/errors
[fr_to_di_migration_guideline]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/documentintelligence/azure-ai-documentintelligence/MIGRATION_GUIDE.md

[azure_core_ref_docs]: https://aka.ms/azsdk/python/core/docs
[azure_core_exceptions]: https://aka.ms/azsdk/python/core/docs#module-azure.core.exceptions
[python_logging]: https://docs.python.org/3/library/logging.html
[multi_and_single_service]: https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account?tabs=multiservice%2Cwindows
[azure_cli_endpoint_lookup]: https://docs.microsoft.com/cli/azure/cognitiveservices/account?view=azure-cli-latest#az-cognitiveservices-account-show
[azure_portal_get_endpoint]: https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account?tabs=multiservice%2Cwindows#get-the-keys-for-your-resource
[cognitive_authentication_api_key]: https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account?tabs=multiservice%2Cwindows#get-the-keys-for-your-resource
[register_aad_app]: https://docs.microsoft.com/azure/cognitive-services/authentication#assign-a-role-to-a-service-principal
[custom_subdomain]: https://docs.microsoft.com/azure/cognitive-services/authentication#create-a-resource-with-a-custom-subdomain
[azure_identity]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity
[default_azure_credential]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/identity/azure-identity#defaultazurecredential
[service_recognize_receipt]: https://aka.ms/azsdk/formrecognizer/receiptfieldschema
[service_recognize_business_cards]: https://aka.ms/azsdk/formrecognizer/businesscardfieldschema
[service_recognize_invoice]: https://aka.ms/azsdk/formrecognizer/invoicefieldschema
[service_recognize_identity_documents]: https://aka.ms/azsdk/formrecognizer/iddocumentfieldschema
[service_recognize_tax_documents]: https://aka.ms/azsdk/formrecognizer/taxusw2fieldschema
[service_prebuilt_document]: https://docs.microsoft.com/azure/applied-ai-services/form-recognizer/concept-general-document#general-document-features
[sdk_logging_docs]: https://docs.microsoft.com/azure/developer/python/sdk/azure-sdk-logging
[sample_readme]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples
[changelog]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md
[migration-guide]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/MIGRATION_GUIDE.md
[classify_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples/v3.2_and_later/sample_classify_document.py
[service-rename]: https://techcommunity.microsoft.com/t5/azure-ai-services-blog/azure-form-recognizer-is-now-azure-ai-document-intelligence-with/ba-p/3875765
[addon_barcodes_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples/v3.2_and_later/sample_analyze_addon_barcodes.py
[addon_fonts_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples/v3.2_and_later/sample_analyze_addon_fonts.py
[addon_formulas_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples/v3.2_and_later/sample_analyze_addon_formulas.py
[addon_highres_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples/v3.2_and_later/sample_analyze_addon_highres.py
[addon_languages_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/samples/v3.2_and_later/sample_analyze_addon_languages.py

[cla]: https://cla.microsoft.com
[code_of_conduct]: https://opensource.microsoft.com/codeofconduct/
[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/
[coc_contact]: mailto:opencode@microsoft.com


# Release History

## 3.3.3 (2024-04-09)

### Other Changes
- Added support for Python 3.12.
- Python 3.7 is no longer supported. Please use Python version 3.8 or later.
- Changed the default polling interval from 5s to 1s.

## 3.3.2 (2023-11-07)

### Bugs Fixed
- Fixed incorrect data type for returned formula objects.

## 3.3.1 (2023-10-10)

### Features Added
- Exposed `send_request()` method in each client to send custom requests using the client's existing pipeline. ([#32151](https://github.com/Azure/azure-sdk-for-python/issues/32151))

## 3.3.0 (2023-08-08)

This version of the client library defaults to the service API version `2023-07-31`.

### Breaking Changes
 > Note: The following changes are only breaking from the previous beta. They are not breaking against previous stable versions.
 
- Going forward this library will default to service API version `2023-07-31`.
- Removed `query_fields` keyword argument from `begin_analyze_document()` and `begin_analyze_document_from_url()`.
- Removed `kind` property from `DocumentPage`.
- Removed `images` property from `DocumentPage`.
- Removed `DocumentImage` model.
- Removed `annotations` property from `DocumentPage`.
- Removed `DocumentAnnotation` model.
- Removed `common_name` property from `DocumentKeyValuePair`.
- Changed `AnalysisFeature` enum member names and values. Supported enum members are: `OCR_HIGH_RESOLUTION`, `LANGUAGES`, `BARCODES`, `FORMULAS`, `KEY_VALUE_PAIRS`, `STYLE_FONT`.
- Renamed `custom_neural_document_model_builds` property to `neural_document_model_quota` on `ResourceDetails` model.
- Renamed `AzureBlobSource` model to `BlobSource`.
- Renamed `AzureBlobFileListSource` model to `BlobFileListSource`.
- Marked `neural_document_model_quota` as optional on `ResourceDetails`.

### Other Changes
- Corrected typing for the `polygon` property on `DocumentWord`, `DocumentSelectionMark`, `DocumentLine`.
- Corrected typing for `words`, `lines`, and `selection_marks` properties on `DocumentPage`.
- Renamed the samples directory to `v3.2_and_later/` for samples that support 3.2 and later.

## 3.3.0b1 (2023-04-13)

This version of the client library defaults to the service API version `2023-02-28-preview`.

### Features Added

- Added `features` keyword argument on `begin_analyze_document()` and `begin_analyze_document_from_url()`.
- Added `query_fields` keyword argument on `begin_analyze_document()` and `begin_analyze_document_from_url()`.
- Added `AnalysisFeature` enum with optional document analysis feature to enable.
- Added `file_list` keyword argument on `begin_build_document_model()`.
- Added the following optional properties on `DocumentStyle` class: `similar_font_family`, `font_style`, `font_weight`, `color`, `background_color`.
- Added support for custom document classification on `DocumentModelAdministrationClient`: `begin_build_document_classifier`, 
  `list_document_classifiers`, `get_document_classifier`, and `delete_document_classifier`.
- Added support for classifying documents on `DocumentAnalysisClient`: `begin_classify_document` and `begin_classify_document_from_url`.
- Added `ClassifierDocumentTypeDetails` to use with `begin_build_document_classifier()`.
- Added model `QuotaDetails` and property `custom_neural_document_model_builds` on `ResourceDetails`.
- Added kind `documentClassifierBuild` to `OperationSummary` and `OperationDetails`.
- Added property `expires_on` to `DocumentModelDetails` and `DocumentModelSummary`.
- Added kind `formulaBlock` to `DocumentParagraph`.
- Added property `common_name` to `DocumentKeyValuePair`.
- Added property `code` to `CurrencyValue`.
- Added properties `unit`, `city_district`, `state_district`, `suburb`, `house`, and `level` to `AddressValue`.
- Added "boolean" `value_type` and `bool` `value` to `DocumentField`.
- Added properties `annotations`, `images`, `formulas`, and `barcodes` to `DocumentPage`. 
- Added models `DocumentAnnotation`, `DocumentImage`, `DocumentFormula`, and `DocumentBarcode`.

## 3.2.1 (2023-03-07)

### Bugs Fixed
- Corrected typing for `invoice` argument in `begin_recognize_invoices()` on async `FormRecognizerClient`.
- Fixed issue when calling `to_dict()` on `DocumentField` where `value` is not returned for address and currency fields.
- Corrected typing for `form_type_confidence` property on `RecognizedForm`.
- Corrected typing for `appearance` property on `FormLine`.

### Other Changes
- Improved static typing.

## 3.2.0 (2022-09-08)

### Features Added
- Content type `image/heif` is supported for document analysis and building models.
- Added `custom_document_models` property on `ResourceDetails`.
- Added new `CustomDocumentModelsDetails` model to represent the details of the custom document models in a given Form Recognizer resource.

### Breaking Changes
- This library will default to service API version `2022-08-31` going forward.
- Removed `kind` property on `DocumentPage`.
- Renamed `begin_build_model()` to `begin_build_document_model()` on the `DocumentModelAdministrationClient`.
- Renamed `begin_compose_model()` to `begin_compose_document_model()` on the `DocumentModelAdministrationClient`.
- Renamed `begin_copy_model_to()` to `begin_copy_document_model_to()` on the `DocumentModelAdministrationClient`.
- Renamed `list_models()` to `list_document_models()` on the `DocumentModelAdministrationClient`.
- Renamed `get_model()` to `get_document_model()` on the `DocumentModelAdministrationClient`.
- Renamed `delete_model()` to `delete_document_model()` on the `DocumentModelAdministrationClient`.
- Removed `document_model_count` and `document_model_limit` properties on `ResourceDetails`.
- Renamed `DocumentModelOperationDetails` to `OperationDetails`.
- Renamed `DocumentModelOperationSummary` to `OperationSummary`.
- Removed `DocumentContentElement`.
- Removed `kind` and `content` properties from `DocumentSelectionMark`.
- Removed `kind` from `DocumentWord`.

### Bugs Fixed
- Added `DocumentParagraph` to `__all__`.

## 3.2.0b6 (2022-08-09)

### Features Added
- Added `TargetAuthorization` of type `dict[str, str]`.

### Breaking Changes
- Renamed `source` argument to `blob_container_url` on `begin_build_model()` and made it a required keyword-only argument.
- Changed argument order on `begin_build_model()`. `build_mode` is the first expected argument, followed by `blob_container_url`.
- Renamed `begin_create_composed_model()` on `DocumentModelAdministrationClient` to `begin_compose_model()`.
- Renamed `get_account_info()` on `DocumentModelAdministrationClient` to `get_resource_details()`.
- Renamed `DocumentBuildMode` to `ModelBuildMode`.
- Renamed `AccountInfo` model to `ResourceDetails`.
- Renamed `DocTypeInfo` model to `DocumentTypeDetails`.
- Renamed `DocumentModelInfo` model to `DocumentModelSummary`.
- Renamed `DocumentModel` to `DocumentModelDetails`.
- Renamed `ModelOperation` to `DocumentModelOperationDetails`.
- Renamed `ModelOperationInfo` to `DocumentModelOperationSummary`.
- Renamed `model` parameter to `model_id` on `begin_analyze_document()` and `begin_analyze_document_from_url()`.
- Removed `continuation_token` keyword from `begin_analyze_document()` and `begin_analyze_document_from_url()` on `DocumentAnalysisClient` and from `begin_build_model()`, `begin_compose_model()` and `begin_copy_model_to()` on `DocumentModelAdministrationClient`.
- Changed return type of `get_copy_authorization()` from `dict[str, str]` to `TargetAuthorization`.
- Changed expected `target` parameter in `begin_copy_to()` from `dict[str, str]` to `TargetAuthorization`.
- Long-running operation metadata is now accessible through the `details` property on the returned `DocumentModelAdministrationLROPoller` and `AsyncDocumentModelAdministrationLROPoller` instances.

### Other Changes
- Python 3.6 is no longer supported in this release. Please use Python 3.7 or later.

## 3.2.0b5 (2022-06-07)

### Features Added
- Added `paragraphs` property on `AnalyzeResult`.
- Added new `DocumentParagraph` model to represent document paragraphs.
- Added new `AddressValue` model to represent address fields found in documents.
- Added `kind` property on `DocumentPage`.

### Breaking Changes
- Renamed `bounding_box` to `polygon` on `BoundingRegion`, `DocumentContentElement`, `DocumentLine`, `DocumentSelectionMark`, `DocumentWord`.
- Renamed `language_code` to `locale` on `DocumentLanguage`.
- Some models that previously returned string for address related fields may now return `AddressValue`. TIP: Use `get_model()` on `DocumentModelAdministrationClient` to see updated prebuilt model schemas.
- Removed `entities` property on `AnalyzeResult`.
- Removed `DocumentEntity` model.

## 3.2.0b4 (2022-04-05)

### Breaking Changes
- Renamed `begin_copy_model()` to `begin_copy_model_to()`.
- In `begin_create_composed_model()`, renamed required parameter `model_ids` to `component_model_ids`.
- Renamed `model_count` and `model_limit` on `AccountInfo` to `document_model_count` and `document_model_limit`.

### Bugs Fixed
- Fixed `to_dict()` and `from_dict()` methods on `DocumentField` to support converting lists, dictionaries, and CurrenyValue field types to and from a dictionary.

### Other Changes
- Renamed `sample_copy_model.py` and `sample_copy_model_async.py` to `sample_copy_model_to.py` and `sample_copy_model_to_async.py` under the `3.2-beta` samples folder. Updated the samples to use renamed copy model method.

## 3.2.0b3 (2022-02-10)

### Features Added
- Added new `CurrencyValue` model to represent the amount and currency symbol values found in documents.
- Added `DocumentBuildMode` enum with values `template` and `neural`. These enum values can be passed in for the `build_mode` parameter in `begin_build_model()`.
- Added `api_version` and `tags` properties on `ModelOperation`, `ModelOperationInfo`, `DocumentModel`, `DocumentModelInfo`.
- Added `build_mode` property on `DocTypeInfo`.
- Added a `tags` keyword argument to `begin_build_model()`, `begin_create_composed_model()`, and `get_copy_authorization()`.
- Added `languages` property on `AnalyzeResult`.
- Added model `DocumentLanguage` that includes information about the detected languages found in a document.
- Added `sample_analyze_read.py` and `sample_analyze_read_async.py` under the `v3.2-beta` samples directory. These samples use the new `prebuilt-read` model added by the service.
- Added `sample_analyze_tax_us_w2.py` and `sample_analyze_tax_us_w2_async.py` under the `v3.2-beta` samples directory. These samples use the new `prebuilt-tax.us.w2` model added by the service.

### Breaking Changes
- Added new required parameter `build_mode` to `begin_build_model()`.
- Some models that previously returned float for currency related fields may now return a `CurrencyValue`. TIP: Use `get_model()` on `DocumentModelAdministrationClient` to see updated prebuilt model schemas.

### Bugs Fixed
- Default the `percent_completed` property to 0 when not returned with model operation information.

### Other Changes
- Python 2.7 is no longer supported in this release. Please use Python 3.6 or later.
- Bumped `azure-core` minimum dependency version from `1.13.0` to `1.20.1`.
- Updated samples that call `begin_build_model()` to send the `build_mode` parameter.

## 3.2.0b2 (2021-11-09)

### Features Added
- Added `get_words()` on `DocumentLine`.
- Added samples showing how to use `get_words()` on a `DocumentLine` under `/samples/v3.2-beta`: `sample_get_words_on_document_line.py` and `sample_get_words_on_document_line_async.py`.

### Breaking Changes
- Renamed `DocumentElement` to `DocumentContentElement`.

## 3.2.0b1 (2021-10-07)

This version of the SDK defaults to the latest supported API version, which is currently 2021-09-30-preview.

> Note: Starting with version 2021-09-30-preview, a new set of clients were introduced to leverage the newest features of the Form Recognizer service. Please see the [Migration Guide](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/MIGRATION_GUIDE.md) for detailed instructions on how to update application code from client library version 3.1.X or lower to the latest version. Also, please refer to the [README](https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/formrecognizer/azure-ai-formrecognizer/README.md) for more information about the library. 

### Features Added
- Added new `DocumentAnalysisClient` with  `begin_analyze_document` and `begin_analyze_document_from_url` methods. Use these methods with the latest Form Recognizer 
API version to analyze documents, with prebuilt and custom models.
- Added new models to use with the new `DocumentAnalysisClient`: `AnalyzeResult`, `AnalyzedDocument`, `BoundingRegion`, `DocumentElement`, `DocumentEntity`, `DocumentField`, `DocumentKeyValuePair`, `DocumentKeyValueElement`, `DocumentLine`, `DocumentPage`, `DocumentSelectionMark`, `DocumentSpan`, `DocumentStyle`, `DocumentTable`, `DocumentTableCell`, `DocumentWord`.
- Added new `DocumentModelAdministrationClient` with methods: `begin_build_model`, `begin_create_composed_model`, `begin_copy_model`, `get_copy_authorization`, `get_model`, `delete_model`, `list_models`, `get_operation`, `list_operations`, `get_account_info`, `get_document_analysis_client`.
- Added new models to use with the new `DocumentModelAdministrationClient`: `DocumentModel`, `DocumentModelInfo`, `DocTypeInfo`, `ModelOperation`, `ModelOperationInfo`, `AccountInfo`, `DocumentAnalysisError`, `DocumentAnalysisInnerError`.
- Added samples using the `DocumentAnalysisClient` and `DocumentModelAdministrationClient` under `/samples/v3.2-beta`.
- Added `DocumentAnalysisApiVersion` to be used with `DocumentAnalysisClient` and `DocumentModelAdministrationClient`.

### Other Changes
- Python 3.5 is no longer supported in this release.

## 3.1.2 (2021-08-10)

### Bugs Fixed
- A `HttpResponseError` will be immediately raised when the call quota volume is exceeded in a `F0` tier Form Recognizer
resource.

### Other Changes
- Bumped `azure-core` minimum dependency version from `1.8.2` to `1.13.0`

## 3.1.1 (2021-06-08)

**Bug Fixes**

- Handles invoices that do not have sub-line item fields detected.

## 3.1.0 (2021-05-26)

This version of the SDK defaults to the latest supported API version, which currently is v2.1

Note: this version will be the last to officially support Python 3.5, future versions will require Python 2.7 or Python 3.6+

**Breaking Changes**

- `begin_recognize_id_documents` renamed to `begin_recognize_identity_documents`.
- `begin_recognize_id_documents_from_url` renamed to `begin_recognize_identity_documents_from_url`.
- The model `TextAppearance` now includes the properties `style_name` and `style_confidence` that were part of the `TextStyle` object.
- Removed the model `TextStyle`.
- Removed field value types "gender" and "country" from the `FieldValueType` enum.
- Added field value type "countryRegion" to the `FieldValueType` enum.
- Renamed field name for identity documents from "Country" to "CountryRegion".

**New features**

- Added `to_dict` and `from_dict` methods to all of the models

## 3.1.0b4 (2021-04-06)

**New features**

- New methods `begin_recognize_id_documents` and `begin_recognize_id_documents_from_url` introduced to the SDK. Use these methods to recognize data from identity documents.
- New field value types "gender" and "country" described in the `FieldValueType` enum.
- Content-type `image/bmp` now supported by custom forms and training methods.
- Added keyword argument `pages` for business cards, receipts, custom forms, and invoices
to specify which page to process of the document.
- Added keyword argument `reading_order` to `begin_recognize_content` and `begin_recognize_content_from_url`.

**Dependency Updates**

- Bumped `msrest` requirement from `0.6.12` to `0.6.21`.

## 3.1.0b3 (2021-02-09)

**Breaking Changes**

- `Appearance` is renamed to `TextAppearance`
- `Style` is renamed to `TextStyle`
- Client property `api_version` is no longer exposed. Pass keyword argument `api_version` into the client to select the
API version

**Dependency Updates**

- Bumped `six` requirement from `1.6` to `1.11.0`.

## 3.1.0b2 (2021-01-12)

**Bug Fixes**

- Package requires [azure-core](https://pypi.org/project/azure-core/) version 1.8.2 or greater


## 3.1.0b1 (2020-11-23)

This version of the SDK defaults to the latest supported API version, which currently is v2.1-preview.

**New features**

- New methods `begin_recognize_business_cards` and `begin_recognize_business_cards_from_url` introduced to the SDK. Use these
methods to recognize data from business cards
- New methods `begin_recognize_invoices` and `begin_recognize_invoices_from_url` introduced to the SDK. Use these
methods to recognize data from invoices
- Recognize receipt methods now take keyword argument `locale` to optionally indicate the locale of the receipt for
improved results
- Added ability to create a composed model from the `FormTrainingClient` by calling method `begin_create_composed_model()`
- Added support to train and recognize custom forms with selection marks such as check boxes and radio buttons.
This functionality is only available for models trained with labels
- Added property `selection_marks` to `FormPage` which contains a list of `FormSelectionMark`
- When passing `include_field_elements=True`, the property `field_elements` on `FieldData` and `FormTableCell` will
also be populated with any selection marks found on the page
- Added the properties `model_name` and `properties` to types `CustomFormModel` and `CustomFormModelInfo`
- Added keyword argument `model_name` to `begin_training()` and `begin_create_composed_model()`
- Added model type `CustomFormModelProperties` that includes information like if a model is a composed model
- Added property `model_id` to `CustomFormSubmodel` and `TrainingDocumentInfo`
- Added properties `model_id` and `form_type_confidence` to `RecognizedForm`
- `appearance` property added to `FormLine` to indicate the style of extracted text - like "handwriting" or "other"
- Added keyword argument `pages` to `begin_recognize_content` and `begin_recognize_content_from_url` to specify the page
numbers to analyze
- Added property `bounding_box` to `FormTable`
- Content-type `image/bmp` now supported by recognize content and prebuilt models
- Added keyword argument `language` to `begin_recognize_content` and `begin_recognize_content_from_url` to specify
which language to process document in

**Dependency updates**

- Package now requires [azure-common](https://pypi.org/project/azure-common/) version 1.1

## 3.0.0 (2020-08-20)

First stable release of the azure-ai-formrecognizer client library.

**New features**

- Client-level, keyword argument `api_version` can be used to specify the service API version to use. Currently only v2.0
is supported. See the enum `FormRecognizerApiVersion` for supported API versions.
- `FormWord` and `FormLine` now have attribute `kind` which specifies the kind of element it is, e.g. "word" or "line"

## 3.0.0b1 (2020-08-11)

The version of this package now targets the service's v2.0 API.

**Breaking Changes**

- Client library version bumped to `3.0.0b1`
- Values are now capitalized for enums `FormContentType`, `LengthUnit`, `TrainingStatus`, and `CustomFormModelStatus`
- `document_name` renamed to `name` on `TrainingDocumentInfo`
- Keyword argument `include_sub_folders` renamed to `include_subfolders` on `begin_training` methods

**New features**

- `FormField` now has attribute `value_type` which contains the semantic data type of the field value. The options for
`value_type` are described in the enum `FieldValueType`

**Fixes and improvements**

- Fixes a bug where error code and message weren't being returned on `HttpResponseError` if operation failed during polling
- `FormField` property `value_data` is now set to `None` if no values are returned on its `FieldData`.
Previously `value_data` returned a `FieldData` with all its attributes set to `None` in the above case.


## 1.0.0b4 (2020-07-07)

**Breaking Changes**

- `RecognizedReceipts` class has been removed.
- `begin_recognize_receipts` and `begin_recognize_receipts_from_url` now return `RecognizedForm`.
- `requested_on` has been renamed to `training_started_on` and `completed_on` renamed to `training_completed_on` on `
CustomFormModel` and `CustomFormModelInfo`
- `FieldText` has been renamed to `FieldData`
- `FormContent` has been renamed to `FormElement`
- Parameter `include_text_content` has been renamed to `include_field_elements` for
`begin_recognize_receipts`, `begin_recognize_receipts_from_url`, `begin_recognize_custom_forms`, and `begin_recognize_custom_forms_from_url`
- `text_content` has been renamed to `field_elements` on `FieldData` and `FormTableCell`

**Fixes and improvements**

- Fixes a bug where `text_angle` was being returned out of the specified interval (-180, 180]

## 1.0.0b3 (2020-06-10)

**Breaking Changes**

- All asynchronous long running operation methods now return an instance of an `AsyncLROPoller` from `azure-core`
- All asynchronous long running operation methods are renamed with the `begin_` prefix to indicate that an `AsyncLROPoller` is returned:
    - `train_model` is renamed to `begin_training`
    - `recognize_receipts` is renamed to `begin_recognize_receipts`
    - `recognize_receipts_from_url` is renamed to `begin_recognize_receipts_from_url`
    - `recognize_content` is renamed to `begin_recognize_content`
    - `recognize_content_from_url` is renamed to `begin_recognize_content_from_url`
    - `recognize_custom_forms` is renamed to `begin_recognize_custom_forms`
    - `recognize_custom_forms_from_url` is renamed to `begin_recognize_custom_forms_from_url`
- Sync method `begin_train_model` renamed to `begin_training`
- `training_files` parameter of `begin_training` is renamed to `training_files_url`
- `use_labels` parameter of `begin_training` is renamed to `use_training_labels`
- `list_model_infos` method has been renamed to `list_custom_models`
- Removed `get_form_training_client` from `FormRecognizerClient`
- Added `get_form_recognizer_client` to `FormTrainingClient`
- A `HttpResponseError` is now raised if a model with `status=="invalid"` is returned from the `begin_training` methods
- `PageRange` is renamed to `FormPageRange`
- `first_page` and `last_page` renamed to `first_page_number` and `last_page_number`, respectively on `FormPageRange`
- `FormField` does not have a page_number
- `use_training_labels` is now a required positional param in the `begin_training` APIs
- `stream` and `url` parameters found on methods for `FormRecognizerClient` have been renamed to `form` and `form_url`, respectively
- For `begin_recognize_receipt` methods, parameters have been renamed to `receipt` and `receipt_url`
- `created_on` and `last_modified` are renamed to `requested_on` and `completed_on` in the
`CustomFormModel`  and `CustomFormModelInfo` models
- `models` property of `CustomFormModel` is renamed to `submodels`
- `CustomFormSubModel` is renamed to `CustomFormSubmodel`
- `begin_recognize_receipts` APIs now return a list of `RecognizedReceipt` instead of `USReceipt`
- Removed `USReceipt`. To see how to deal with the return value of `begin_recognize_receipts`, see the recognize receipt samples in the [samples directory](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/formrecognizer/azure-ai-formrecognizer/samples) for details.
- Removed `USReceiptItem`. To see how to access the individual items on a receipt, see the recognize receipt samples in the [samples directory](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/formrecognizer/azure-ai-formrecognizer/samples) for details.
- Removed `USReceiptType` and the `receipt_type` property from `RecognizedReceipt`. See the recognize receipt samples in the [samples directory](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/formrecognizer/azure-ai-formrecognizer/samples) for details.

**New features**

- Support to copy a custom model from one Form Recognizer resource to another
- Authentication using `azure-identity` credentials now supported
  - see the [Azure Identity documentation](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/identity/azure-identity/README.md) for more information
- `page_number` attribute has been added to `FormTable`
- All long running operation methods now accept the keyword argument `continuation_token` to restart the poller from a saved state

**Dependency updates**

- Adopted [azure-core](https://pypi.org/project/azure-core/) version 1.6.0 or greater

## 1.0.0b2 (2020-05-06)

**Fixes and improvements**

- Bug fixed where `confidence` == `0.0` was erroneously getting set to `1.0`
- `__repr__` has been added to all of the models


## 1.0.0b1 (2020-04-23)

Version (1.0.0b1) is the first preview of our efforts to create a user-friendly and Pythonic client library for Azure Form Recognizer.
This library replaces the package found here: https://pypi.org/project/azure-cognitiveservices-formrecognizer/

For more information about this, and preview releases of other Azure SDK libraries, please visit
https://azure.github.io/azure-sdk/releases/latest/python.html.

**Breaking changes: New API design**

- New namespace/package name:
  - The namespace/package name for the Form Recognizer client library has changed from
    `azure.cognitiveservices.formrecognizer` to `azure.ai.formrecognizer`
- Two client design:
    - FormRecognizerClient to analyze fields/values on custom forms, receipts, and form content/layout
    - FormTrainingClient to train custom models (with/without labels), and manage the custom models on your account
- Different analyze methods based on input type: file stream or URL.
    - URL input should use the method with suffix `from_url`
    - Stream methods will automatically detect content-type of the input file
- Asynchronous APIs added under `azure.ai.formrecognizer.aio` namespace
- Authentication with API key supported using `AzureKeyCredential("<api_key>")` from `azure.core.credentials`
- New underlying REST pipeline implementation based on the azure-core library
- Client and pipeline configuration is now available via keyword arguments at both the client level, and per-operation.
    See README for a link to optional configuration arguments
- New error hierarchy:
    - All service errors will now use the base type: `azure.core.exceptions.HttpResponseError`