Skip to content

Commit

Permalink
[formrecognizer] Add missing pages comments and tests (#17197)
Browse files Browse the repository at this point in the history
* add missing pages comments

* update polling declaration in fr clients in custom forms

* adding tests and recordings

* updating changelog

* remove extra pages tests in content tests
  • Loading branch information
catalinaperalta authored Mar 12, 2021
1 parent 81129a4 commit 46d6979
Show file tree
Hide file tree
Showing 43 changed files with 4,421 additions and 36 deletions.
2 changes: 2 additions & 0 deletions sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

- 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.
- 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.

**Dependency Updates**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ def begin_recognize_business_cards(self, business_card, **kwargs):
:keyword bool include_field_elements:
Whether or not to include all lines per page and field elements such as lines, words,
and selection marks for each form field.
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword content_type: Content-type of the body sent to the API. Content-type is
auto-detected, but can be overridden by passing this keyword argument. For options,
see :class:`~azure.ai.formrecognizer.FormContentType`.
Expand Down Expand Up @@ -305,6 +308,9 @@ def begin_recognize_business_cards_from_url(self, business_card_url, **kwargs):
:keyword bool include_field_elements:
Whether or not to include all lines per page and field elements such as lines, words,
and selection marks for each form field.
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword int polling_interval: Waiting time between two polls for LRO operations
if no Retry-After header is present. Defaults to 5 seconds.
:keyword str continuation_token: A continuation token to restart a poller from a saved state.
Expand Down Expand Up @@ -467,6 +473,9 @@ def begin_recognize_invoices(self, invoice, **kwargs):
:keyword bool include_field_elements:
Whether or not to include all lines per page and field elements such as lines, words,
and selection marks for each form field.
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword content_type: Content-type of the body sent to the API. Content-type is
auto-detected, but can be overridden by passing this keyword argument. For options,
see :class:`~azure.ai.formrecognizer.FormContentType`.
Expand Down Expand Up @@ -533,6 +542,9 @@ def begin_recognize_invoices_from_url(self, invoice_url, **kwargs):
:keyword bool include_field_elements:
Whether or not to include all lines per page and field elements such as lines, words,
and selection marks for each form field.
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword int polling_interval: Waiting time between two polls for LRO operations
if no Retry-After header is present. Defaults to 5 seconds.
:keyword str continuation_token: A continuation token to restart a poller from a saved state.
Expand Down Expand Up @@ -749,15 +761,6 @@ def begin_recognize_custom_forms(self, model_id, form, **kwargs):
raise ValueError("model_id cannot be None or empty.")

pages = kwargs.pop("pages", None)
# FIXME: part of this code will be removed once autorest can handle diff mixin
# signatures across API versions
if pages:
if self._api_version == FormRecognizerApiVersion.V2_1_PREVIEW:
kwargs.update({"pages": pages})
else:
raise ValueError(
"'pages' is only available for API version V2_1_PREVIEW and up"
)
polling_interval = kwargs.pop(
"polling_interval", self._client._config.polling_interval
)
Expand All @@ -767,11 +770,25 @@ def begin_recognize_custom_forms(self, model_id, form, **kwargs):
raise TypeError(
"Call begin_recognize_custom_forms_from_url() to analyze a document from a URL."
)

include_field_elements = kwargs.pop("include_field_elements", False)
if content_type is None and continuation_token is None:
content_type = get_content_type(form)

include_field_elements = kwargs.pop("include_field_elements", False)

polling = LROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
)

# FIXME: part of this code will be removed once autorest can handle diff mixin
# signatures across API versions
if pages:
if self._api_version == FormRecognizerApiVersion.V2_1_PREVIEW:
kwargs.update({"pages": pages})
else:
raise ValueError(
"'pages' is only available for API version V2_1_PREVIEW and up"
)

def analyze_callback(
raw_response, _, headers
): # pylint: disable=unused-argument
Expand All @@ -786,9 +803,7 @@ def analyze_callback(
include_text_details=include_field_elements,
content_type=content_type,
cls=kwargs.pop("cls", analyze_callback),
polling=LROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
),
polling=polling,
continuation_token=continuation_token,
**kwargs
)
Expand Down Expand Up @@ -822,6 +837,16 @@ def begin_recognize_custom_forms_from_url(self, model_id, form_url, **kwargs):
raise ValueError("model_id cannot be None or empty.")

pages = kwargs.pop("pages", None)
continuation_token = kwargs.pop("continuation_token", None)
include_field_elements = kwargs.pop("include_field_elements", False)
polling_interval = kwargs.pop(
"polling_interval", self._client._config.polling_interval
)

polling = LROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
)

# FIXME: part of this code will be removed once autorest can handle diff mixin
# signatures across API versions
if pages:
Expand All @@ -831,11 +856,6 @@ def begin_recognize_custom_forms_from_url(self, model_id, form_url, **kwargs):
raise ValueError(
"'pages' is only available for API version V2_1_PREVIEW and up"
)
polling_interval = kwargs.pop(
"polling_interval", self._client._config.polling_interval
)
continuation_token = kwargs.pop("continuation_token", None)
include_field_elements = kwargs.pop("include_field_elements", False)

def analyze_callback(
raw_response, _, headers
Expand All @@ -850,9 +870,7 @@ def analyze_callback(
model_id=model_id,
include_text_details=include_field_elements,
cls=kwargs.pop("cls", analyze_callback),
polling=LROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
),
polling=polling,
continuation_token=continuation_token,
**kwargs
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ async def begin_recognize_business_cards(
auto-detected, but can be overridden by passing this keyword argument. For options,
see :class:`~azure.ai.formrecognizer.FormContentType`.
:paramtype content_type: str or ~azure.ai.formrecognizer.FormContentType
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword int polling_interval: Waiting time between two polls for LRO operations
if no Retry-After header is present. Defaults to 5 seconds.
:keyword str continuation_token: A continuation token to restart a poller from a saved state.
Expand Down Expand Up @@ -312,6 +315,9 @@ async def begin_recognize_business_cards_from_url(
:keyword bool include_field_elements:
Whether or not to include all lines per page and field elements such as lines, words,
and selection marks for each form field.
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword int polling_interval: Waiting time between two polls for LRO operations
if no Retry-After header is present. Defaults to 5 seconds.
:keyword str continuation_token: A continuation token to restart a poller from a saved state.
Expand Down Expand Up @@ -481,6 +487,9 @@ async def begin_recognize_invoices(
auto-detected, but can be overridden by passing this keyword argument. For options,
see :class:`~azure.ai.formrecognizer.FormContentType`.
:paramtype content_type: str or ~azure.ai.formrecognizer.FormContentType
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword int polling_interval: Waiting time between two polls for LRO operations
if no Retry-After header is present. Defaults to 5 seconds.
:keyword str continuation_token: A continuation token to restart a poller from a saved state.
Expand Down Expand Up @@ -544,6 +553,9 @@ async def begin_recognize_invoices_from_url(
:keyword bool include_field_elements:
Whether or not to include all lines per page and field elements such as lines, words,
and selection marks for each form field.
:keyword list[str] pages: Custom page numbers for multi-page documents(PDF/TIFF). Input the page numbers
and/or ranges of pages you want to get in the result. For a range of pages, use a hyphen, like
`pages=["1-3", "5-6"]`. Separate each page number or range with a comma.
:keyword int polling_interval: Waiting time between two polls for LRO operations
if no Retry-After header is present. Defaults to 5 seconds.
:keyword str continuation_token: A continuation token to restart a poller from a saved state.
Expand Down Expand Up @@ -771,8 +783,15 @@ async def begin_recognize_custom_forms(
raise TypeError(
"Call begin_recognize_custom_forms_from_url() to analyze a document from a URL."
)
if content_type is None and continuation_token is None:
content_type = get_content_type(form)

pages = kwargs.pop("pages", None)
include_field_elements = kwargs.pop("include_field_elements", False)

polling = AsyncLROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
)

# FIXME: part of this code will be removed once autorest can handle diff mixin
# signatures across API versions
Expand All @@ -784,10 +803,6 @@ async def begin_recognize_custom_forms(
"'pages' is only available for API version V2_1_PREVIEW and up"
)

include_field_elements = kwargs.pop("include_field_elements", False)
if content_type is None and continuation_token is None:
content_type = get_content_type(form)

def analyze_callback(
raw_response, _, headers
): # pylint: disable=unused-argument
Expand All @@ -802,9 +817,7 @@ def analyze_callback(
include_text_details=include_field_elements,
content_type=content_type,
cls=kwargs.pop("cls", analyze_callback),
polling=AsyncLROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
),
polling=polling,
continuation_token=continuation_token,
**kwargs
)
Expand Down Expand Up @@ -842,6 +855,12 @@ async def begin_recognize_custom_forms_from_url(
)

pages = kwargs.pop("pages", None)
continuation_token = kwargs.pop("continuation_token", None)
include_field_elements = kwargs.pop("include_field_elements", False)

polling = AsyncLROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
)

# FIXME: part of this code will be removed once autorest can handle diff mixin
# signatures across API versions
Expand All @@ -853,9 +872,6 @@ async def begin_recognize_custom_forms_from_url(
"'pages' is only available for API version V2_1_PREVIEW and up"
)

continuation_token = kwargs.pop("continuation_token", None)
include_field_elements = kwargs.pop("include_field_elements", False)

def analyze_callback(
raw_response, _, headers
): # pylint: disable=unused-argument
Expand All @@ -869,9 +885,7 @@ def analyze_callback(
model_id=model_id,
include_text_details=include_field_elements,
cls=kwargs.pop("cls", analyze_callback),
polling=AsyncLROBasePolling(
timeout=polling_interval, lro_algorithms=[AnalyzePolling()], **kwargs
),
polling=polling,
continuation_token=continuation_token,
**kwargs
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
interactions:
- request:
body: '!!! The request body has been omitted from the recording because its size
915108 is larger than 128KB. !!!'
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Length:
- '915108'
Content-Type:
- image/jpeg
User-Agent:
- azsdk-python-ai-formrecognizer/3.1.0b4 Python/3.8.5 (Windows-10-10.0.19041-SP0)
method: POST
uri: https://region.api.cognitive.microsoft.com/formrecognizer/v2.1-preview.3/prebuilt/businessCard/analyze?includeTextDetails=false&pages=1
response:
body:
string: ''
headers:
apim-request-id:
- e800b802-37c0-46c9-9381-7f3670e3e8e4
content-length:
- '0'
date:
- Thu, 11 Mar 2021 17:47:07 GMT
operation-location:
- https://region.api.cognitive.microsoft.com/formrecognizer/v2.1-preview.3/prebuilt/businessCard/analyzeResults/e800b802-37c0-46c9-9381-7f3670e3e8e4
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-content-type-options:
- nosniff
x-envoy-upstream-service-time:
- '454'
status:
code: 202
message: Accepted
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- azsdk-python-ai-formrecognizer/3.1.0b4 Python/3.8.5 (Windows-10-10.0.19041-SP0)
method: GET
uri: https://region.api.cognitive.microsoft.com/formrecognizer/v2.1-preview.3/prebuilt/businessCard/analyzeResults/e800b802-37c0-46c9-9381-7f3670e3e8e4
response:
body:
string: '{"status": "succeeded", "createdDateTime": "2021-03-11T17:47:07Z",
"lastUpdatedDateTime": "2021-03-11T17:47:11Z", "analyzeResult": {"version":
"2.1.0", "readResults": [{"page": 1, "angle": -16.6836, "width": 4032, "height":
3024, "unit": "pixel"}], "documentResults": [{"docType": "prebuilt:businesscard",
"pageRange": [1, 1], "fields": {"Addresses": {"type": "array", "valueArray":
[{"type": "string", "valueString": "2 Kingdom Street Paddington, London, W2
6BD", "text": "2 Kingdom Street Paddington, London, W2 6BD", "boundingBox":
[1227.3, 2138.3, 2520.2, 1690.5, 2597, 1912.3, 1304.1, 2360.1], "page": 1,
"confidence": 0.98}]}, "CompanyNames": {"type": "array", "valueArray": [{"type":
"string", "valueString": "Contoso", "text": "Contoso", "boundingBox": [1146,
1926, 2224, 1587, 2285, 1756, 1202, 2099], "page": 1, "confidence": 0.168}]},
"ContactNames": {"type": "array", "valueArray": [{"type": "object", "valueObject":
{"FirstName": {"type": "string", "valueString": "Avery", "text": "Avery",
"boundingBox": [666, 1102, 1111, 995, 1140, 1114, 696, 1216], "page": 1},
"LastName": {"type": "string", "valueString": "Smith", "text": "Smith", "boundingBox":
[1170, 981, 1571, 881, 1600, 1000, 1200, 1100], "page": 1}}, "text": "Dr.
Avery Smith", "boundingBox": [414.1, 1153, 1572, 880.8, 1601.3, 1005.6, 443.5,
1277.9], "page": 1, "confidence": 0.979}]}, "Departments": {"type": "array",
"valueArray": [{"type": "string", "valueString": "Cloud & Al Department",
"text": "Cloud & Al Department", "boundingBox": [473.6, 1409.5, 1586, 1134,
1607.3, 1219.8, 494.9, 1495.3], "page": 1, "confidence": 0.989}]}, "Emails":
{"type": "array", "valueArray": [{"type": "string", "valueString": "[email protected]",
"text": "[email protected]", "boundingBox": [2106, 934, 2908, 706, 2921,
769, 2122, 993], "page": 1, "confidence": 0.99}]}, "Faxes": {"type": "array",
"valueArray": [{"type": "phoneNumber", "text": "+44 (0) 20 6789 2345", "boundingBox":
[2520.4, 1195.5, 3191.8, 983.5, 3215.8, 1059.2, 2544.3, 1271.3], "page": 1,
"confidence": 0.99}]}, "JobTitles": {"type": "array", "valueArray": [{"type":
"string", "valueString": "Senior Researcher", "text": "Senior Researcher",
"boundingBox": [451, 1312, 1315.9, 1103.6, 1334.7, 1181.7, 469.8, 1390], "page":
1, "confidence": 0.99}]}, "MobilePhones": {"type": "array", "valueArray":
[{"type": "phoneNumber", "text": "+44 (0) 7911 123456", "boundingBox": [2426.8,
1040.1, 3065.5, 846, 3087.2, 917.6, 2448.5, 1111.7], "page": 1, "confidence":
0.99}]}, "Websites": {"type": "array", "valueArray": [{"type": "string", "valueString":
"https://www.contoso.com/", "text": "https://www.contoso.com/", "boundingBox":
[2120, 1003, 2981, 757, 3006, 824, 2139, 1075], "page": 1, "confidence": 0.99}]},
"WorkPhones": {"type": "array", "valueArray": [{"type": "phoneNumber", "text":
"+44 (0) 20 9876 5432", "boundingBox": [2468.2, 1118.1, 3130.3, 914.6, 3152.9,
988.2, 2490.8, 1191.6], "page": 1, "confidence": 0.989}]}}}]}}'
headers:
apim-request-id:
- 1b20e12c-ddd7-4ca4-80bc-35b899311ddd
content-length:
- '2684'
content-type:
- application/json; charset=utf-8
date:
- Thu, 11 Mar 2021 17:47:12 GMT
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-content-type-options:
- nosniff
x-envoy-upstream-service-time:
- '18'
status:
code: 200
message: OK
version: 1
Loading

0 comments on commit 46d6979

Please sign in to comment.