Skip to content

Commit e9f0106

Browse files
✨ add support for Multi Receipts Detector V1
1 parent cd52156 commit e9f0106

File tree

9 files changed

+142
-5
lines changed

9 files changed

+142
-5
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from mindee import Client, documents
2+
3+
# Init a new client
4+
mindee_client = Client(api_key="my-api-key")
5+
6+
# Load a file from disk
7+
input_doc = mindee_client.doc_from_path("/path/to/the/file.ext")
8+
9+
# Parse the Multi Receipts Detector by passing the appropriate type
10+
result = input_doc.parse(documents.TypeMultiReceiptsDetectorV1)
11+
12+
# Print a brief summary of the parsed data
13+
print(result.document)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Multi Receipts Detector V1
2+
--------------------------
3+
4+
**Sample Code:**
5+
6+
.. literalinclude:: /extras/code_samples/multi_receipts_detector_v1.txt
7+
:language: Python
8+
9+
.. autoclass:: mindee.documents.MultiReceiptsDetectorV1
10+
:members:

mindee/client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,11 @@ def _init_default_endpoints(self) -> None:
474474
url_name="material_certificate",
475475
version="1",
476476
),
477+
ConfigSpec(
478+
doc_class=documents.MultiReceiptsDetectorV1,
479+
url_name="multi_receipts_detector",
480+
version="1",
481+
),
477482
ConfigSpec(
478483
doc_class=documents.us.W9V1,
479484
url_name="us_w9",

mindee/documents/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
MaterialCertificateV1,
1616
TypeMaterialCertificateV1,
1717
)
18+
from mindee.documents.multi_receipts_detector import (
19+
MultiReceiptsDetectorV1,
20+
TypeMultiReceiptsDetectorV1,
21+
)
1822
from mindee.documents.passport import PassportV1, TypePassportV1
1923
from mindee.documents.proof_of_address import ProofOfAddressV1, TypeProofOfAddressV1
2024
from mindee.documents.receipt import (
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .multi_receipts_detector_v1 import MultiReceiptsDetectorV1, TypeMultiReceiptsDetectorV1
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from typing import List, Optional, TypeVar
2+
3+
from mindee.documents.base import Document, TypeApiPrediction, clean_out_string
4+
from mindee.fields.position import PositionField
5+
6+
7+
class MultiReceiptsDetectorV1(Document):
8+
"""Multi Receipts Detector v1 prediction results."""
9+
10+
receipts: List[PositionField]
11+
"""Positions of the receipts on the document."""
12+
13+
def __init__(
14+
self,
15+
api_prediction=None,
16+
input_source=None,
17+
page_n: Optional[int] = None,
18+
):
19+
"""
20+
Multi Receipts Detector v1 prediction results.
21+
22+
:param api_prediction: Raw prediction from HTTP response
23+
:param input_source: Input object
24+
:param page_n: Page number for multi pages pdf input
25+
"""
26+
super().__init__(
27+
input_source=input_source,
28+
document_type="multi_receipts_detector",
29+
api_prediction=api_prediction,
30+
page_n=page_n,
31+
)
32+
self._build_from_api_prediction(api_prediction["prediction"], page_n=page_n)
33+
34+
def _build_from_api_prediction(
35+
self, api_prediction: TypeApiPrediction, page_n: Optional[int] = None
36+
) -> None:
37+
"""
38+
Build the object from the prediction API JSON.
39+
40+
:param api_prediction: Raw prediction from HTTP response
41+
:param page_n: Page number
42+
"""
43+
self.receipts = [
44+
PositionField(prediction, page_id=page_n)
45+
for prediction in api_prediction["receipts"]
46+
]
47+
48+
def __str__(self) -> str:
49+
receipts = f"\n { ' ' * 18 }".join(
50+
[str(item) for item in self.receipts],
51+
)
52+
return clean_out_string(
53+
"Multi Receipts Detector V1 Prediction\n"
54+
"=====================================\n"
55+
f":Filename: {self.filename or ''}\n"
56+
f":List of Receipts: {receipts}\n"
57+
)
58+
59+
60+
TypeMultiReceiptsDetectorV1 = TypeVar(
61+
"TypeMultiReceiptsDetectorV1",
62+
bound=MultiReceiptsDetectorV1,
63+
)

mindee/fields/position.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ def get_polygon(key: str) -> Optional[Polygon]:
7272
self.value = self.polygon
7373

7474
def __str__(self) -> str:
75-
if self.polygon is None:
76-
return ""
77-
return f"Polygon with {len(self.polygon)} points."
75+
if self.polygon is not None:
76+
return f"Polygon with {len(self.polygon)} points."
77+
if self.bounding_box is not None:
78+
return f"Polygon with {len(self.bounding_box)} points."
79+
if self.rectangle is not None:
80+
return f"Polygon with {len(self.rectangle)} points."
81+
if self.quadrangle is not None:
82+
return f"Polygon with {len(self.quadrangle)} points."
83+
return ""

tests/documents/test_barcode_reader_v1.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
from mindee.documents import BarcodeReaderV1
66

77
BARCODE_READER_DATA_DIR = "./tests/data/products/barcode_reader"
8-
FILE_PATH_BARCODE_READER_V1_COMPLETE = f"{ BARCODE_READER_DATA_DIR }/response_v1/complete.json"
9-
FILE_PATH_BARCODE_READER_V1_EMPTY = f"{ BARCODE_READER_DATA_DIR }/response_v1/empty.json"
8+
FILE_PATH_BARCODE_READER_V1_COMPLETE = (
9+
f"{ BARCODE_READER_DATA_DIR }/response_v1/complete.json"
10+
)
11+
FILE_PATH_BARCODE_READER_V1_EMPTY = (
12+
f"{ BARCODE_READER_DATA_DIR }/response_v1/empty.json"
13+
)
1014

1115

1216
@pytest.fixture
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import json
2+
3+
import pytest
4+
5+
from mindee.documents import MultiReceiptsDetectorV1
6+
7+
MULTI_RECEIPTS_DETECTOR_DATA_DIR = "./tests/data/products/multi_receipts_detector"
8+
FILE_PATH_MULTI_RECEIPTS_DETECTOR_V1_COMPLETE = f"{ MULTI_RECEIPTS_DETECTOR_DATA_DIR }/response_v1/complete.json"
9+
FILE_PATH_MULTI_RECEIPTS_DETECTOR_V1_EMPTY = f"{ MULTI_RECEIPTS_DETECTOR_DATA_DIR }/response_v1/empty.json"
10+
11+
12+
@pytest.fixture
13+
def multi_receipts_detector_v1_doc() -> MultiReceiptsDetectorV1:
14+
json_data = json.load(open(FILE_PATH_MULTI_RECEIPTS_DETECTOR_V1_COMPLETE, encoding="utf-8"))
15+
return MultiReceiptsDetectorV1(json_data["document"]["inference"], page_n=None)
16+
17+
18+
@pytest.fixture
19+
def multi_receipts_detector_v1_doc_empty() -> MultiReceiptsDetectorV1:
20+
json_data = json.load(open(FILE_PATH_MULTI_RECEIPTS_DETECTOR_V1_EMPTY, encoding="utf-8"))
21+
return MultiReceiptsDetectorV1(json_data["document"]["inference"], page_n=None)
22+
23+
24+
@pytest.fixture
25+
def multi_receipts_detector_v1_page0():
26+
json_data = json.load(open(FILE_PATH_MULTI_RECEIPTS_DETECTOR_V1_COMPLETE, encoding="utf-8"))
27+
return MultiReceiptsDetectorV1(json_data["document"]["inference"]["pages"][0], page_n=0)
28+
29+
30+
def test_empty_doc_constructor(multi_receipts_detector_v1_doc_empty):
31+
assert len(multi_receipts_detector_v1_doc_empty.receipts) == 0

0 commit comments

Comments
 (0)