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
13 changes: 13 additions & 0 deletions docs/extras/code_samples/bank_account_details_v2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from mindee import Client, documents

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

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

# Parse the Bank Account Details by passing the appropriate type
result = input_doc.parse(documents.fr.TypeBankAccountDetailsV2)

# Print a brief summary of the parsed data
print(result.document)
1 change: 0 additions & 1 deletion docs/extras/code_samples/invoice_splitter_v1_async.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ mindee_client = Client(api_key="my-api-key")
input_doc = mindee_client.doc_from_path("/path/to/the/file.ext")

# Put the document class in a local variable to keep the code DRY

doc_class = documents.TypeInvoiceSplitterV1

# Limit the amount of API calls to retrieve your document
Expand Down
13 changes: 13 additions & 0 deletions docs/predictions/standard/documents/fr/bank_account_details_v2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Bank Account Details V2
-----------------------

**Sample Code:**

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

.. autoclass:: mindee.documents.fr.BankAccountDetailsV2
:members:

.. autoclass:: mindee.documents.fr.BankAccountDetailsV2Bban
:members:
1 change: 1 addition & 0 deletions docs/predictions/standard/fr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ France
.. include:: ./documents/fr/carte_vitale_v1.rst
.. include:: ./documents/fr/carte_grise_v1.rst
.. include:: ./documents/fr/bank_account_details_v1.rst
.. include:: ./documents/fr/bank_account_details_v2.rst
5 changes: 5 additions & 0 deletions mindee/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,11 @@ def _init_default_endpoints(self) -> None:
url_name="bank_account_details",
version="1",
),
ConfigSpec(
doc_class=documents.fr.BankAccountDetailsV2,
url_name="bank_account_details",
version="2",
),
ConfigSpec(
doc_class=documents.eu.LicensePlateV1,
url_name="license_plates",
Expand Down
4 changes: 4 additions & 0 deletions mindee/documents/fr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
BankAccountDetailsV1,
TypeBankAccountDetailsV1,
)
from .bank_account_details.bank_account_details_v2 import (
BankAccountDetailsV2,
TypeBankAccountDetailsV2,
)
from .carte_grise.carte_grise_v1 import CarteGriseV1, TypeCarteGriseV1
from .carte_vitale.carte_vitale_v1 import CarteVitaleV1, TypeCarteVitaleV1
from .id_card.id_card_v1 import IdCardV1, TypeIdCardV1
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from typing import Optional, TypeVar

from mindee.documents.base import Document, TypeApiPrediction, clean_out_string
from mindee.fields.text import TextField

from .bank_account_details_v2_bban import BankAccountDetailsV2Bban


class BankAccountDetailsV2(Document):
"""Bank Account Details v2 prediction results."""

account_holders_names: TextField
"""Full extraction of the account holders names."""
bban: BankAccountDetailsV2Bban
"""Full extraction of BBAN, including: branch code, bank code, account and key."""
iban: TextField
"""Full extraction of the IBAN number."""
swift_code: TextField
"""Full extraction of the SWIFT code."""

def __init__(
self,
api_prediction=None,
input_source=None,
page_n: Optional[int] = None,
):
"""
Bank Account Details v2 prediction results.

:param api_prediction: Raw prediction from HTTP response
:param input_source: Input object
:param page_n: Page number for multi pages pdf input
"""
super().__init__(
input_source=input_source,
document_type="bank_account_details",
api_prediction=api_prediction,
page_n=page_n,
)
self._build_from_api_prediction(api_prediction["prediction"], page_n=page_n)

def _build_from_api_prediction(
self, api_prediction: TypeApiPrediction, page_n: Optional[int] = None
) -> None:
"""
Build the object from the prediction API JSON.

:param api_prediction: Raw prediction from HTTP response
:param page_n: Page number
"""
self.account_holders_names = TextField(
api_prediction["account_holders_names"],
page_id=page_n,
)
self.bban = BankAccountDetailsV2Bban(
api_prediction["bban"],
page_id=page_n,
)
self.iban = TextField(
api_prediction["iban"],
page_id=page_n,
)
self.swift_code = TextField(
api_prediction["swift_code"],
page_id=page_n,
)

def __str__(self) -> str:
return clean_out_string(
"FR Bank Account Details V2 Prediction\n"
"=====================================\n"
f":Filename: {self.filename or ''}\n"
f":Account Holder's Names: {self.account_holders_names}\n"
f":Basic Bank Account Number:\n{self.bban.to_field_list()}\n"
f":IBAN: {self.iban}\n"
f":SWIFT Code: {self.swift_code}\n"
)


TypeBankAccountDetailsV2 = TypeVar(
"TypeBankAccountDetailsV2", bound=BankAccountDetailsV2
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from typing import Dict, Optional

from mindee.fields.base import FieldConfidenceMixin, FieldPositionMixin, TypePrediction


class BankAccountDetailsV2Bban(FieldPositionMixin, FieldConfidenceMixin):
"""Full extraction of BBAN, including: branch code, bank code, account and key."""

bban_bank_code: Optional[str]
"""The BBAN bank code outputted as a string."""
bban_branch_code: Optional[str]
"""The BBAN branch code outputted as a string."""
bban_key: Optional[str]
"""The BBAN key outputted as a string."""
bban_number: Optional[str]
"""The BBAN Account number outputted as a string."""
page_n: int
"""The document page on which the information was found."""

def __init__(
self,
prediction: TypePrediction,
page_id: Optional[int] = None,
):
self._set_confidence(prediction)
self._set_position(prediction)

if page_id is None:
try:
self.page_n = prediction["page_id"]
except KeyError:
pass
else:
self.page_n = page_id

self.bban_bank_code = prediction["bban_bank_code"]
self.bban_branch_code = prediction["bban_branch_code"]
self.bban_key = prediction["bban_key"]
self.bban_number = prediction["bban_number"]

def _printable_values(self) -> Dict[str, str]:
"""Return values for printing."""
return {
"bban_bank_code": self.bban_bank_code
if self.bban_bank_code is not None
else "",
"bban_branch_code": self.bban_branch_code
if self.bban_branch_code is not None
else "",
"bban_key": self.bban_key if self.bban_key is not None else "",
"bban_number": self.bban_number if self.bban_number is not None else "",
}

def to_field_list(self) -> str:
"""Output the object in a format suitable for inclusion in an rST field list."""
printable = self._printable_values()
return (
f" :Bank Code: {printable['bban_bank_code']}\n"
f" :Branch Code: {printable['bban_branch_code']}\n"
f" :Key: {printable['bban_key']}\n"
f" :Account Number: {printable['bban_number']}"
)

def __str__(self) -> str:
"""Default string representation."""
printable = self._printable_values()
return (
f"Bank Code: {printable['bban_bank_code']}, "
f"Branch Code: {printable['bban_branch_code']}, "
f"Key: {printable['bban_key']}, "
f"Account Number: {printable['bban_number']}, "
).strip()
55 changes: 55 additions & 0 deletions tests/documents/fr/test_bank_account_details_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import json

import pytest

from mindee.documents.fr import BankAccountDetailsV2

FR_BANK_ACCOUNT_DETAILS_DATA_DIR = "./tests/data/fr/bank_account_details"
FILE_PATH_FR_BANK_ACCOUNT_DETAILS_V2_COMPLETE = (
f"{ FR_BANK_ACCOUNT_DETAILS_DATA_DIR }/response_v2/complete.json"
)
FILE_PATH_FR_BANK_ACCOUNT_DETAILS_V2_EMPTY = (
f"{ FR_BANK_ACCOUNT_DETAILS_DATA_DIR }/response_v2/empty.json"
)


@pytest.fixture
def bank_account_details_v2_doc() -> BankAccountDetailsV2:
json_data = json.load(open(FILE_PATH_FR_BANK_ACCOUNT_DETAILS_V2_COMPLETE))
return BankAccountDetailsV2(json_data["document"]["inference"], page_n=None)


@pytest.fixture
def bank_account_details_v2_doc_empty() -> BankAccountDetailsV2:
json_data = json.load(open(FILE_PATH_FR_BANK_ACCOUNT_DETAILS_V2_EMPTY))
return BankAccountDetailsV2(json_data["document"]["inference"], page_n=None)


@pytest.fixture
def bank_account_details_v2_page0():
json_data = json.load(open(FILE_PATH_FR_BANK_ACCOUNT_DETAILS_V2_COMPLETE))
return BankAccountDetailsV2(
json_data["document"]["inference"]["pages"][0], page_n=0
)


def test_empty_doc_constructor(bank_account_details_v2_doc_empty):
assert bank_account_details_v2_doc_empty.account_holders_names.value is None
assert bank_account_details_v2_doc_empty.bban.bban_bank_code is None
assert bank_account_details_v2_doc_empty.bban.bban_branch_code is None
assert bank_account_details_v2_doc_empty.bban.bban_key is None
assert bank_account_details_v2_doc_empty.bban.bban_number is None
assert bank_account_details_v2_doc_empty.iban.value is None
assert bank_account_details_v2_doc_empty.swift_code.value is None


def test_doc_constructor(bank_account_details_v2_doc):
file_path = f"{ FR_BANK_ACCOUNT_DETAILS_DATA_DIR }/response_v2/doc_to_string.rst"
reference_str = open(file_path, "r", encoding="utf-8").read()
assert str(bank_account_details_v2_doc) == reference_str


def test_page0_constructor(bank_account_details_v2_page0):
file_path = f"{ FR_BANK_ACCOUNT_DETAILS_DATA_DIR }/response_v2/page0_to_string.rst"
reference_str = open(file_path, "r", encoding="utf-8").read()
assert str(bank_account_details_v2_page0) == reference_str