clarifai 11.3.0__py3-none-any.whl → 11.3.0rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- clarifai/__init__.py +1 -1
- clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/__pycache__/errors.cpython-310.pyc +0 -0
- clarifai/__pycache__/errors.cpython-311.pyc +0 -0
- clarifai/__pycache__/versions.cpython-310.pyc +0 -0
- clarifai/__pycache__/versions.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-39.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/compute_cluster.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/compute_cluster.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/deployment.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/deployment.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/nodepool.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/nodepool.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-311.pyc +0 -0
- clarifai/client/cli/__init__.py +0 -0
- clarifai/client/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
- clarifai/client/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
- clarifai/client/cli/base_cli.py +88 -0
- clarifai/client/cli/model_cli.py +29 -0
- clarifai/constants/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/dataset.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/input.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/input.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/rag.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/rag.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/workflow.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/workflow.cpython-311.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/multimodal.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/multimodal.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/coco_detection.cpython-311.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/imagenet_classification.cpython-311.pyc +0 -0
- clarifai/models/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/modules/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-311.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-39.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/dockerfile_template/Dockerfile.cpu.template +31 -0
- clarifai/runners/dockerfile_template/Dockerfile.cuda.template +42 -0
- clarifai/runners/dockerfile_template/Dockerfile.nim +71 -0
- clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-39.pyc +0 -0
- clarifai/runners/models/__pycache__/model_builder.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-310-pytest-7.1.2.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
- clarifai/runners/models/base_typed_model.py +238 -0
- clarifai/runners/models/model_builder.py +14 -1
- clarifai/runners/models/model_class_refract.py +80 -0
- clarifai/runners/models/model_upload.py +607 -0
- clarifai/runners/models/temp.py +25 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/buffered_stream.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/buffered_stream.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/buffered_stream.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/constants.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/constants.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/constants.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/grpc_server.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/grpc_server.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/grpc_server.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/health.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/health.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/health.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/stream_source.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/stream_source.cpython-39.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-38.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-39.pyc +0 -0
- clarifai/runners/utils/data_handler.py +231 -0
- clarifai/runners/utils/data_handler_refract.py +213 -0
- clarifai/runners/utils/data_utils.py +107 -14
- clarifai/runners/utils/logger.py +0 -0
- clarifai/runners/utils/openai_format.py +87 -0
- clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/schema/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/utils/__pycache__/cli.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/cli.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/config.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/constants.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/constants.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/model_train.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/protobuf.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/helpers.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/main.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/main.cpython-39.pyc +0 -0
- clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/__init__.cpython-39.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-311.pyc +0 -0
- {clarifai-11.3.0.dist-info → clarifai-11.3.0rc2.dist-info}/METADATA +3 -15
- clarifai-11.3.0rc2.dist-info/RECORD +322 -0
- {clarifai-11.3.0.dist-info → clarifai-11.3.0rc2.dist-info}/WHEEL +1 -1
- clarifai-11.3.0.dist-info/RECORD +0 -107
- {clarifai-11.3.0.dist-info/licenses → clarifai-11.3.0rc2.dist-info}/LICENSE +0 -0
- {clarifai-11.3.0.dist-info → clarifai-11.3.0rc2.dist-info}/entry_points.txt +0 -0
- {clarifai-11.3.0.dist-info → clarifai-11.3.0rc2.dist-info}/top_level.txt +0 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,231 @@
|
|
1
|
+
from typing import Dict, List, Tuple, Union
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
from clarifai_grpc.grpc.api import resources_pb2
|
5
|
+
from clarifai_grpc.grpc.api.status import status_code_pb2, status_pb2
|
6
|
+
from PIL import Image
|
7
|
+
|
8
|
+
from clarifai.client.auth.helper import ClarifaiAuthHelper
|
9
|
+
|
10
|
+
from .data_utils import bytes_to_image, image_to_bytes
|
11
|
+
|
12
|
+
|
13
|
+
class BaseDataHandler:
|
14
|
+
|
15
|
+
def __init__(self,
|
16
|
+
proto: Union[resources_pb2.Input, resources_pb2.Output],
|
17
|
+
auth: ClarifaiAuthHelper = None):
|
18
|
+
self._proto = proto
|
19
|
+
self._auth = auth
|
20
|
+
|
21
|
+
#
|
22
|
+
def to_python(self):
|
23
|
+
return dict(text=self.text, image=self.image, audio=self.audio)
|
24
|
+
|
25
|
+
# ---------------- Start get/setters ---------------- #
|
26
|
+
# Proto
|
27
|
+
@property
|
28
|
+
def proto(self):
|
29
|
+
return self._proto
|
30
|
+
|
31
|
+
# Status
|
32
|
+
@property
|
33
|
+
def status(self) -> status_pb2.Status:
|
34
|
+
return self._proto.status
|
35
|
+
|
36
|
+
def set_status(self, code: str, description: str = ""):
|
37
|
+
self._proto.status.code = code
|
38
|
+
self._proto.status.description = description
|
39
|
+
|
40
|
+
# Text
|
41
|
+
@property
|
42
|
+
def text(self) -> Union[None, str]:
|
43
|
+
data = self._proto.data.text
|
44
|
+
text = None
|
45
|
+
if data.ByteSize():
|
46
|
+
if data.raw:
|
47
|
+
text = data.raw
|
48
|
+
else:
|
49
|
+
raise NotImplementedError
|
50
|
+
return text
|
51
|
+
|
52
|
+
def set_text(self, text: str):
|
53
|
+
self._proto.data.text.raw = text
|
54
|
+
|
55
|
+
# Image
|
56
|
+
@property
|
57
|
+
def image(self, format: str = "np") -> Union[None, Image.Image, np.ndarray]:
|
58
|
+
data = self._proto.data.image
|
59
|
+
image = None
|
60
|
+
if data.ByteSize():
|
61
|
+
data: resources_pb2.Image = data
|
62
|
+
if data.base64:
|
63
|
+
image = data.base64
|
64
|
+
elif data.url:
|
65
|
+
raise NotImplementedError
|
66
|
+
image = bytes_to_image(image)
|
67
|
+
image = image if not format == "np" else np.asarray(image).astype("uint8")
|
68
|
+
return image
|
69
|
+
|
70
|
+
def set_image(self, image: Union[Image.Image, np.ndarray]):
|
71
|
+
if isinstance(image, np.ndarray):
|
72
|
+
image = Image.fromarray(image)
|
73
|
+
self._proto.data.image.base64 = image_to_bytes(image)
|
74
|
+
|
75
|
+
# Audio
|
76
|
+
@property
|
77
|
+
def audio(self) -> bytes:
|
78
|
+
data = self._proto.data.audio
|
79
|
+
audio = None
|
80
|
+
if data.ByteSize():
|
81
|
+
if data.base64:
|
82
|
+
audio = data.base64
|
83
|
+
return audio
|
84
|
+
|
85
|
+
def set_audio(self, audio: bytes):
|
86
|
+
self._proto.data.audio.base64 = audio
|
87
|
+
|
88
|
+
# Bboxes
|
89
|
+
@property
|
90
|
+
def bboxes(self, real_coord: bool = False, image_width: int = None,
|
91
|
+
image_height: int = None) -> Tuple[List, List, List]:
|
92
|
+
if real_coord:
|
93
|
+
assert (image_height or image_width
|
94
|
+
), "image_height and image_width are required when when return real coordinates"
|
95
|
+
xyxy = []
|
96
|
+
scores = []
|
97
|
+
concepts = []
|
98
|
+
for _, each in enumerate(self._proto.data.regions):
|
99
|
+
box = each.region_info
|
100
|
+
score = each.value
|
101
|
+
concept = each.data.concepts[0].id
|
102
|
+
x1 = box.left_col
|
103
|
+
y1 = box.top_row
|
104
|
+
x2 = box.right_col
|
105
|
+
y2 = box.bottom_row
|
106
|
+
if real_coord:
|
107
|
+
x1 = x1 * image_width
|
108
|
+
y1 = y1 * image_height
|
109
|
+
x2 = x2 * image_width
|
110
|
+
y2 = y2 * image_height
|
111
|
+
xyxy.append([x1, y1, x2, y2])
|
112
|
+
scores.append(score)
|
113
|
+
concepts.append(concept)
|
114
|
+
|
115
|
+
return xyxy, scores, concepts
|
116
|
+
|
117
|
+
def set_bboxes(self,
|
118
|
+
boxes: list,
|
119
|
+
scores: list,
|
120
|
+
concepts: list,
|
121
|
+
real_coord: bool = False,
|
122
|
+
image_width: int = None,
|
123
|
+
image_height: int = None):
|
124
|
+
if real_coord:
|
125
|
+
assert (image_height and
|
126
|
+
image_width), "image_height and image_width are required when `real_coord` is set"
|
127
|
+
bboxes = [[x[1] / image_height, x[0] / image_width, x[3] / image_height, x[2] / image_width]
|
128
|
+
for x in boxes] # normalize the bboxes to [0,1] and [y1 x1 y2 x2]
|
129
|
+
bboxes = np.clip(bboxes, 0, 1.0)
|
130
|
+
|
131
|
+
regions = []
|
132
|
+
for ith, bbox in enumerate(bboxes):
|
133
|
+
score = scores[ith]
|
134
|
+
concept = concepts[ith]
|
135
|
+
if any([each > 1.0 for each in bbox]):
|
136
|
+
assert ValueError(
|
137
|
+
"Box coordinates is not normalized between [0, 1]. Please set format_box to True and provide image_height and image_width to normalize"
|
138
|
+
)
|
139
|
+
region = resources_pb2.RegionInfo(bounding_box=resources_pb2.BoundingBox(
|
140
|
+
top_row=bbox[0], # y_min
|
141
|
+
left_col=bbox[1], # x_min
|
142
|
+
bottom_row=bbox[2], # y_max
|
143
|
+
right_col=bbox[3], # x_max
|
144
|
+
))
|
145
|
+
data = resources_pb2.Data(concepts=resources_pb2.Concept(id=concept, value=score))
|
146
|
+
regions.append(resources_pb2.Region(region_info=region, data=data))
|
147
|
+
|
148
|
+
self._proto.data.regions = regions
|
149
|
+
|
150
|
+
# Concepts
|
151
|
+
@property
|
152
|
+
def concepts(self) -> Dict[str, float]:
|
153
|
+
con_scores = {}
|
154
|
+
for each in self.proto.data.concepts:
|
155
|
+
con_scores.update({each.id: each.value})
|
156
|
+
return con_scores
|
157
|
+
|
158
|
+
def set_concepts(self, concept_score_pairs: Dict[str, float]):
|
159
|
+
concepts = []
|
160
|
+
for concept, score in concept_score_pairs.items():
|
161
|
+
con_score = resources_pb2.Concept(id=concept, name=concept, value=score)
|
162
|
+
concepts.append(con_score)
|
163
|
+
if concepts:
|
164
|
+
self._proto.data.ClearField("concepts")
|
165
|
+
for each in concepts:
|
166
|
+
self._proto.data.concepts.append(each)
|
167
|
+
|
168
|
+
# Embeddings
|
169
|
+
@property
|
170
|
+
def embeddings(self) -> List[List[float]]:
|
171
|
+
return [each.vector for each in self.proto.data.embeddings]
|
172
|
+
|
173
|
+
def set_embeddings(self, list_vectors: List[List[float]]):
|
174
|
+
if list_vectors[0]:
|
175
|
+
self._proto.data.ClearField("embeddings")
|
176
|
+
for vec in list_vectors:
|
177
|
+
self._proto.data.embeddings.append(
|
178
|
+
resources_pb2.Embedding(vector=vec, num_dimensions=len(vec)))
|
179
|
+
|
180
|
+
# ---------------- End get/setters ---------------- #
|
181
|
+
|
182
|
+
# Constructors
|
183
|
+
@classmethod
|
184
|
+
def from_proto(cls, proto):
|
185
|
+
clss = cls(proto=proto)
|
186
|
+
return clss
|
187
|
+
|
188
|
+
@classmethod
|
189
|
+
def from_data(
|
190
|
+
cls,
|
191
|
+
status_code: int = status_code_pb2.SUCCESS,
|
192
|
+
status_description: str = "",
|
193
|
+
text: str = None,
|
194
|
+
image: Union[Image.Image, np.ndarray] = None,
|
195
|
+
audio: bytes = None,
|
196
|
+
boxes: dict = None,
|
197
|
+
concepts: Dict[str, float] = {},
|
198
|
+
embeddings: List[List[float]] = [],
|
199
|
+
) -> 'OutputDataHandler':
|
200
|
+
clss = cls(proto=resources_pb2.Output())
|
201
|
+
if isinstance(image, Image.Image) or isinstance(image, np.ndarray):
|
202
|
+
clss.set_image(image)
|
203
|
+
if text:
|
204
|
+
clss.set_text(text)
|
205
|
+
if audio:
|
206
|
+
clss.set_audio(audio)
|
207
|
+
if boxes:
|
208
|
+
clss.set_bboxes(**boxes)
|
209
|
+
if concepts:
|
210
|
+
clss.set_concepts(concepts)
|
211
|
+
if embeddings:
|
212
|
+
clss.set_embeddings(embeddings)
|
213
|
+
|
214
|
+
clss.set_status(code=status_code, description=status_description)
|
215
|
+
return clss
|
216
|
+
|
217
|
+
|
218
|
+
class InputDataHandler(BaseDataHandler):
|
219
|
+
|
220
|
+
def __init__(self,
|
221
|
+
proto: resources_pb2.Input = resources_pb2.Input(),
|
222
|
+
auth: ClarifaiAuthHelper = None):
|
223
|
+
super().__init__(proto=proto, auth=auth)
|
224
|
+
|
225
|
+
|
226
|
+
class OutputDataHandler(BaseDataHandler):
|
227
|
+
|
228
|
+
def __init__(self,
|
229
|
+
proto: resources_pb2.Output = resources_pb2.Output(),
|
230
|
+
auth: ClarifaiAuthHelper = None):
|
231
|
+
super().__init__(proto=proto, auth=auth)
|
@@ -0,0 +1,213 @@
|
|
1
|
+
import io
|
2
|
+
from typing import Any, Callable, Dict, Type
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
from clarifai_grpc.grpc.api import resources_pb2
|
6
|
+
from clarifai_grpc.grpc.api.resources_pb2 import Audio as AudioProto
|
7
|
+
from clarifai_grpc.grpc.api.resources_pb2 import Image as ImageProto
|
8
|
+
from clarifai_grpc.grpc.api.resources_pb2 import NDArray
|
9
|
+
from clarifai_grpc.grpc.api.resources_pb2 import Text as TextProto
|
10
|
+
from clarifai_grpc.grpc.api.resources_pb2 import Video as VideoProto
|
11
|
+
from google.protobuf.json_format import MessageToDict, ParseDict
|
12
|
+
from google.protobuf.struct_pb2 import Struct
|
13
|
+
from PIL import Image as PILImage
|
14
|
+
|
15
|
+
# Type registry for conversion between Python types and protobuf
|
16
|
+
_TYPE_HANDLERS: Dict[Type, Callable] = {
|
17
|
+
# Python type: (to_proto, from_proto)
|
18
|
+
TextProto: (
|
19
|
+
lambda value: value.to_proto(),
|
20
|
+
lambda proto: Text.from_proto(proto)
|
21
|
+
),
|
22
|
+
ImageProto: (
|
23
|
+
lambda value: value.to_proto(),
|
24
|
+
lambda proto: Image(proto)
|
25
|
+
),
|
26
|
+
AudioProto: (
|
27
|
+
lambda value: value.to_proto(),
|
28
|
+
lambda proto: Audio(proto)
|
29
|
+
),
|
30
|
+
VideoProto: (
|
31
|
+
lambda value: value.to_proto(),
|
32
|
+
lambda proto: Video(proto)
|
33
|
+
),
|
34
|
+
str: (
|
35
|
+
lambda value: TextProto(raw=value),
|
36
|
+
lambda proto: proto.raw
|
37
|
+
),
|
38
|
+
bytes: (
|
39
|
+
lambda value: resources_pb2.Data(base64=value),
|
40
|
+
lambda proto: proto.base64
|
41
|
+
),
|
42
|
+
int: (
|
43
|
+
lambda value: resources_pb2.Data(int_value=value),
|
44
|
+
lambda proto: proto.int_value
|
45
|
+
),
|
46
|
+
float: (
|
47
|
+
lambda value: resources_pb2.Data(float_value=value),
|
48
|
+
lambda proto: proto.float_value
|
49
|
+
),
|
50
|
+
bool: (
|
51
|
+
lambda value: resources_pb2.Data(boolean=value),
|
52
|
+
lambda proto: proto.boolean
|
53
|
+
),
|
54
|
+
np.ndarray: (
|
55
|
+
lambda value: NDArray(buffer=value.tobytes(), shape=value.shape, dtype=str(value.dtype)),
|
56
|
+
lambda proto: np.frombuffer(proto.buffer, dtype=np.dtype(proto.dtype)).reshape(proto.shape)
|
57
|
+
),
|
58
|
+
PILImage.Image: (
|
59
|
+
lambda value: Image.from_pil(value).to_proto(),
|
60
|
+
lambda proto: Image(proto).to_pil()
|
61
|
+
),
|
62
|
+
dict: (
|
63
|
+
lambda value: _dict_to_metadata(value),
|
64
|
+
lambda proto: MessageToDict(proto.metadata)
|
65
|
+
)
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
def _dict_to_metadata(metadata: dict) -> Struct:
|
70
|
+
struct = Struct()
|
71
|
+
ParseDict(metadata, struct)
|
72
|
+
return struct
|
73
|
+
|
74
|
+
|
75
|
+
def _value_to_proto(value: Any) -> resources_pb2.Data:
|
76
|
+
"""Convert a Python value to a protobuf Data message."""
|
77
|
+
data = resources_pb2.Data()
|
78
|
+
for py_type, (to_proto, _) in _TYPE_HANDLERS.items():
|
79
|
+
if isinstance(value, py_type):
|
80
|
+
handler = to_proto
|
81
|
+
break
|
82
|
+
else:
|
83
|
+
if isinstance(value, (Text, Image, Audio, Video)):
|
84
|
+
data_part = getattr(data, type(value).__name__.lower())
|
85
|
+
data_part.CopyFrom(value.to_proto())
|
86
|
+
return data
|
87
|
+
raise TypeError(f"Unsupported type: {type(value)}")
|
88
|
+
|
89
|
+
result = handler(value)
|
90
|
+
if isinstance(result, resources_pb2.Data):
|
91
|
+
data.CopyFrom(result)
|
92
|
+
else:
|
93
|
+
field_name = type(result).DESCRIPTOR.name.lower()
|
94
|
+
getattr(data, field_name).CopyFrom(result)
|
95
|
+
return data
|
96
|
+
|
97
|
+
|
98
|
+
def _proto_to_value(proto: resources_pb2.Data) -> Any:
|
99
|
+
"""Convert a protobuf Data message to a Python value."""
|
100
|
+
for field in proto.DESCRIPTOR.fields:
|
101
|
+
if proto.HasField(field.name):
|
102
|
+
_, from_proto = _TYPE_HANDLERS.get(field.type, (None, None))
|
103
|
+
if from_proto:
|
104
|
+
return from_proto(getattr(proto, field.name))
|
105
|
+
if proto.parts:
|
106
|
+
return [_proto_to_value(part.data) for part in proto.parts]
|
107
|
+
return None
|
108
|
+
|
109
|
+
|
110
|
+
def kwargs_to_proto(**kwargs) -> resources_pb2.Data:
|
111
|
+
"""Convert keyword arguments to a Data proto."""
|
112
|
+
data_proto = resources_pb2.Data()
|
113
|
+
for part_name, part_value in kwargs.items():
|
114
|
+
part = data_proto.parts.add()
|
115
|
+
part.id = part_name
|
116
|
+
|
117
|
+
if isinstance(part_value, list):
|
118
|
+
for item in part_value:
|
119
|
+
item_proto = _value_to_proto(item)
|
120
|
+
part_part = part.data.parts.add()
|
121
|
+
part_part.data.CopyFrom(item_proto)
|
122
|
+
else:
|
123
|
+
part_proto = _value_to_proto(part_value)
|
124
|
+
part.data.CopyFrom(part_proto)
|
125
|
+
return data_proto
|
126
|
+
|
127
|
+
|
128
|
+
def proto_to_kwargs(data: resources_pb2.Data) -> dict:
|
129
|
+
"""Convert a Data proto to keyword arguments."""
|
130
|
+
kwargs = {}
|
131
|
+
for part in data.parts:
|
132
|
+
part_name = part.id
|
133
|
+
if part.data.parts:
|
134
|
+
kwargs[part_name] = [_proto_to_value(part.data) for _ in part.data.parts]
|
135
|
+
else:
|
136
|
+
kwargs[part_name] = _proto_to_value(part.data)
|
137
|
+
return kwargs
|
138
|
+
|
139
|
+
|
140
|
+
class Output:
|
141
|
+
|
142
|
+
def __init__(self, **kwargs: Any):
|
143
|
+
if not kwargs:
|
144
|
+
raise ValueError("Output must have at least one key-value pair")
|
145
|
+
self.parts = kwargs
|
146
|
+
|
147
|
+
def to_proto(self) -> resources_pb2.Output:
|
148
|
+
data_proto = kwargs_to_proto(**self.parts)
|
149
|
+
return resources_pb2.Output(data=data_proto)
|
150
|
+
|
151
|
+
|
152
|
+
class Text:
|
153
|
+
|
154
|
+
def __init__(self, text: str):
|
155
|
+
self.text = text
|
156
|
+
|
157
|
+
def to_proto(self) -> TextProto:
|
158
|
+
return TextProto(raw=self.text)
|
159
|
+
|
160
|
+
@classmethod
|
161
|
+
def from_proto(cls, proto: TextProto) -> "Text":
|
162
|
+
return cls(proto.raw)
|
163
|
+
|
164
|
+
|
165
|
+
class Image:
|
166
|
+
|
167
|
+
def __init__(self, proto_image: ImageProto):
|
168
|
+
self.proto = proto_image
|
169
|
+
|
170
|
+
@classmethod
|
171
|
+
def from_url(cls, url: str) -> "Image":
|
172
|
+
return cls(ImageProto(url=url))
|
173
|
+
|
174
|
+
@classmethod
|
175
|
+
def from_pil(cls, pil_image: PILImage.Image) -> "Image":
|
176
|
+
with io.BytesIO() as output:
|
177
|
+
pil_image.save(output, format="PNG")
|
178
|
+
return cls(ImageProto(base64=output.getvalue()))
|
179
|
+
|
180
|
+
def to_pil(self) -> PILImage.Image:
|
181
|
+
return PILImage.open(io.BytesIO(self.proto.base64))
|
182
|
+
|
183
|
+
def to_proto(self) -> ImageProto:
|
184
|
+
return self.proto
|
185
|
+
|
186
|
+
|
187
|
+
class Audio:
|
188
|
+
|
189
|
+
def __init__(self, proto_audio: AudioProto):
|
190
|
+
self.proto = proto_audio
|
191
|
+
|
192
|
+
def to_proto(self) -> AudioProto:
|
193
|
+
return self.proto
|
194
|
+
|
195
|
+
|
196
|
+
class Video:
|
197
|
+
|
198
|
+
def __init__(self, proto_video: VideoProto):
|
199
|
+
self.proto = proto_video
|
200
|
+
|
201
|
+
def to_proto(self) -> VideoProto:
|
202
|
+
return self.proto
|
203
|
+
|
204
|
+
|
205
|
+
'''
|
206
|
+
Type Handling Registry: Centralized conversion logic reduces duplication and enhances extensibility.
|
207
|
+
Simplified Conversion Functions: _value_to_proto and _proto_to_value handle all type conversions using the registry.
|
208
|
+
Streamlined Wrapper Methods: Common processing logic extracted into _process_request, reducing code duplication.
|
209
|
+
Improved Batch Processing: Uses ThreadPoolExecutor.map for cleaner batch prediction.
|
210
|
+
Error Handling: Clearer error messages and validation of required parameters.
|
211
|
+
Removed Redundant Checks: Simplified Output class initialization.
|
212
|
+
|
213
|
+
'''
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import operator
|
1
2
|
from io import BytesIO
|
2
3
|
from typing import List
|
3
4
|
|
@@ -61,21 +62,19 @@ def is_openai_chat_format(messages):
|
|
61
62
|
class InputField(MessageData):
|
62
63
|
"""A field that can be used to store input data."""
|
63
64
|
|
64
|
-
def __init__(
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# is_param=True
|
72
|
-
):
|
65
|
+
def __init__(self,
|
66
|
+
default=None,
|
67
|
+
description=None,
|
68
|
+
min_value=None,
|
69
|
+
max_value=None,
|
70
|
+
choices=None,
|
71
|
+
is_param=True):
|
73
72
|
self.default = default
|
74
73
|
self.description = description
|
75
74
|
self.min_value = min_value
|
76
75
|
self.max_value = max_value
|
77
76
|
self.choices = choices
|
78
|
-
|
77
|
+
self.is_param = is_param
|
79
78
|
|
80
79
|
def __repr__(self) -> str:
|
81
80
|
attrs = []
|
@@ -89,9 +88,104 @@ class InputField(MessageData):
|
|
89
88
|
attrs.append(f"max_value={self.max_value!r}")
|
90
89
|
if self.choices is not None:
|
91
90
|
attrs.append(f"choices={self.choices!r}")
|
92
|
-
|
91
|
+
attrs.append(f"is_param={self.is_param!r}")
|
93
92
|
return f"InputField({', '.join(attrs)})"
|
94
93
|
|
94
|
+
# All *explicit* conversions
|
95
|
+
def __int__(self):
|
96
|
+
return int(self.default)
|
97
|
+
|
98
|
+
def __float__(self):
|
99
|
+
return float(self.default)
|
100
|
+
|
101
|
+
def __str__(self):
|
102
|
+
return str(self.default)
|
103
|
+
|
104
|
+
def __bool__(self):
|
105
|
+
return bool(self.default)
|
106
|
+
|
107
|
+
def __index__(self):
|
108
|
+
return int(self.default) # for slicing
|
109
|
+
|
110
|
+
# sequence / mapping protocol delegation
|
111
|
+
def __len__(self):
|
112
|
+
return len(self.default)
|
113
|
+
|
114
|
+
def __iter__(self):
|
115
|
+
return iter(self.default)
|
116
|
+
|
117
|
+
def __reversed__(self):
|
118
|
+
return reversed(self.default)
|
119
|
+
|
120
|
+
def __contains__(self, item):
|
121
|
+
return item in self.default
|
122
|
+
|
123
|
+
def __getitem__(self, key):
|
124
|
+
return self.default[key]
|
125
|
+
|
126
|
+
def __setitem__(self, k, v):
|
127
|
+
self.default[k] = v
|
128
|
+
|
129
|
+
def __delitem__(self, k):
|
130
|
+
del self.default[k]
|
131
|
+
|
132
|
+
def __hash__(self):
|
133
|
+
return hash(self.default)
|
134
|
+
|
135
|
+
def __call__(self, *args, **kwargs):
|
136
|
+
return self.default(*args, **kwargs)
|
137
|
+
|
138
|
+
# Comparison operators
|
139
|
+
def __eq__(self, other):
|
140
|
+
return self.default == other
|
141
|
+
|
142
|
+
def __lt__(self, other):
|
143
|
+
return self.default < other
|
144
|
+
|
145
|
+
def __le__(self, other):
|
146
|
+
return self.default <= other
|
147
|
+
|
148
|
+
def __gt__(self, other):
|
149
|
+
return self.default > other
|
150
|
+
|
151
|
+
def __ge__(self, other):
|
152
|
+
return self.default >= other
|
153
|
+
|
154
|
+
# Arithmetic operators – # arithmetic & bitwise operators – auto-generated
|
155
|
+
_arith_ops = {
|
156
|
+
"__add__": operator.add,
|
157
|
+
"__sub__": operator.sub,
|
158
|
+
"__mul__": operator.mul,
|
159
|
+
"__truediv__": operator.truediv,
|
160
|
+
"__floordiv__": operator.floordiv,
|
161
|
+
"__mod__": operator.mod,
|
162
|
+
"__pow__": operator.pow,
|
163
|
+
"__and__": operator.and_,
|
164
|
+
"__or__": operator.or_,
|
165
|
+
"__xor__": operator.xor,
|
166
|
+
"__lshift__": operator.lshift,
|
167
|
+
"__rshift__": operator.rshift,
|
168
|
+
}
|
169
|
+
|
170
|
+
# Create both left- and right-hand versions of each operator
|
171
|
+
for _name, _op in _arith_ops.items():
|
172
|
+
|
173
|
+
def _make(op):
|
174
|
+
|
175
|
+
def _f(self, other, *, _op=op): # default arg binds op
|
176
|
+
return _op(self.default, other)
|
177
|
+
|
178
|
+
return _f
|
179
|
+
|
180
|
+
locals()[_name] = _make(_op)
|
181
|
+
locals()["__r" + _name[2:]] = _make(lambda x, y, _op=_op: _op(y, x))
|
182
|
+
del _name, _op, _make
|
183
|
+
|
184
|
+
# Attribute access delegation – anything we did *not* define above
|
185
|
+
# will automatically be looked up on the wrapped default value.
|
186
|
+
def __getattr__(self, item):
|
187
|
+
return getattr(self.default, item)
|
188
|
+
|
95
189
|
def to_proto(self, proto=None) -> InputFieldProto:
|
96
190
|
if proto is None:
|
97
191
|
proto = InputFieldProto()
|
@@ -112,7 +206,7 @@ class InputField(MessageData):
|
|
112
206
|
if self.max_value is not None:
|
113
207
|
range_info.max = float(self.max_value)
|
114
208
|
proto.model_type_range_info.CopyFrom(range_info)
|
115
|
-
|
209
|
+
proto.is_param = self.is_param
|
116
210
|
|
117
211
|
if self.default is not None:
|
118
212
|
proto = self.set_default(proto, self.default)
|
@@ -159,8 +253,7 @@ class InputField(MessageData):
|
|
159
253
|
min_value=min_value,
|
160
254
|
max_value=max_value,
|
161
255
|
choices=choices,
|
162
|
-
|
163
|
-
)
|
256
|
+
is_param=proto.is_param)
|
164
257
|
|
165
258
|
@classmethod
|
166
259
|
def set_default(cls, proto=None, default=None):
|
File without changes
|