Skip to content

Commit 98a07a2

Browse files
[formrecognizer] Add samples for searching with spans (#21704)
* add samples for searching with spans * remove printing extra data * move samples to subfolder * add README * remove unused links * address feedback
1 parent cd452cd commit 98a07a2

File tree

3 files changed

+306
-0
lines changed

3 files changed

+306
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Advanced usage samples for Azure Form Recognizer client library for Python
2+
3+
> Note: The samples included in this folder are aimed at providing additional context for processing information for the Form Recognizer library clients. These samples currently show usage with a preview version of the library and may be subject to change during later releases.
4+
5+
These code samples show more advanced scenario operations with the Azure Form Recognizer client library.
6+
The async versions of the samples require Python 3.6 or later.
7+
8+
All of these samples need the endpoint to your Form Recognizer resource ([instructions on how to get endpoint][get-endpoint-instructions]), and your Form Recognizer API key ([instructions on how to get key][get-key-instructions]).
9+
10+
## Advanced samples for client library versions 3.2.0b1 and later
11+
12+
|**File Name**|**Description**|
13+
|----------------|-------------|
14+
|sample_get_elements_with_spans.py and sample_get_elements_with_spans_async.py|Get elements, such as lines, words, and/or styles, that are contained in the spans of another element|
15+
16+
## Next steps
17+
18+
Check out the [API reference documentation][python-fr-ref-docs] to learn more about
19+
what you can do with the Azure Form Recognizer client library.
20+
21+
22+
[python-fr-ref-docs]: https://aka.ms/azsdk/python/formrecognizer/docs
23+
[get-endpoint-instructions]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/formrecognizer/azure-ai-formrecognizer/README.md#get-the-endpoint
24+
[get-key-instructions]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/formrecognizer/azure-ai-formrecognizer/README.md#get-the-api-key
25+
26+
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-python/sdk/formrecognizer/azure-ai-formrecognizer/samples/v3.2-beta/advanced_samples/README.png)
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# coding: utf-8
2+
3+
# -------------------------------------------------------------------------
4+
# Copyright (c) Microsoft Corporation. All rights reserved.
5+
# Licensed under the MIT License. See License.txt in the project root for
6+
# license information.
7+
# --------------------------------------------------------------------------
8+
9+
"""
10+
FILE: sample_get_elements_with_spans_async.py
11+
12+
DESCRIPTION:
13+
This sample demonstrates how to get elements that are contained in the spans of another element.
14+
In this sample, the examples attempt to find the lines and styles that have the same spans as the
15+
main search element. The purpose of this sample is to show how to search for document elements
16+
that are within the same span area as other elements.
17+
18+
USAGE:
19+
python sample_get_elements_with_spans_async.py
20+
21+
Set the environment variables with your own values before running the sample:
22+
1) AZURE_FORM_RECOGNIZER_ENDPOINT - the endpoint to your Cognitive Services resource.
23+
2) AZURE_FORM_RECOGNIZER_KEY - your Form Recognizer API key
24+
"""
25+
26+
import os
27+
import asyncio
28+
29+
def get_styles(element_spans, styles):
30+
result = []
31+
for span in element_spans:
32+
for style in styles:
33+
for style_span in style.spans:
34+
if style_span.offset >= span.offset and (
35+
style_span.offset + style_span.length
36+
) <= (span.offset + span.length):
37+
result.append(style)
38+
return result
39+
40+
def get_lines(element_spans, document_page):
41+
result = []
42+
for span in element_spans:
43+
for line in document_page.lines:
44+
for line_span in line.spans:
45+
if line_span.offset >= span.offset and (
46+
line_span.offset + line_span.length
47+
) <= (span.offset + span.length):
48+
result.append(line)
49+
return result
50+
51+
def get_page(page_number, pages):
52+
for page in pages:
53+
if page.page_number == page_number:
54+
return page
55+
raise ValueError("could not find the requested page")
56+
57+
async def get_elements_with_spans_async():
58+
path_to_sample_documents = os.path.abspath(
59+
os.path.join(
60+
os.path.abspath(__file__),
61+
"..",
62+
"..",
63+
"..",
64+
"./sample_forms/forms/Form_1.jpg",
65+
)
66+
)
67+
68+
from azure.core.credentials import AzureKeyCredential
69+
from azure.ai.formrecognizer.aio import DocumentAnalysisClient
70+
71+
endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
72+
key = os.environ["AZURE_FORM_RECOGNIZER_KEY"]
73+
74+
document_analysis_client = DocumentAnalysisClient(
75+
endpoint=endpoint, credential=AzureKeyCredential(key)
76+
)
77+
async with document_analysis_client:
78+
with open(path_to_sample_documents, "rb") as f:
79+
poller = await document_analysis_client.begin_analyze_document(
80+
"prebuilt-document", document=f
81+
)
82+
result = await poller.result()
83+
84+
# Below is a method to search for the lines of a particular element by using spans.
85+
# This example uses DocumentTable, but other elements that also have a `spans` or `span` field
86+
# can also be used to search for related elements, such as lines in this case.
87+
# To see an example for searching for words which have a `span` field, see
88+
# `sample_get_words_on_document_line.py` under the samples v3.2-beta directory.
89+
for table_idx, table in enumerate(result.tables):
90+
print(
91+
"Table # {} has {} rows and {} columns".format(
92+
table_idx, table.row_count, table.column_count
93+
)
94+
)
95+
96+
lines = []
97+
98+
for region in table.bounding_regions:
99+
print(
100+
"Table # {} location on page: {}".format(
101+
table_idx,
102+
region.page_number,
103+
)
104+
)
105+
lines.extend(get_lines(table.spans, get_page(region.page_number, result.pages)))
106+
107+
print("Found # {} lines in the table".format(len(lines)))
108+
for line in lines:
109+
print(
110+
"...Line '{}' is within bounding box: '{}'".format(
111+
line.content,
112+
line.bounding_box,
113+
)
114+
)
115+
116+
# Below is a method to search for the style of a particular element by using spans.
117+
# This example uses DocumentEntity, but other elements that also have a `spans` or `span`
118+
# field can also be used to search for document text style.
119+
for entity in result.entities:
120+
styles = get_styles(entity.spans, result.styles)
121+
print(
122+
"Found entity '{}' of type '{}' with style:".format(
123+
entity.content, entity.category,
124+
)
125+
)
126+
if not styles:
127+
print(
128+
"...no handwritten text found"
129+
)
130+
for style in styles:
131+
if style.is_handwritten:
132+
print(
133+
"...handwritten with confidence {}".format(style.confidence)
134+
)
135+
print("----------------------------------------")
136+
137+
138+
async def main():
139+
await get_elements_with_spans_async()
140+
141+
142+
if __name__ == '__main__':
143+
loop = asyncio.get_event_loop()
144+
loop.run_until_complete(main())
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# coding: utf-8
2+
3+
# -------------------------------------------------------------------------
4+
# Copyright (c) Microsoft Corporation. All rights reserved.
5+
# Licensed under the MIT License. See License.txt in the project root for
6+
# license information.
7+
# --------------------------------------------------------------------------
8+
9+
"""
10+
FILE: sample_get_elements_with_spans.py
11+
12+
DESCRIPTION:
13+
This sample demonstrates how to get elements that are contained in the spans of another element.
14+
In this sample, the examples attempt to find the lines and styles that have the same spans as the
15+
main search element. The purpose of this sample is to show how to search for document elements
16+
that are within the same span area as other elements.
17+
18+
USAGE:
19+
python sample_get_elements_with_spans.py
20+
21+
Set the environment variables with your own values before running the sample:
22+
1) AZURE_FORM_RECOGNIZER_ENDPOINT - the endpoint to your Cognitive Services resource.
23+
2) AZURE_FORM_RECOGNIZER_KEY - your Form Recognizer API key
24+
"""
25+
26+
import os
27+
28+
def get_styles(element_spans, styles):
29+
result = []
30+
for span in element_spans:
31+
for style in styles:
32+
for style_span in style.spans:
33+
if style_span.offset >= span.offset and (
34+
style_span.offset + style_span.length
35+
) <= (span.offset + span.length):
36+
result.append(style)
37+
return result
38+
39+
def get_lines(element_spans, document_page):
40+
result = []
41+
for span in element_spans:
42+
for line in document_page.lines:
43+
for line_span in line.spans:
44+
if line_span.offset >= span.offset and (
45+
line_span.offset + line_span.length
46+
) <= (span.offset + span.length):
47+
result.append(line)
48+
return result
49+
50+
def get_page(page_number, pages):
51+
for page in pages:
52+
if page.page_number == page_number:
53+
return page
54+
raise ValueError("could not find the requested page")
55+
56+
def get_elements_with_spans():
57+
path_to_sample_documents = os.path.abspath(
58+
os.path.join(
59+
os.path.abspath(__file__),
60+
"..",
61+
"..",
62+
"./sample_forms/forms/Form_1.jpg",
63+
)
64+
)
65+
66+
from azure.core.credentials import AzureKeyCredential
67+
from azure.ai.formrecognizer import DocumentAnalysisClient
68+
69+
endpoint = os.environ["AZURE_FORM_RECOGNIZER_ENDPOINT"]
70+
key = os.environ["AZURE_FORM_RECOGNIZER_KEY"]
71+
72+
document_analysis_client = DocumentAnalysisClient(
73+
endpoint=endpoint, credential=AzureKeyCredential(key)
74+
)
75+
with open(path_to_sample_documents, "rb") as f:
76+
poller = document_analysis_client.begin_analyze_document(
77+
"prebuilt-document", document=f
78+
)
79+
result = poller.result()
80+
81+
# Below is a method to search for the lines of a particular element by using spans.
82+
# This example uses DocumentTable, but other elements that also have a `spans` or `span` field
83+
# can also be used to search for related elements, such as lines in this case.
84+
# To see an example for searching for words which have a `span` field, see
85+
# `sample_get_words_on_document_line.py` under the samples v3.2-beta directory.
86+
for table_idx, table in enumerate(result.tables):
87+
print(
88+
"Table # {} has {} rows and {} columns".format(
89+
table_idx, table.row_count, table.column_count
90+
)
91+
)
92+
93+
lines = []
94+
95+
for region in table.bounding_regions:
96+
print(
97+
"Table # {} location on page: {}".format(
98+
table_idx,
99+
region.page_number,
100+
)
101+
)
102+
lines.extend(get_lines(table.spans, get_page(region.page_number, result.pages)))
103+
104+
print("Found # {} lines in the table".format(len(lines)))
105+
for line in lines:
106+
print(
107+
"...Line '{}' is within bounding box: '{}'".format(
108+
line.content,
109+
line.bounding_box,
110+
)
111+
)
112+
113+
# Below is a method to search for the style of a particular element by using spans.
114+
# This example uses DocumentEntity, but other elements that also have a `spans` or `span`
115+
# field can also be used to search for document text style.
116+
for entity in result.entities:
117+
styles = get_styles(entity.spans, result.styles)
118+
print(
119+
"Found entity '{}' of type '{}' with style:".format(
120+
entity.content, entity.category,
121+
)
122+
)
123+
if not styles:
124+
print(
125+
"...no handwritten text found"
126+
)
127+
for style in styles:
128+
if style.is_handwritten:
129+
print(
130+
"...handwritten with confidence {}".format(style.confidence)
131+
)
132+
print("----------------------------------------")
133+
134+
135+
if __name__ == "__main__":
136+
get_elements_with_spans()

0 commit comments

Comments
 (0)