Skip to content

Commit ce2c775

Browse files
✨ add support for local loading
1 parent f74bb46 commit ce2c775

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed

mindee/client.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from mindee.error.mindee_error import MindeeClientError, MindeeError
66
from mindee.error.mindee_http_error import handle_error
7+
from mindee.input import LocalResponse
78
from mindee.input.page_options import PageOptions
89
from mindee.input.sources import (
910
Base64Input,
@@ -178,6 +179,23 @@ def enqueue(
178179
cropper,
179180
)
180181

182+
def load_prediction(
183+
self, product_class: Type[Inference], local_response: LocalResponse
184+
) -> Union[AsyncPredictResponse, PredictResponse]:
185+
"""
186+
Load a prediction.
187+
188+
:param product_class: Class of the product to use.
189+
:param local_response: Local response to load.
190+
:return:
191+
"""
192+
try:
193+
if local_response.json.get("job"):
194+
return AsyncPredictResponse(product_class, local_response.json)
195+
return PredictResponse(product_class, local_response.json)
196+
except KeyError as exc:
197+
raise MindeeError("No prediction found in local response.") from exc
198+
181199
def parse_queued(
182200
self,
183201
product_class: Type[Inference],

mindee/input/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from mindee.input.local_response import LocalResponse
12
from mindee.input.page_options import PageOptions
23
from mindee.input.sources import (
34
Base64Input,

mindee/input/local_response.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import json
2+
from pathlib import Path
3+
from typing import Union, BinaryIO, Dict, Any
4+
import io
5+
6+
from mindee.error import MindeeError
7+
8+
9+
class LocalResponse:
10+
json: Dict[str, Any]
11+
12+
def __init__(self, input_file: Union[BinaryIO, str, Path, bytes]):
13+
input_binary: BinaryIO
14+
if isinstance(input_file, BinaryIO):
15+
input_binary = input_file
16+
input_binary.seek(0)
17+
elif isinstance(input_file, str) or isinstance(input_file, Path):
18+
with open(input_file, 'rb') as f:
19+
input_binary = io.BytesIO(f.read())
20+
elif isinstance(input_file, bytes):
21+
input_binary = io.BytesIO(input_file)
22+
else:
23+
raise TypeError('Incompatible type for input.')
24+
try:
25+
input_binary.seek(0)
26+
self.json = json.load(input_binary)
27+
input_binary.close()
28+
except json.decoder.JSONDecodeError as exc:
29+
raise MindeeError('File is not a valid dictionary.') from exc

tests/test_client.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
import pytest
44

5-
from mindee import Client, PageOptions, product
6-
from mindee.error.mindee_error import MindeeClientError
5+
from mindee import AsyncPredictResponse, Client, PageOptions, PredictResponse, product
6+
from mindee.error.mindee_error import MindeeClientError, MindeeError
77
from mindee.error.mindee_http_error import MindeeHTTPError
8+
from mindee.input import LocalResponse
89
from mindee.input.sources import LocalInputSource
10+
from mindee.product import InternationalIdV2, InvoiceV4
911
from mindee.product.invoice_splitter.invoice_splitter_v1 import InvoiceSplitterV1
1012
from mindee.product.receipt.receipt_v4 import ReceiptV4
11-
from tests.test_inputs import FILE_TYPES_DIR
13+
from tests.mindee_http.test_error import ERROR_DATA_DIR
14+
from tests.test_inputs import FILE_TYPES_DIR, PRODUCT_DATA_DIR
1215
from tests.utils import clear_envvars, dummy_envvars
1316

1417

@@ -113,3 +116,40 @@ def test_async_wrong_polling_delay(dummy_client: Client):
113116
input_doc = dummy_client.source_from_path(FILE_TYPES_DIR / "pdf" / "blank.pdf")
114117
with pytest.raises(MindeeClientError):
115118
dummy_client.enqueue_and_parse(InvoiceSplitterV1, input_doc, delay_sec=0)
119+
120+
121+
def test_local_response_from_sync_json(dummy_client: Client):
122+
input_file = LocalResponse(
123+
PRODUCT_DATA_DIR / "invoices" / "response_v4" / "complete.json"
124+
)
125+
with open(PRODUCT_DATA_DIR / "invoices" / "response_v4" / "summary_full.rst") as f:
126+
reference_doc = f.read()
127+
result = dummy_client.load_prediction(InvoiceV4, input_file)
128+
assert isinstance(result, PredictResponse)
129+
assert str(result.document) == reference_doc
130+
131+
132+
def test_local_response_from_async_json(dummy_client: Client):
133+
input_file = LocalResponse(
134+
PRODUCT_DATA_DIR / "international_id" / "response_v2" / "complete.json"
135+
)
136+
with open(
137+
PRODUCT_DATA_DIR / "international_id" / "response_v2" / "summary_full.rst"
138+
) as f:
139+
reference_doc = f.read()
140+
result = dummy_client.load_prediction(InternationalIdV2, input_file)
141+
assert isinstance(result, AsyncPredictResponse)
142+
assert str(result.document) == reference_doc
143+
144+
145+
def test_local_response_from_invalid_file(dummy_client: Client):
146+
with pytest.raises(MindeeError):
147+
LocalResponse(
148+
PRODUCT_DATA_DIR / "invoices" / "response_v4" / "summary_full.rst"
149+
)
150+
151+
152+
def test_local_response_from_invalid_dict(dummy_client: Client):
153+
input_file = LocalResponse(ERROR_DATA_DIR / "error_400_no_details.json")
154+
with pytest.raises(MindeeError):
155+
dummy_client.load_prediction(InvoiceV4, input_file)

0 commit comments

Comments
 (0)