Introduction
In today's digital era, businesses deal with an enormous amount of paperwork, ranging from invoices and receipts to forms and surveys. Manual data entry can be time-consuming, error-prone, and resource-intensive. However, Azure Form Recognizer, a powerful AI-based service by Microsoft, offers a solution to streamline and automate this process. In this article, we'll explore how you can leverage the capabilities of Azure Form Recognizer using Python, enabling you to extract valuable information from forms effortlessly.
What is Azure Form Recognizer?
Azure Form Recognizer is a cloud-based service that utilizes machine learning algorithms to automatically extract key-value pairs, tables, and text from documents. It employs optical character recognition (OCR) technology, allowing businesses to digitize and process large volumes of forms efficiently. The service can handle various document types, including invoices, receipts, business cards, and more, making it a versatile tool for document processing.
Setting up Azure Form Recognizer resource
Go to Azure Portal and search Form Recognizer, then click on Create.

Choose the subscription, resource group, region, pricing tier, and type the resource name. Then, click on Review + create.

Once the resource is created, go to Keys and Endpoint to copy your credentials.
Getting Started with Azure Form Recognizer on Python
You need to install the Azure AI Form Recognizer SDK. You can do this by running the following command in your Python environment:
pip install azure-ai-formrecognizer
Next, import the required libraries and authenticate with your Azure account.
from azure.core.credentials import AzureKeyCredential
from azure.ai.formrecognizer import DocumentAnalysisClient
import numpy as np
import pandas as pd
ENDPOINT = "<YOUR_ENDPOINT>"
APIKEY = "<YOUR_API_KEY>"
document_analysis_client = DocumentAnalysisClient(ENDPOINT, credential=AzureKeyCredential(APIKEY))
We'll use the document_analysis_client to extract information from different types of documents using the following prebuilt models:
- Invoices
- Receipts
- Business cards
- Identity documents
Visit this page to know about all the models that Azure Form Recognizer offers.
We'll create the following utility methods:
def is_class(o):
return hasattr(o, '__dict__')
def get_valid_rounded_value(val):
return round(val * 100, 2) if val else None
Let's start testing the Prebuilt Models. We'll create two more methods, one to analyze the documents and the another one to print a table with the extracted information:
def get_poller_result(path: str, model_id: str):
with open(path, "rb") as f:
poller = document_analysis_client.begin_analyze_document(
model_id, document=f, locale="en-US",
)
return poller.result()
def print_generic_table(items, is_business_card: bool = False):
if not is_business_card:
array: list = []
for name, field in items:
if name == 'MachineReadableZone':
continue
if field.value is not None and not is_class(field.value) and not type(field.value) is list:
array.append([name, field.value, get_valid_rounded_value(field.confidence)])
if len(array) > 0:
np_array = np.array(array)
df = pd.DataFrame(np_array, columns = ['Field', 'Value', '% Confidence'])
display(df)
else:
array: list = []
for name, field in items:
if field.value is not None and type(field.value) is list:
array: list = []
for idx, sub_item in enumerate(field.value):
if sub_item.value is not None and not is_class(sub_item.value) and not type(sub_item.value) is list:
if name == 'ContactNames':
for sub_field in ['FirstName', 'LastName']:
if sub_item.value[sub_field]:
sub_item_details = sub_item.value[sub_field]
array.append(['{} {}'.format(sub_field, idx + 1), sub_item_details.value, get_valid_rounded_value(sub_item_details.confidence)])
else:
array.append(['{} {}'.format(name, idx + 1), sub_item.value, get_valid_rounded_value(sub_item.confidence)])
elif name == 'Addresses':
array.append(['{} {}'.format(name, idx + 1), sub_item.content, get_valid_rounded_value(sub_item.confidence)])
if len(array) > 0:
display(name)
np_array = np.array(array)
df = pd.DataFrame(np_array, columns = ['Field', 'Value', '% Confidence'])
display(df)
Invoices
It analyzes and extracts key fields and line items from sales invoices, utility bills, and purchase orders. Invoices can be of various formats and quality including phone-captured images, scanned documents, and digital PDFs. The API analyzes invoice text; extracts key information such as customer name, billing address, due date, and amount due; and returns a structured JSON data representation.
To know about the supported languages, fields extraction and more, visit this page.
Lest's test the Invoice model. We can pass an image or PDF with one or more invoices.
invoices = get_poller_result("invoices/invoice_sample.png", "prebuilt-invoice")
def print_products_table(items, document_type: str):
array: list = []
for idx, item in enumerate(items):
if document_type == 'invoice':
fields = ["ProductCode", "Description", "Quantity", "Unit", "UnitPrice", "Tax", "Amount"]
elif document_type == 'receipt':
fields = ["ProductCode", "Description", "Quantity", "QuantityUnit", "Price", "TotalPrice"]
current_row = []
for field in fields:
current_item = item.value.get(field)
if current_item:
current_row.append(current_item.value)
else:
current_row.append(None)
array.append(current_row)
np_array = np.array(array)
df = pd.DataFrame(np_array, columns = fields)
display(df)
def print_invoices_details(invoices):
for idx, invoice in enumerate(invoices.documents):
display("-------- Recognizing invoice #{} --------".format(idx + 1))
items = invoice.fields.items()
print_generic_table(items)
display("Invoice products:")
invoice_products = invoice.fields.get("Items").value
print_products_table(invoice_products, 'invoice')
We created the print_products_table method to print the products for invoices and receipts.
Call the print_invoices_details method and pass the invoices.
print_invoices_details(invoices)
-------- Recognizing invoice #1 --------
| Field | Value | % Confidence |
| BillingAddressRecipient | Microsoft Finance | 93.5 |
| CustomerAddressRecipient | Microsoft Corp | 93.2 |
| CustomerId | CID-12345 | 94.3 |
| CustomerName | MICROSOFT CORPORATION | 89.6 |
| DueDate | 2019-12-15 | 97.1 |
| InvoiceDate | 2019-11-15 | 97.1 |
| InvoiceId | INV-100 | 96.4 |
| PurchaseOrder | PO-3333 | 94.3 |
| RemittanceAddressRecipient | Contoso Billing | 93.4 |
| ServiceAddressRecipient | Microsoft Services | 93.2 |
| ServiceEndDate | 2019-11-14 | 95.4 |
| ServiceStartDate | 2019-10-14 | 95.8 |
| ShippingAddressRecipient | Microsoft Delivery | 93.2 |
| VendorAddressRecipient | Contoso Headquarters | 93.2 |
| VendorName | CONTOSO LTD. | 93.0 |
Invoice products:
| ProductCode | Description | Quantity | Unit | UnitPrice | Tax | Amount |
| A123 | Consulting Services | 2.0 | hours | $30.0 | $6.0 | $60.0 |
| B456 | Document Fee | 3.0 | None | $10.0 | $3.0 | $30.0 |
| C789 | Printing Fee | 10.0 | pages | $1.0 | $1.0 | $10.0 |
Receipts
It analyzes and extracts key information from sales receipts. Receipts can be of various formats and quality including printed and handwritten receipts. The API extracts key information such as merchant name, merchant phone number, transaction date, tax, and transaction total and returns structured JSON data.
To know about the supported languages, fields extraction and more, visit this page.
Lest's test the Receipt model.
receipts = get_poller_result("receipts/receipt_sample.png", "prebuilt-receipt")
def print_receipts_details(receipts):
for idx, receipt in enumerate(receipts.documents):
print("-------- Recognizing receipt #{} --------".format(idx + 1))
items = receipt.fields.items()
print_generic_table(items)
display("Receipt products:")
receipt_products = receipt.fields.get("Items").value
print_products_table(receipt_products, 'receipt')
Call the print_receipts_details method and pass the receipts.
print_receipts_details(receipts)
-------- Recognizing receipt #1 --------
| Field | Value | % Confidence |
| MerchantName | Contoso | 98.5 |
| MerchantPhoneNumber | +11234567890 | 98.9 |
| Subtotal | 1098.99 | 99.0 |
| Total | 1203.39 | 95.9 |
| TotalTax | 104.4 | 99.0 |
| TransactionDate | 2019-06-10 | 98.9 |
| TransactionTime | 13:59:00 | 99.5 |
Receipt products:
| ProductCode | Description | Quantity | QuantityUnit | Price | TotalPrice |
| None | Surface Pro 6 | 1.0 | None | None | 999.0 |
| None | SurfacePen | 1.0 | None | None | 99.99 |
Business cards
It analyzes and extracts data from business card images. The API analyzes printed business cards; extracts key information such as first name, last name, company name, email address, and phone number; and returns a structured JSON data representation.
To know about the supported languages, fields extraction and more, visit this page.
Lest's test the Business card model.
business_cards = get_poller_result("business_cards/bizcard.jpg", "prebuilt-businessCard")
def print_business_cards_details(business_cards):
for idx, business_card in enumerate(business_cards.documents):
print("-------- Analyzing business card #{} --------".format(idx + 1))
items = business_card.fields.items()
print_generic_table(items, True)
Join the conversation! Your thoughts help the community grow.