Skip to content

Commit

Permalink
✨ add support for us mail v3
Browse files Browse the repository at this point in the history
  • Loading branch information
Mindee committed Dec 26, 2024
1 parent 30d2b9e commit 9318c94
Show file tree
Hide file tree
Showing 17 changed files with 478 additions and 19 deletions.
16 changes: 16 additions & 0 deletions docs/extras/code_samples/us_mail_v3_async.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from mindee import Client, product, AsyncPredictResponse

# Init a new client
mindee_client = Client(api_key="my-api-key")

# Load a file from disk
input_doc = mindee_client.source_from_path("/path/to/the/file.ext")

# Load a file from disk and enqueue it.
result: AsyncPredictResponse = mindee_client.enqueue_and_parse(
product.us.UsMailV3,
input_doc,
)

# Print a brief summary of the parsed data
print(result.document)
46 changes: 34 additions & 12 deletions docs/extras/guide/us_mail_v2.md → docs/extras/guide/us_mail_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ input_doc = mindee_client.source_from_path("/path/to/the/file.ext")

# Load a file from disk and enqueue it.
result: AsyncPredictResponse = mindee_client.enqueue_and_parse(
product.us.UsMailV2,
product.us.UsMailV3,
input_doc,
)

Expand All @@ -32,7 +32,20 @@ print(result.document)

**Output (RST):**
```rst
:Sender Name: zed
########
Document
########
:Mindee ID: f9c36f59-977d-4ddc-9f2d-31c294c456ac
:Filename: default_sample.jpg
Inference
#########
:Product: mindee/us_mail v3.0
:Rotation applied: Yes
Prediction
==========
:Sender Name: company zed
:Sender Address:
:City: Dallas
:Complete Address: 54321 Elm Street, Dallas, Texas 54321
Expand All @@ -41,11 +54,12 @@ print(result.document)
:Street: 54321 Elm Street
:Recipient Names: Jane Doe
:Recipient Addresses:
+-----------------+-------------------------------------+-------------------+-------------+------------------------+-------+---------------------------+
| City | Complete Address | Is Address Change | Postal Code | Private Mailbox Number | State | Street |
+=================+=====================================+===================+=============+========================+=======+===========================+
| Detroit | 1234 Market Street PMB 4321, Det... | | 12345 | 4321 | MI | 1234 Market Street |
+-----------------+-------------------------------------+-------------------+-------------+------------------------+-------+---------------------------+
+-----------------+-------------------------------------+-------------------+-------------+------------------------+-------+---------------------------+-----------------+
| City | Complete Address | Is Address Change | Postal Code | Private Mailbox Number | State | Street | Unit |
+=================+=====================================+===================+=============+========================+=======+===========================+=================+
| Detroit | 1234 Market Street PMB 4321, Det... | False | 12345 | 4321 | MI | 1234 Market Street | |
+-----------------+-------------------------------------+-------------------+-------------+------------------------+-------+---------------------------+-----------------+
:Return to Sender: False
```

# Field Types
Expand Down Expand Up @@ -77,7 +91,7 @@ Fields which are specific to this product; they are not used in any other produc
### Recipient Addresses Field
The addresses of the recipients.

A `UsMailV2RecipientAddress` implements the following attributes:
A `UsMailV3RecipientAddress` implements the following attributes:

* **city** (`str`): The city of the recipient's address.
* **complete** (`str`): The complete address of the recipient.
Expand All @@ -86,12 +100,13 @@ A `UsMailV2RecipientAddress` implements the following attributes:
* **private_mailbox_number** (`str`): The private mailbox number of the recipient's address.
* **state** (`str`): Second part of the ISO 3166-2 code, consisting of two letters indicating the US State.
* **street** (`str`): The street of the recipient's address.
* **unit** (`str`): The unit number of the recipient's address.
Fields which are specific to this product; they are not used in any other product.

### Sender Address Field
The address of the sender.

A `UsMailV2SenderAddress` implements the following attributes:
A `UsMailV3SenderAddress` implements the following attributes:

* **city** (`str`): The city of the sender's address.
* **complete** (`str`): The complete address of the sender.
Expand All @@ -100,10 +115,17 @@ A `UsMailV2SenderAddress` implements the following attributes:
* **street** (`str`): The street of the sender's address.

# Attributes
The following fields are extracted for US Mail V2:
The following fields are extracted for US Mail V3:

## Return to Sender
**is_return_to_sender** ([BooleanField](#booleanfield)): Whether the mailing is marked as return to sender.

```py
print(result.document.inference.prediction.is_return_to_sender.value)
```

## Recipient Addresses
**recipient_addresses** (List[[UsMailV2RecipientAddress](#recipient-addresses-field)]): The addresses of the recipients.
**recipient_addresses** (List[[UsMailV3RecipientAddress](#recipient-addresses-field)]): The addresses of the recipients.

```py
for recipient_addresses_elem in result.document.inference.prediction.recipient_addresses:
Expand All @@ -119,7 +141,7 @@ for recipient_names_elem in result.document.inference.prediction.recipient_names
```

## Sender Address
**sender_address** ([UsMailV2SenderAddress](#sender-address-field)): The address of the sender.
**sender_address** ([UsMailV3SenderAddress](#sender-address-field)): The address of the sender.

```py
print(result.document.inference.prediction.sender_address.value)
Expand Down
2 changes: 1 addition & 1 deletion docs/product/bill_of_lading_v1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Bill of Lading V1

**Sample Code:**

.. literalinclude:: /extras/code_samples/bill_of_lading_v1.txt
.. literalinclude:: /extras/code_samples/bill_of_lading_v1_async.txt
:language: Python

.. autoclass:: mindee.product.bill_of_lading.bill_of_lading_v1.BillOfLadingV1
Expand Down
2 changes: 1 addition & 1 deletion docs/product/ind/indian_passport_v1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Passport - India V1

**Sample Code:**

.. literalinclude:: /extras/code_samples/ind_passport_v1.txt
.. literalinclude:: /extras/code_samples/ind_passport_v1_async.txt
:language: Python

.. autoclass:: mindee.product.ind.indian_passport.indian_passport_v1.IndianPassportV1
Expand Down
2 changes: 1 addition & 1 deletion docs/product/international_id_v2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ International ID V2

**Sample Code:**

.. literalinclude:: /extras/code_samples/international_id_v2.txt
.. literalinclude:: /extras/code_samples/international_id_v2_async.txt
:language: Python

.. autoclass:: mindee.product.international_id.international_id_v2.InternationalIdV2
Expand Down
2 changes: 1 addition & 1 deletion docs/product/nutrition_facts_label_v1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Nutrition Facts Label V1

**Sample Code:**

.. literalinclude:: /extras/code_samples/nutrition_facts_v1.txt
.. literalinclude:: /extras/code_samples/nutrition_facts_v1_async.txt
:language: Python

.. autoclass:: mindee.product.nutrition_facts_label.nutrition_facts_label_v1.NutritionFactsLabelV1
Expand Down
2 changes: 1 addition & 1 deletion docs/product/us/us_mail_v2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ US Mail V2

**Sample Code:**

.. literalinclude:: /extras/code_samples/us_mail_v2.txt
.. literalinclude:: /extras/code_samples/us_mail_v2_async.txt
:language: Python

.. autoclass:: mindee.product.us.us_mail.us_mail_v2.UsMailV2
Expand Down
23 changes: 23 additions & 0 deletions docs/product/us/us_mail_v3.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
US Mail V3
----------

**Sample Code:**

.. literalinclude:: /extras/code_samples/us_mail_v3_async.txt
:language: Python

.. autoclass:: mindee.product.us.us_mail.us_mail_v3.UsMailV3
:members:
:inherited-members:

.. autoclass:: mindee.product.us.us_mail.us_mail_v3_document.UsMailV3Document
:members:
:inherited-members:

.. autoclass:: mindee.product.us.us_mail.us_mail_v3_sender_address.UsMailV3SenderAddress
:members:
:inherited-members:

.. autoclass:: mindee.product.us.us_mail.us_mail_v3_recipient_address.UsMailV3RecipientAddress
:members:
:inherited-members:
2 changes: 1 addition & 1 deletion mindee/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class CommandConfig(Generic[TypeInference]):
),
"us-mail": CommandConfig(
help="US Mail",
doc_class=product.us.UsMailV2,
doc_class=product.us.UsMailV3,
is_sync=False,
is_async=True,
),
Expand Down
6 changes: 6 additions & 0 deletions mindee/product/us/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
UsMailV2RecipientAddress,
)
from mindee.product.us.us_mail.us_mail_v2_sender_address import UsMailV2SenderAddress
from mindee.product.us.us_mail.us_mail_v3 import UsMailV3
from mindee.product.us.us_mail.us_mail_v3_document import UsMailV3Document
from mindee.product.us.us_mail.us_mail_v3_recipient_address import (
UsMailV3RecipientAddress,
)
from mindee.product.us.us_mail.us_mail_v3_sender_address import UsMailV3SenderAddress
from mindee.product.us.w9.w9_v1 import W9V1
from mindee.product.us.w9.w9_v1_document import W9V1Document
from mindee.product.us.w9.w9_v1_page import W9V1Page
6 changes: 6 additions & 0 deletions mindee/product/us/us_mail/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@
UsMailV2RecipientAddress,
)
from mindee.product.us.us_mail.us_mail_v2_sender_address import UsMailV2SenderAddress
from mindee.product.us.us_mail.us_mail_v3 import UsMailV3
from mindee.product.us.us_mail.us_mail_v3_document import UsMailV3Document
from mindee.product.us.us_mail.us_mail_v3_recipient_address import (
UsMailV3RecipientAddress,
)
from mindee.product.us.us_mail.us_mail_v3_sender_address import UsMailV3SenderAddress
39 changes: 39 additions & 0 deletions mindee/product/us/us_mail/us_mail_v3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from typing import List

from mindee.parsing.common.inference import Inference
from mindee.parsing.common.page import Page
from mindee.parsing.common.string_dict import StringDict
from mindee.product.us.us_mail.us_mail_v3_document import (
UsMailV3Document,
)


class UsMailV3(Inference):
"""US Mail API version 3 inference prediction."""

prediction: UsMailV3Document
"""Document-level prediction."""
pages: List[Page[UsMailV3Document]]
"""Page-level prediction(s)."""
endpoint_name = "us_mail"
"""Name of the endpoint."""
endpoint_version = "3"
"""Version of the endpoint."""

def __init__(self, raw_prediction: StringDict):
"""
US Mail v3 inference.
:param raw_prediction: Raw prediction from the HTTP response.
"""
super().__init__(raw_prediction)

self.prediction = UsMailV3Document(raw_prediction["prediction"])
self.pages = []
for page in raw_prediction["pages"]:
try:
page_prediction = page["prediction"]
except KeyError:
continue
if page_prediction:
self.pages.append(Page(UsMailV3Document, page))
105 changes: 105 additions & 0 deletions mindee/product/us/us_mail/us_mail_v3_document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from typing import List, Optional

from mindee.parsing.common.prediction import Prediction
from mindee.parsing.common.string_dict import StringDict
from mindee.parsing.common.summary_helper import clean_out_string
from mindee.parsing.standard.boolean import BooleanField
from mindee.parsing.standard.text import StringField
from mindee.product.us.us_mail.us_mail_v3_recipient_address import (
UsMailV3RecipientAddress,
)
from mindee.product.us.us_mail.us_mail_v3_sender_address import UsMailV3SenderAddress


class UsMailV3Document(Prediction):
"""US Mail API version 3.0 document data."""

is_return_to_sender: BooleanField
"""Whether the mailing is marked as return to sender."""
recipient_addresses: List[UsMailV3RecipientAddress]
"""The addresses of the recipients."""
recipient_names: List[StringField]
"""The names of the recipients."""
sender_address: UsMailV3SenderAddress
"""The address of the sender."""
sender_name: StringField
"""The name of the sender."""

def __init__(
self,
raw_prediction: StringDict,
page_id: Optional[int] = None,
):
"""
US Mail document.
:param raw_prediction: Raw prediction from HTTP response
:param page_id: Page number for multi pages pdf input
"""
super().__init__(raw_prediction, page_id)
self.is_return_to_sender = BooleanField(
raw_prediction["is_return_to_sender"],
page_id=page_id,
)
self.recipient_addresses = [
UsMailV3RecipientAddress(prediction, page_id=page_id)
for prediction in raw_prediction["recipient_addresses"]
]
self.recipient_names = [
StringField(prediction, page_id=page_id)
for prediction in raw_prediction["recipient_names"]
]
self.sender_address = UsMailV3SenderAddress(
raw_prediction["sender_address"],
page_id=page_id,
)
self.sender_name = StringField(
raw_prediction["sender_name"],
page_id=page_id,
)

@staticmethod
def _recipient_addresses_separator(char: str) -> str:
out_str = " "
out_str += f"+{char * 17}"
out_str += f"+{char * 37}"
out_str += f"+{char * 19}"
out_str += f"+{char * 13}"
out_str += f"+{char * 24}"
out_str += f"+{char * 7}"
out_str += f"+{char * 27}"
out_str += f"+{char * 17}"
return out_str + "+"

def _recipient_addresses_to_str(self) -> str:
if not self.recipient_addresses:
return ""

lines = f"\n{self._recipient_addresses_separator('-')}\n ".join(
[item.to_table_line() for item in self.recipient_addresses]
)
out_str = ""
out_str += f"\n{self._recipient_addresses_separator('-')}\n "
out_str += " | City "
out_str += " | Complete Address "
out_str += " | Is Address Change"
out_str += " | Postal Code"
out_str += " | Private Mailbox Number"
out_str += " | State"
out_str += " | Street "
out_str += " | Unit "
out_str += f" |\n{self._recipient_addresses_separator('=')}"
out_str += f"\n {lines}"
out_str += f"\n{self._recipient_addresses_separator('-')}"
return out_str

def __str__(self) -> str:
recipient_names = f"\n { ' ' * 17 }".join(
[str(item) for item in self.recipient_names],
)
out_str: str = f":Sender Name: {self.sender_name}\n"
out_str += f":Sender Address:\n{self.sender_address.to_field_list()}\n"
out_str += f":Recipient Names: {recipient_names}\n"
out_str += f":Recipient Addresses: {self._recipient_addresses_to_str()}\n"
out_str += f":Return to Sender: {self.is_return_to_sender}\n"
return clean_out_string(out_str)
Loading

0 comments on commit 9318c94

Please sign in to comment.