Skip to content

Commit 4e43eb0

Browse files
[formrecognizer] Fix dictionary methods on DocumentField model (#23673)
* add fix for dict and list methods * improve testing * add invoice tests * update changelog * remove extra invoice test * update tests to use AzureJSONEncoder * move currency value in if * pylint fix
1 parent 68dda72 commit 4e43eb0

4 files changed

Lines changed: 38 additions & 3 deletions

File tree

sdk/formrecognizer/azure-ai-formrecognizer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Renamed `model_count` and `model_limit` on `AccountInfo` to `document_model_count` and `document_model_limit`.
1111

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

1415
### Other Changes
1516
- 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.

sdk/formrecognizer/azure-ai-formrecognizer/azure/ai/formrecognizer/_models.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,9 +2598,18 @@ def to_dict(self):
25982598
:return: dict
25992599
:rtype: dict
26002600
"""
2601+
value = self.value
2602+
# CurrencyValue objects are interpreted as dict, therefore need to be processed first
2603+
# to call the proper to_dict() method.
2604+
if self.value_type == "currency":
2605+
value = self.value.to_dict()
2606+
elif isinstance(self.value, dict):
2607+
value = {k: v.to_dict() for k, v in self.value.items()}
2608+
elif isinstance(self.value, list):
2609+
value = [v.to_dict() for v in self.value]
26012610
return {
26022611
"value_type": self.value_type,
2603-
"value": self.value,
2612+
"value": value,
26042613
"content": self.content,
26052614
"bounding_regions": [f.to_dict() for f in self.bounding_regions]
26062615
if self.bounding_regions
@@ -2620,9 +2629,20 @@ def from_dict(cls, data):
26202629
:return: DocumentField
26212630
:rtype: DocumentField
26222631
"""
2632+
2633+
value = data.get("value", None)
2634+
# CurrencyValue objects are interpreted as dict, therefore need to be processed first
2635+
# to call the proper from_dict() method.
2636+
if data.get("value_type", None) == "currency":
2637+
value = CurrencyValue.from_dict(data.get("value")) #type: ignore
2638+
elif isinstance(data.get("value"), dict):
2639+
value = {k: DocumentField.from_dict(v) for k, v in data.get("value").items()} # type: ignore
2640+
elif isinstance(data.get("value"), list):
2641+
value = [DocumentField.from_dict(v) for v in data.get("value")] # type: ignore
2642+
26232643
return cls(
26242644
value_type=data.get("value_type", None),
2625-
value=data.get("value", None),
2645+
value=value,
26262646
content=data.get("content", None),
26272647
bounding_regions=[BoundingRegion.from_dict(v) for v in data.get("bounding_regions")] # type: ignore
26282648
if len(data.get("bounding_regions", [])) > 0
@@ -2880,7 +2900,7 @@ class DocumentPage(object):
28802900
:vartype width: float
28812901
:ivar height: The height of the image/PDF in pixels/inches, respectively.
28822902
:vartype height: float
2883-
:ivar unit: The unit used by the width, height, and boundingBox properties. For
2903+
:ivar unit: The unit used by the width, height, and bounding box properties. For
28842904
images, the unit is "pixel". For PDF, the unit is "inch". Possible values include: "pixel",
28852905
"inch".
28862906
:vartype unit: str

sdk/formrecognizer/azure-ai-formrecognizer/tests/test_dac_analyze_prebuilts.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
# ------------------------------------
66

77
import pytest
8+
import json
89
import functools
910
from datetime import date, time
1011
from devtools_testutils import recorded_by_proxy
1112
from io import BytesIO
1213
from azure.core.exceptions import ClientAuthenticationError, ServiceRequestError, HttpResponseError
1314
from azure.core.credentials import AzureKeyCredential
15+
from azure.core.serialization import AzureJSONEncoder
1416
from azure.ai.formrecognizer._generated.v2022_01_30_preview.models import AnalyzeResultOperation
1517
from azure.ai.formrecognizer import DocumentAnalysisClient, AnalyzeResult, FormContentType
1618
from testcase import FormRecognizerTest
@@ -182,6 +184,9 @@ def test_invoice_jpg(self, client, **kwargs):
182184
poller = client.begin_analyze_document("prebuilt-invoice", invoice)
183185

184186
result = poller.result()
187+
d = result.to_dict()
188+
json.dumps(d, cls=AzureJSONEncoder)
189+
result = AnalyzeResult.from_dict(d)
185190
assert len(result.documents) == 1
186191
invoice = result.documents[0]
187192

@@ -419,6 +424,8 @@ def test_receipt_multipage(self, client):
419424
result = poller.result()
420425

421426
d = result.to_dict()
427+
# this is simply checking that the dict is JSON serializable
428+
json.dumps(d, cls=AzureJSONEncoder)
422429
result = AnalyzeResult.from_dict(d)
423430

424431
assert len(result.documents) == 2

sdk/formrecognizer/azure-ai-formrecognizer/tests/test_dac_analyze_prebuilts_async.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
# ------------------------------------
66

77
import pytest
8+
import json
89
import functools
910
from io import BytesIO
1011
from devtools_testutils.aio import recorded_by_proxy_async
1112
from datetime import date, time
1213
from azure.core.exceptions import HttpResponseError
14+
from azure.core.serialization import AzureJSONEncoder
1315
from azure.ai.formrecognizer.aio import DocumentAnalysisClient
1416
from azure.ai.formrecognizer import AnalyzeResult
1517
from azure.ai.formrecognizer._generated.v2022_01_30_preview.models import AnalyzeResultOperation
@@ -210,6 +212,8 @@ async def test_receipt_multipage(self, client):
210212
result = await poller.result()
211213

212214
d = result.to_dict()
215+
# this is simply checking that the dict is JSON serializable
216+
json.dumps(d, cls=AzureJSONEncoder)
213217
result = AnalyzeResult.from_dict(d)
214218

215219
assert len(result.documents) == 2
@@ -491,6 +495,9 @@ async def test_invoice_jpg(self, client, **kwargs):
491495
poller = await client.begin_analyze_document("prebuilt-invoice", invoice)
492496

493497
result = await poller.result()
498+
d = result.to_dict()
499+
json.dumps(d, cls=AzureJSONEncoder)
500+
result = AnalyzeResult.from_dict(d)
494501
assert len(result.documents) == 1
495502
invoice = result.documents[0]
496503

0 commit comments

Comments
 (0)