Skip to content
100 changes: 100 additions & 0 deletions sdk/formrecognizer/azure-ai-formrecognizer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,106 @@ except ResourceNotFoundError:
print("Successfully deleted model with id {}".format(custom_model.model_id))
```

### Convenience methods to get items from a specific model (**Beta feature**)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I thought when you said README you meant add get_lines() and get_words() to the existing examples. Do you think adding a dedicated sample with this info could work? which we could link to from the readme? We've gotten feedback to keep READMEs brief / focused on the big features so I'm not sure this is the right place for it.
Adding @maririos @kinelski @samvaity @witemple-msft for more perspectives on how they plan to show the feature.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that sounds better, will update.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, removed from the readme but added a get words in one of the examples.


In version `azure-ai-formrecognizer (3.2.0b2)`, the following models have a `get_words()` convenience method:
- `AnalyzedDocument`
- `DocumentEntity`
- `DocumentField`
- `DocumentLine`
- `DocumentKeyValueElement`
- `DocumentTable`
- `DocumentTableCell`

The `get_words()` method can be used to obtain the words that are found within the same area of the document element that the call is made on.

For instance, in the example below `get_words()` is called on every document line that is processed:
```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 page in result.pages:
print("----Analyzing document from page #{}----".format(page.page_number))

for line_idx, line in enumerate(page.lines):
words = line.get_words()

print(
"...Line # {} has word count {} and text '{}' within bounding box '{}'".format(
line_idx,
len(words),
line.content,
format_bounding_box(line.bounding_box),
)
)

# print every word found for this line
for word in words:
print(
"......Word '{}' has a confidence of {}".format(
word.content, word.confidence
)
)
```


Likewise, in version `azure-ai-formrecognizer (3.2.0b2)`, the following models have a `get_lines()` convenience method:
- `AnalyzedDocument`
- `DocumentEntity`
- `DocumentField`
- `DocumentKeyValueElement`
- `DocumentTable`
- `DocumentTableCell`

The `get_lines()` method can be used to obtain the lines that are found within the same area of the document element that the call is made on.

For instance, in the example below `get_lines()` is called on every document entity that is processed:
```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()

print("----Entities found in document----")
for entity in result.entities:
print("Entity of category '{}' with sub-category '{}'".format(entity.category, entity.sub_category))
# NOTE: Calling get_lines() here will return a list of the DocumentLines that make up the entity.
# These lines can be processed just like any other DocumentLine instance.
lines = entity.get_lines()

# print every line found for this document entity
for line in lines:
print(
"...Line has '{}' text and is within bounding box '{}'".format(
line.content,
line.bounding_box,
)
)
```


## Troubleshooting

### General
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ async def analyze_general_documents():
print("----Entities found in document----")
for entity in result.entities:
print("Entity of category '{}' with sub-category '{}'".format(entity.category, entity.sub_category))
# NOTE: Calling get_lines() here will return a list of the DocumentLines that make up the entity.
# These lines can be processed just like any other DocumentLine instance.
line_length = len(entity.get_lines())
if line_length > 0:
print("...has {} line(s)".format(line_length))
Comment thread
catalinaperalta marked this conversation as resolved.
Outdated
print("...has content '{}'".format(entity.content))
print("...within '{}' bounding regions".format(format_bounding_region(entity.bounding_regions)))
print("...with confidence {}\n".format(entity.confidence))
Expand All @@ -101,20 +106,22 @@ async def analyze_general_documents():
)

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

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

for selection_mark in page.selection_marks:
print(
Expand All @@ -131,6 +138,11 @@ async def analyze_general_documents():
table_idx, table.row_count, table.column_count
)
)
print(
"Table # {} has {} lines and {} words".format(
table_idx, len(table.get_lines()), len(table.get_words())
)
)
for region in table.bounding_regions:
print(
"Table # {} location on page: {} is {}".format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,22 @@ async def analyze_layout_async():
)

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

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

for selection_mark in page.selection_marks:
print(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ def analyze_general_documents():
print("----Entities found in document----")
for entity in result.entities:
print("Entity of category '{}' with sub-category '{}'".format(entity.category, entity.sub_category))
# NOTE: Calling get_lines() here will return a list of the DocumentLines that make up the entity.
# These lines can be processed just like any other DocumentLine instance.
line_length = len(entity.get_lines())
if line_length > 0:
print("...has {} line(s)".format(line_length))
print("...has content '{}'".format(entity.content))
print("...within '{}' bounding regions".format(format_bounding_region(entity.bounding_regions)))
print("...with confidence {}\n".format(entity.confidence))
Expand All @@ -97,20 +102,22 @@ def analyze_general_documents():
)

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

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

for selection_mark in page.selection_marks:
print(
Expand All @@ -127,6 +134,11 @@ def analyze_general_documents():
table_idx, table.row_count, table.column_count
)
)
print(
"Table # {} has {} lines and {} words".format(
table_idx, len(table.get_lines()), len(table.get_words())
)
)
for region in table.bounding_regions:
print(
"Table # {} location on page: {} is {}".format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,22 @@ def analyze_layout():
)

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

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

for selection_mark in page.selection_marks:
print(
Expand Down