Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -19,6 +19,8 @@
- For recognize receipt methods, parameters have been renamed to `receipt` and `receipt_url`.
- `created_on` and `last_modified` are renamed to `requested_on` and `completed_on` in the
`CustomFormModel` and `CustomFormModelInfo` models.
- `models` property of `CustomFormModel` is renamed to `submodels`
- `CustomFormSubModel` is renamed to `CustomFormSubmodel`

**New features**

Expand Down
8 changes: 4 additions & 4 deletions sdk/formrecognizer/azure-ai-formrecognizer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ az cognitiveservices account show --name "resource-name" --resource-group "resou
```

#### Types of credentials
The `credential` parameter may be provided as a [AzureKeyCredential][azure-key-credential] from [azure.core][azure_core],
The `credential` parameter may be provided as a [AzureKeyCredential][azure-key-credential] from [azure.core][azure_core],
or as a credential type from Azure Active Directory.
See the full details regarding [authentication][cognitive_authentication] of cognitive services.

Expand All @@ -75,12 +75,12 @@ See the full details regarding [authentication][cognitive_authentication] of cog
The API key can be found in the Azure Portal or by running the following Azure CLI command:

```az cognitiveservices account keys list --name "resource-name" --resource-group "resource-group-name"```

Use the key as the credential parameter to authenticate the client:
```python
from azure.ai.formrecognizer import FormRecognizerClient
from azure.core.credentials import AzureKeyCredential

endpoint = "https://<region>.api.cognitive.microsoft.com/"
credential = AzureKeyCredential("<api_key>")
form_recognizer_client = FormRecognizerClient(endpoint, credential)
Expand Down Expand Up @@ -270,7 +270,7 @@ print("Completed on: {}".format(model.completed_on))

print("Recognized fields:")
# looping through the submodels, which contains the fields they were trained on
for submodel in model.models:
for submodel in model.submodels:
print("The submodel with form type '{}' has recognized the following fields: {}".format(
submodel.form_type,
", ".join([label for label in submodel.fields])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
FormLine,
FormWord,
CustomFormModel,
CustomFormSubModel,
CustomFormSubmodel,
CustomFormModelField
)

Expand Down Expand Up @@ -63,7 +63,7 @@
'FormLine',
'FormWord',
'CustomFormModel',
'CustomFormSubModel',
'CustomFormSubmodel',
'CustomFormModelField'
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ class CustomFormModel(object):
The date and time (UTC) when model training was requested.
:ivar ~datetime.datetime completed_on:
Date and time (UTC) when model training completed.
:ivar list[~azure.ai.formrecognizer.CustomFormSubModel] models:
:ivar list[~azure.ai.formrecognizer.CustomFormSubmodel] submodels:
A list of submodels that are part of this model, each of
which can recognize and extract fields from a different type of form.
:ivar list[~azure.ai.formrecognizer.FormRecognizerError] errors:
Expand All @@ -690,7 +690,7 @@ def __init__(self, **kwargs):
self.status = kwargs.get("status", None)
self.requested_on = kwargs.get("requested_on", None)
self.completed_on = kwargs.get("completed_on", None)
self.models = kwargs.get("models", None)
self.submodels = kwargs.get("submodels", None)
self.errors = kwargs.get("errors", None)
self.training_documents = kwargs.get("training_documents", [])

Expand All @@ -701,22 +701,22 @@ def _from_generated(cls, model):
status=model.model_info.status,
requested_on=model.model_info.created_date_time,
completed_on=model.model_info.last_updated_date_time,
models=CustomFormSubModel._from_generated_unlabeled(model)
if model.keys else CustomFormSubModel._from_generated_labeled(model),
submodels=CustomFormSubmodel._from_generated_unlabeled(model)
if model.keys else CustomFormSubmodel._from_generated_labeled(model),
errors=FormRecognizerError._from_generated(model.train_result.errors) if model.train_result else None,
training_documents=TrainingDocumentInfo._from_generated(model.train_result)
if model.train_result else None
)

def __repr__(self):
return "CustomFormModel(model_id={}, status={}, requested_on={}, completed_on={}, models={}, " \
return "CustomFormModel(model_id={}, status={}, requested_on={}, completed_on={}, submodels={}, " \
"errors={}, training_documents={})".format(
self.model_id, self.status, self.requested_on, self.completed_on, repr(self.models),
self.model_id, self.status, self.requested_on, self.completed_on, repr(self.submodels),
repr(self.errors), repr(self.training_documents)
)[:1024]


class CustomFormSubModel(object):
class CustomFormSubmodel(object):
"""Represents a submodel that extracts fields from a specific type of form.

:ivar float accuracy: The mean of the model's field accuracies.
Expand Down Expand Up @@ -751,7 +751,7 @@ def _from_generated_labeled(cls, model):
)] if model.train_result else None

def __repr__(self):
return "CustomFormSubModel(accuracy={}, fields={}, form_type={})".format(
return "CustomFormSubmodel(accuracy={}, fields={}, form_type={})".format(
self.accuracy, repr(self.fields), self.form_type
)[:1024]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ async def train_model_with_labels(self):
print("Recognized fields:")
# looping through the submodels, which contains the fields they were trained on
# The labels are based on the ones you gave the training document.
for submodel in model.models:
for submodel in model.submodels:
print("...The submodel with form type {} has accuracy '{}'".format(submodel.form_type, submodel.accuracy))
for name, field in submodel.fields.items():
print("...The model found field '{}' to have name '{}' with an accuracy of {}".format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async def train_model_without_labels(self):

print("Recognized fields:")
# Looping through the submodels, which contains the fields they were trained on
for submodel in model.models:
for submodel in model.submodels:
print("...The submodel has form type '{}'".format(submodel.form_type))
for name, field in submodel.fields.items():
print("...The model found field '{}' to have label '{}'".format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def train_model_with_labels(self):
print("Recognized fields:")
# looping through the submodels, which contains the fields they were trained on
# The labels are based on the ones you gave the training document.
for submodel in model.models:
for submodel in model.submodels:
print("...The submodel with form type {} has accuracy '{}'".format(submodel.form_type, submodel.accuracy))
for name, field in submodel.fields.items():
print("...The model found field '{}' to have name '{}' with an accuracy of {}".format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def train_model_without_labels(self):

print("Recognized fields:")
# Looping through the submodels, which contains the fields they were trained on
for submodel in model.models:
for submodel in model.submodels:
print("...The submodel has form type '{}'".format(submodel.form_type))
for name, field in submodel.fields.items():
print("...The model found field '{}' to have label '{}'".format(
Expand Down
4 changes: 2 additions & 2 deletions sdk/formrecognizer/azure-ai-formrecognizer/tests/test_mgmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def test_mgmt_model_labeled(self, client, container_sas_url):
self.assertEqual(a.errors, b.errors)
self.assertEqual(a.page_count, b.page_count)
self.assertEqual(a.status, b.status)
for a, b in zip(labeled_model_from_train.models, labeled_model_from_get.models):
for a, b in zip(labeled_model_from_train.submodels, labeled_model_from_get.submodels):
for field1, field2 in zip(a.fields.items(), b.fields.items()):
self.assertEqual(a.fields[field1[0]].name, b.fields[field2[0]].name)
self.assertEqual(a.fields[field1[0]].accuracy, b.fields[field2[0]].accuracy)
Expand Down Expand Up @@ -131,7 +131,7 @@ def test_mgmt_model_unlabeled(self, client, container_sas_url):
self.assertEqual(a.errors, b.errors)
self.assertEqual(a.page_count, b.page_count)
self.assertEqual(a.status, b.status)
for a, b in zip(unlabeled_model_from_train.models, unlabeled_model_from_get.models):
for a, b in zip(unlabeled_model_from_train.submodels, unlabeled_model_from_get.submodels):
for field1, field2 in zip(a.fields.items(), b.fields.items()):
self.assertEqual(a.fields[field1[0]].label, b.fields[field2[0]].label)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ async def test_mgmt_model_labeled(self, client, container_sas_url):
self.assertEqual(a.errors, b.errors)
self.assertEqual(a.page_count, b.page_count)
self.assertEqual(a.status, b.status)
for a, b in zip(labeled_model_from_train.models, labeled_model_from_get.models):
for a, b in zip(labeled_model_from_train.submodels, labeled_model_from_get.submodels):
for field1, field2 in zip(a.fields.items(), b.fields.items()):
self.assertEqual(a.fields[field1[0]].name, b.fields[field2[0]].name)
self.assertEqual(a.fields[field1[0]].accuracy, b.fields[field2[0]].accuracy)
Expand Down Expand Up @@ -129,7 +129,7 @@ async def test_mgmt_model_unlabeled(self, client, container_sas_url):
self.assertEqual(a.errors, b.errors)
self.assertEqual(a.page_count, b.page_count)
self.assertEqual(a.status, b.status)
for a, b in zip(unlabeled_model_from_train.models, unlabeled_model_from_get.models):
for a, b in zip(unlabeled_model_from_train.submodels, unlabeled_model_from_get.submodels):
for field1, field2 in zip(a.fields.items(), b.fields.items()):
self.assertEqual(a.fields[field1[0]].label, b.fields[field2[0]].label)

Expand Down
8 changes: 4 additions & 4 deletions sdk/formrecognizer/azure-ai-formrecognizer/tests/test_repr.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ def custom_form_model_field():

@pytest.fixture
def custom_form_sub_model(custom_form_model_field):
model = _models.CustomFormSubModel(accuracy=0.99, fields={"name": custom_form_model_field[0]}, form_type="Itemized")
model_repr = "CustomFormSubModel(accuracy=0.99, fields={{'name': {}}}, form_type=Itemized)".format(custom_form_model_field[1])[:1024]
model = _models.CustomFormSubmodel(accuracy=0.99, fields={"name": custom_form_model_field[0]}, form_type="Itemized")
model_repr = "CustomFormSubmodel(accuracy=0.99, fields={{'name': {}}}, form_type=Itemized)".format(custom_form_model_field[1])[:1024]
assert repr(model) == model_repr
return model, model_repr

Expand Down Expand Up @@ -207,13 +207,13 @@ def test_custom_form_model(self, custom_form_sub_model, form_recognizer_error, t
status=_models.CustomFormModelStatus.creating,
requested_on=datetime.datetime(1, 1, 1),
completed_on=datetime.datetime(1, 1, 1),
models=[custom_form_sub_model[0], custom_form_sub_model[0]],
submodels=[custom_form_sub_model[0], custom_form_sub_model[0]],
errors=[form_recognizer_error[0]],
training_documents=[training_document_info[0], training_document_info[0]]
)

model_repr = "CustomFormModel(model_id=1, status=creating, requested_on=0001-01-01 00:00:00, " \
"completed_on=0001-01-01 00:00:00, models=[{}, {}], errors=[{}], training_documents=[{}, {}])".format(
"completed_on=0001-01-01 00:00:00, submodels=[{}, {}], errors=[{}], training_documents=[{}, {}])".format(
custom_form_sub_model[1], custom_form_sub_model[1], form_recognizer_error[1], training_document_info[1], training_document_info[1]
)[:1024]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_training(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertEqual(doc.status, "succeeded")
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
for key, field in sub.fields.items():
self.assertIsNotNone(field.label)
Expand All @@ -65,7 +65,7 @@ def test_training_multipage(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertIsNotNone(doc.status)
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
for key, field in sub.fields.items():
self.assertIsNotNone(field.label)
Expand Down Expand Up @@ -126,7 +126,7 @@ def test_training_with_labels(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertEqual(doc.status, "succeeded")
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
self.assertIsNotNone(sub.accuracy)
for key, field in sub.fields.items():
Expand All @@ -150,7 +150,7 @@ def test_training_multipage_with_labels(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertIsNotNone(doc.status)
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
self.assertIsNotNone(sub.accuracy)
for key, field in sub.fields.items():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async def test_training(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertEqual(doc.status, "succeeded")
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
for key, field in sub.fields.items():
self.assertIsNotNone(field.label)
Expand All @@ -65,7 +65,7 @@ async def test_training_multipage(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertIsNotNone(doc.status)
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
for key, field in sub.fields.items():
self.assertIsNotNone(field.label)
Expand Down Expand Up @@ -126,7 +126,7 @@ async def test_training_with_labels(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertEqual(doc.status, "succeeded")
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
for key, field in sub.fields.items():
self.assertIsNotNone(field.accuracy)
Expand All @@ -148,7 +148,7 @@ async def test_training_multipage_with_labels(self, client, container_sas_url):
self.assertIsNotNone(doc.page_count)
self.assertIsNotNone(doc.status)
self.assertEqual(doc.errors, [])
for sub in model.models:
for sub in model.submodels:
self.assertIsNotNone(sub.form_type)
self.assertIsNotNone(sub.accuracy)
for key, field in sub.fields.items():
Expand Down
12 changes: 6 additions & 6 deletions sdk/formrecognizer/azure-ai-formrecognizer/tests/testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,18 @@ def assertModelTransformCorrect(self, model, actual, unlabeled=False):
if unlabeled:
if actual.keys.clusters:
for cluster_id, fields in actual.keys.clusters.items():
self.assertEqual(cluster_id, model.models[int(cluster_id)].form_type[-1])
for field_idx, model_field in model.models[int(cluster_id)].fields.items():
self.assertEqual(cluster_id, model.submodels[int(cluster_id)].form_type[-1])
for field_idx, model_field in model.submodels[int(cluster_id)].fields.items():
self.assertIn(model_field.label, fields)

else:
if actual.train_result:
if actual.train_result.fields:
for a in actual.train_result.fields:
self.assertEqual(model.models[0].fields[a.field_name].name, a.field_name)
self.assertEqual(model.models[0].fields[a.field_name].accuracy, a.accuracy)
self.assertEqual(model.models[0].form_type, "form-"+model.model_id)
self.assertEqual(model.models[0].accuracy, actual.train_result.average_model_accuracy)
self.assertEqual(model.submodels[0].fields[a.field_name].name, a.field_name)
self.assertEqual(model.submodels[0].fields[a.field_name].accuracy, a.accuracy)
self.assertEqual(model.submodels[0].form_type, "form-"+model.model_id)
self.assertEqual(model.submodels[0].accuracy, actual.train_result.average_model_accuracy)

def assertFormPagesTransformCorrect(self, pages, actual_read, page_result=None, **kwargs):
for page, actual_page in zip(pages, actual_read):
Expand Down