Skip to content
Closed
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
4 changes: 1 addition & 3 deletions examples/display_cropping.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@
python examples/display_cropping.py
"""

from typing import List, Tuple

import cv2
import numpy as np

from mindee import Client, product
from mindee.parsing.common.predict_response import PredictResponse


def relative_to_pixel_pos(polygon, image_h: int, image_w: int) -> List[Tuple[int, int]]:
def relative_to_pixel_pos(polygon, image_h: int, image_w: int) -> list[tuple[int, int]]:
"""Convert from Mindee's relative format to an absolute pixel format as used by OpenCV."""
return [(int(point[0] * image_w), int(point[1] * image_h)) for point in polygon]

Expand Down
69 changes: 34 additions & 35 deletions mindee/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from time import sleep
from typing import Dict, Optional, Type, Union

from mindee.client_mixin import ClientMixin
from mindee.error.mindee_error import MindeeClientError, MindeeError
Expand Down Expand Up @@ -70,13 +69,13 @@ def __init__(self, api_key: str = "") -> None:

def parse(
self,
product_class: Type[Inference],
input_source: Union[LocalInputSource, UrlInputSource],
product_class: type[Inference],
input_source: LocalInputSource | UrlInputSource,
include_words: bool = False,
close_file: bool = True,
page_options: Optional[PageOptions] = None,
page_options: PageOptions | None = None,
cropper: bool = False,
endpoint: Optional[Endpoint] = None,
endpoint: Endpoint | None = None,
full_text: bool = False,
) -> PredictResponse:
"""
Expand Down Expand Up @@ -131,15 +130,15 @@ def parse(

def enqueue(
self,
product_class: Type[Inference],
input_source: Union[LocalInputSource, UrlInputSource],
product_class: type[Inference],
input_source: LocalInputSource | UrlInputSource,
include_words: bool = False,
close_file: bool = True,
page_options: Optional[PageOptions] = None,
page_options: PageOptions | None = None,
cropper: bool = False,
endpoint: Optional[Endpoint] = None,
endpoint: Endpoint | None = None,
full_text: bool = False,
workflow_id: Optional[str] = None,
workflow_id: str | None = None,
rag: bool = False,
) -> AsyncPredictResponse:
"""
Expand Down Expand Up @@ -200,8 +199,8 @@ def enqueue(
)

def load_prediction(
self, product_class: Type[Inference], local_response: LocalResponse
) -> Union[AsyncPredictResponse, PredictResponse]:
self, product_class: type[Inference], local_response: LocalResponse
) -> AsyncPredictResponse | PredictResponse:
"""
Load a prediction.

Expand All @@ -218,9 +217,9 @@ def load_prediction(

def parse_queued(
self,
product_class: Type[Inference],
product_class: type[Inference],
queue_id: str,
endpoint: Optional[Endpoint] = None,
endpoint: Endpoint | None = None,
) -> AsyncPredictResponse:
"""
Parses a queued document.
Expand All @@ -239,10 +238,10 @@ def parse_queued(

def execute_workflow(
self,
input_source: Union[LocalInputSource, UrlInputSource],
input_source: LocalInputSource | UrlInputSource,
workflow_id: str,
options: Optional[WorkflowOptions] = None,
page_options: Optional[PageOptions] = None,
options: WorkflowOptions | None = None,
page_options: PageOptions | None = None,
) -> WorkflowResponse:
"""
Send the document to a workflow execution.
Expand Down Expand Up @@ -273,18 +272,18 @@ def execute_workflow(

def enqueue_and_parse( # pylint: disable=too-many-locals
self,
product_class: Type[Inference],
input_source: Union[LocalInputSource, UrlInputSource],
product_class: type[Inference],
input_source: LocalInputSource | UrlInputSource,
include_words: bool = False,
close_file: bool = True,
page_options: Optional[PageOptions] = None,
page_options: PageOptions | None = None,
cropper: bool = False,
endpoint: Optional[Endpoint] = None,
endpoint: Endpoint | None = None,
initial_delay_sec: float = 2,
delay_sec: float = 1.5,
max_retries: int = 80,
full_text: bool = False,
workflow_id: Optional[str] = None,
workflow_id: str | None = None,
rag: bool = False,
) -> AsyncPredictResponse:
"""
Expand Down Expand Up @@ -370,10 +369,10 @@ def enqueue_and_parse( # pylint: disable=too-many-locals

def send_feedback(
self,
product_class: Type[Inference],
product_class: type[Inference],
document_id: str,
feedback: StringDict,
endpoint: Optional[Endpoint] = None,
endpoint: Endpoint | None = None,
) -> FeedbackResponse:
"""
Send a feedback for a document.
Expand Down Expand Up @@ -402,8 +401,8 @@ def send_feedback(

def _make_request(
self,
product_class: Type[Inference],
input_source: Union[LocalInputSource, UrlInputSource],
product_class: type[Inference],
input_source: LocalInputSource | UrlInputSource,
endpoint: Endpoint,
options: PredictOptions,
close_file: bool,
Expand All @@ -427,10 +426,10 @@ def _make_request(

def _predict_async(
self,
product_class: Type[Inference],
input_source: Union[LocalInputSource, UrlInputSource],
product_class: type[Inference],
input_source: LocalInputSource | UrlInputSource,
options: AsyncPredictOptions,
endpoint: Optional[Endpoint] = None,
endpoint: Endpoint | None = None,
close_file: bool = True,
) -> AsyncPredictResponse:
"""Sends a document to the queue, and sends back an asynchronous predict response."""
Expand Down Expand Up @@ -460,7 +459,7 @@ def _predict_async(

def _get_queued_document(
self,
product_class: Type[Inference],
product_class: type[Inference],
endpoint: Endpoint,
queue_id: str,
) -> AsyncPredictResponse:
Expand All @@ -482,8 +481,8 @@ def _get_queued_document(

def _send_to_workflow(
self,
product_class: Type[Inference],
input_source: Union[LocalInputSource, UrlInputSource],
product_class: type[Inference],
input_source: LocalInputSource | UrlInputSource,
workflow_id: str,
options: WorkflowOptions,
) -> WorkflowResponse:
Expand Down Expand Up @@ -518,10 +517,10 @@ def _send_to_workflow(
)
return WorkflowResponse(product_class, dict_response)

def _initialize_ots_endpoint(self, product_class: Type[Inference]) -> Endpoint:
def _initialize_ots_endpoint(self, product_class: type[Inference]) -> Endpoint:
if product_class.__name__ == "CustomV1":
raise MindeeClientError("Missing endpoint specifications for custom build.")
endpoint_info: Dict[str, str] = product_class.get_endpoint_info(product_class)
endpoint_info: dict[str, str] = product_class.get_endpoint_info(product_class)
return self._build_endpoint(
endpoint_info["name"], OTS_OWNER, endpoint_info["version"]
)
Expand All @@ -543,7 +542,7 @@ def create_endpoint(
self,
endpoint_name: str,
account_name: str = "mindee",
version: Optional[str] = None,
version: str | None = None,
) -> Endpoint:
"""
Add a custom endpoint, created using the Mindee API Builder.
Expand Down
6 changes: 2 additions & 4 deletions mindee/client_mixin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import BinaryIO, Union
from typing import BinaryIO

from mindee.error import MindeeClientError
from mindee.input.sources.base_64_input import Base64Input
Expand All @@ -13,9 +13,7 @@ class ClientMixin:
"""Mixin for clients V1 & V2 common static methods."""

@staticmethod
def source_from_path(
input_path: Union[Path, str], fix_pdf: bool = False
) -> PathInput:
def source_from_path(input_path: Path | str, fix_pdf: bool = False) -> PathInput:
"""
Load a document from a path, as a string or a `Path` object.

Expand Down
18 changes: 9 additions & 9 deletions mindee/client_v2.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import warnings
from time import sleep
from typing import Optional, Union, Type, TypeVar
from typing import TypeVar

from mindee.client_mixin import ClientMixin
from mindee.error.mindee_error import MindeeError
Expand Down Expand Up @@ -30,10 +30,10 @@ class ClientV2(ClientMixin):
See: https://docs.mindee.com/
"""

api_key: Optional[str]
api_key: str | None
mindee_api: MindeeApiV2

def __init__(self, api_key: Optional[str] = None) -> None:
def __init__(self, api_key: str | None = None) -> None:
"""
Mindee API Client.

Expand All @@ -44,7 +44,7 @@ def __init__(self, api_key: Optional[str] = None) -> None:

def enqueue_inference(
self,
input_source: Union[LocalInputSource, UrlInputSource],
input_source: LocalInputSource | UrlInputSource,
params: BaseParameters,
disable_redundant_warnings: bool = False,
) -> JobResponse:
Expand All @@ -59,7 +59,7 @@ def enqueue_inference(

def enqueue(
self,
input_source: Union[LocalInputSource, UrlInputSource],
input_source: LocalInputSource | UrlInputSource,
params: BaseParameters,
) -> JobResponse:
"""
Expand Down Expand Up @@ -106,7 +106,7 @@ def get_inference(

def get_result(
self,
response_type: Type[TypeBaseResponse],
response_type: type[TypeBaseResponse],
inference_id: str,
) -> TypeBaseResponse:
"""
Expand All @@ -130,8 +130,8 @@ def get_result(

def enqueue_and_get_result(
self,
response_type: Type[TypeBaseResponse],
input_source: Union[LocalInputSource, UrlInputSource],
response_type: type[TypeBaseResponse],
input_source: LocalInputSource | UrlInputSource,
params: BaseParameters,
) -> TypeBaseResponse:
"""
Expand Down Expand Up @@ -187,7 +187,7 @@ def enqueue_and_get_result(

def enqueue_and_get_inference(
self,
input_source: Union[LocalInputSource, UrlInputSource],
input_source: LocalInputSource | UrlInputSource,
params: InferenceParameters,
) -> InferenceResponse:
"""[Deprecated] Use `enqueue_and_get_result` instead."""
Expand Down
27 changes: 13 additions & 14 deletions mindee/commands/cli_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
from argparse import ArgumentParser, Namespace
from typing import Optional, Type, Union

from mindee.client import Client, Endpoint
from mindee.commands.cli_products import PRODUCTS, CommandConfig
Expand Down Expand Up @@ -109,17 +108,17 @@ class MindeeParser:
"""Mindee client"""
document_info: CommandConfig
"""Config of the document."""
input_doc: Union[LocalInputSource, UrlInputSource]
input_doc: LocalInputSource | UrlInputSource
"""Document to be parsed."""
product_class: Type[Inference]
product_class: type[Inference]
"""Product to parse."""

def __init__(
self,
parser: Optional[MindeeArgumentParser] = None,
parsed_args: Optional[Namespace] = None,
client: Optional[Client] = None,
document_info: Optional[CommandConfig] = None,
parser: MindeeArgumentParser | None = None,
parsed_args: Namespace | None = None,
client: Client | None = None,
document_info: CommandConfig | None = None,
) -> None:
self.parser = (
parser if parser else MindeeArgumentParser(description="Mindee_API")
Expand All @@ -137,7 +136,7 @@ def __init__(

def call_parse(self) -> None:
"""Calls an endpoint with the appropriate method, and displays the results."""
response: Union[PredictResponse, AsyncPredictResponse]
response: PredictResponse | AsyncPredictResponse
if self.document_info.is_sync:
if self.document_info.is_async:
if (
Expand Down Expand Up @@ -169,12 +168,12 @@ def call_parse(self) -> None:

def _parse_sync(self) -> PredictResponse:
"""Processes the results of a synchronous request."""
page_options: Optional[PageOptions] = None
page_options: PageOptions | None = None
if self.parsed_args.cut_doc and self.parsed_args.doc_pages:
page_options = PageOptions(
range(self.parsed_args.doc_pages), on_min_pages=0
)
custom_endpoint: Optional[Endpoint] = None
custom_endpoint: Endpoint | None = None
if self.parsed_args.product_name in ("custom", "generated"):
include_words = False
custom_endpoint = self.client.create_endpoint(
Expand All @@ -194,12 +193,12 @@ def _parse_sync(self) -> PredictResponse:

def _parse_async(self) -> AsyncPredictResponse:
"""Enqueues and processes the results of an asynchronous request."""
page_options: Optional[PageOptions] = None
page_options: PageOptions | None = None
if self.parsed_args.cut_doc and self.parsed_args.doc_pages:
page_options = PageOptions(
range(self.parsed_args.doc_pages), on_min_pages=0
)
custom_endpoint: Optional[Endpoint] = None
custom_endpoint: Endpoint | None = None
if self.parsed_args.product_name in ("custom", "generated"):
include_words = False
custom_endpoint = self.client.create_endpoint(
Expand Down Expand Up @@ -261,13 +260,13 @@ def _set_args(self) -> Namespace:
parsed_args = self.parser.parse_args()
return parsed_args

def _get_input_doc(self) -> Union[LocalInputSource, UrlInputSource]:
def _get_input_doc(self) -> LocalInputSource | UrlInputSource:
"""Loads an input document."""
if self.parsed_args.input_type == "file":
with open(self.parsed_args.path, "rb", buffering=30) as file_handle:
return self.client.source_from_file(file_handle)
elif self.parsed_args.input_type == "base64":
with open(self.parsed_args.path, "rt", encoding="ascii") as base64_handle:
with open(self.parsed_args.path, encoding="ascii") as base64_handle:
return self.client.source_from_b64string(
base64_handle.read(), "test.jpg"
)
Expand Down
6 changes: 3 additions & 3 deletions mindee/commands/cli_products.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Dict, Generic, Type
from typing import Generic

from mindee import product
from mindee.parsing.common import TypeInference
Expand All @@ -10,12 +10,12 @@ class CommandConfig(Generic[TypeInference]):
"""Configuration for a command."""

help: str
doc_class: Type[TypeInference]
doc_class: type[TypeInference]
is_sync: bool
is_async: bool


PRODUCTS: Dict[str, CommandConfig] = {
PRODUCTS: dict[str, CommandConfig] = {
"custom": CommandConfig(
help="Custom document type from API builder",
doc_class=product.CustomV1,
Expand Down
Loading
Loading