clarifai 11.2.4rc3__py3-none-any.whl → 11.3.0rc1__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-311.pyc +0 -0
- clarifai/__pycache__/errors.cpython-311.pyc +0 -0
- clarifai/__pycache__/versions.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/compute_cluster.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/deployment.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/nodepool.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-311.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-311.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-311.pyc +0 -0
- clarifai/client/deployment.py +3 -1
- clarifai/client/model.py +7 -3
- clarifai/constants/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/dataset.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/input.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/rag.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/constants/__pycache__/workflow.cpython-311.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/multimodal.cpython-311.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-311.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__/coco_detection.cpython-311.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/imagenet_classification.cpython-311.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-311.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_builder.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-311.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-311.pyc +0 -0
- clarifai/runners/models/model_builder.py +14 -1
- clarifai/runners/models/model_class.py +4 -2
- clarifai/runners/utils/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-311.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-311.pyc +0 -0
- clarifai/runners/utils/data_handler.py +210 -271
- clarifai/runners/utils/data_types.py +3 -3
- clarifai/runners/utils/data_utils.py +8 -7
- clarifai/runners/utils/method_signatures.py +0 -8
- clarifai/schema/__pycache__/search.cpython-311.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-311.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-311.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-311.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-311.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__/helpers.cpython-311.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/main.cpython-311.pyc +0 -0
- clarifai/utils/protobuf.py +143 -0
- clarifai/workflows/__pycache__/__init__.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-311.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-311.pyc +0 -0
- {clarifai-11.2.4rc3.dist-info → clarifai-11.3.0rc1.dist-info}/METADATA +14 -3
- {clarifai-11.2.4rc3.dist-info → clarifai-11.3.0rc1.dist-info}/RECORD +96 -15
- {clarifai-11.2.4rc3.dist-info → clarifai-11.3.0rc1.dist-info}/WHEEL +1 -1
- {clarifai-11.2.4rc3.dist-info → clarifai-11.3.0rc1.dist-info}/LICENSE +0 -0
- {clarifai-11.2.4rc3.dist-info → clarifai-11.3.0rc1.dist-info}/entry_points.txt +0 -0
- {clarifai-11.2.4rc3.dist-info → clarifai-11.3.0rc1.dist-info}/top_level.txt +0 -0
@@ -1,292 +1,231 @@
|
|
1
|
-
import
|
2
|
-
from typing import Any
|
1
|
+
from typing import Dict, List, Tuple, Union
|
3
2
|
|
4
3
|
import numpy as np
|
5
4
|
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 Text as TextProto
|
9
|
-
from clarifai_grpc.grpc.api.resources_pb2 import Video as VideoProto
|
10
5
|
from clarifai_grpc.grpc.api.status import status_code_pb2, status_pb2
|
11
|
-
from
|
12
|
-
from google.protobuf.struct_pb2 import Struct
|
13
|
-
from PIL import Image as PILImage
|
14
|
-
|
15
|
-
|
16
|
-
def metadata_to_dict(data: resources_pb2.Data) -> dict:
|
17
|
-
return MessageToDict(data.metadata)
|
18
|
-
|
19
|
-
|
20
|
-
def dict_to_metadata(data: resources_pb2.Data, metadata_dict: dict):
|
21
|
-
struct = Struct()
|
22
|
-
ParseDict(metadata_dict, struct)
|
23
|
-
data.metadata.CopyFrom(struct)
|
24
|
-
|
25
|
-
|
26
|
-
def kwargs_to_proto(*args, **kwargs) -> resources_pb2.Data:
|
27
|
-
"""Converts the kwargs to a Clarifai protobuf Data message."""
|
28
|
-
|
29
|
-
kwargs = dict(kwargs)
|
30
|
-
if any(k.startswith("_arg_") for k in kwargs.keys()):
|
31
|
-
raise ValueError("Keys starting with '_arg_' are reserved for positional arguments")
|
32
|
-
for arg_i, arg in enumerate(args):
|
33
|
-
kwargs[f"_arg_{arg_i}"] = arg
|
34
|
-
|
35
|
-
def _handle_list(target_data, value_list, part_name):
|
36
|
-
"""Handles list values by processing each item into a new part."""
|
37
|
-
if isinstance(value_list[0], dict):
|
38
|
-
raise ValueError("List of dictionaries is not supported")
|
39
|
-
|
40
|
-
for item in value_list:
|
41
|
-
new_part = target_data.parts.add()
|
42
|
-
_process_value(new_part.data, item, part_name)
|
43
|
-
|
44
|
-
def _process_value(target_data, value, part_name):
|
45
|
-
"""Processes individual values and sets the appropriate proto field."""
|
46
|
-
if isinstance(value, Text):
|
47
|
-
target_data.text.CopyFrom(value.to_proto())
|
48
|
-
elif isinstance(value, Image):
|
49
|
-
target_data.image.CopyFrom(value.to_proto())
|
50
|
-
elif isinstance(value, Audio):
|
51
|
-
target_data.audio.CopyFrom(value.to_proto())
|
52
|
-
elif isinstance(value, Video):
|
53
|
-
target_data.video.CopyFrom(value.to_proto())
|
54
|
-
elif isinstance(value, str):
|
55
|
-
target_data.text.raw = value
|
56
|
-
elif isinstance(value, bytes):
|
57
|
-
target_data.bytes_value = value
|
58
|
-
elif isinstance(value, int):
|
59
|
-
target_data.int_value = value
|
60
|
-
elif isinstance(value, float):
|
61
|
-
target_data.float_value = value
|
62
|
-
elif isinstance(value, bool):
|
63
|
-
target_data.bool_value = value
|
64
|
-
elif isinstance(value, np.ndarray):
|
65
|
-
ndarray_proto = resources_pb2.NDArray(
|
66
|
-
buffer=value.tobytes(), shape=value.shape, dtype=str(value.dtype))
|
67
|
-
target_data.ndarray.CopyFrom(ndarray_proto)
|
68
|
-
elif isinstance(value, PILImage.Image):
|
69
|
-
image = Image.from_pil(value)
|
70
|
-
target_data.image.CopyFrom(image.to_proto())
|
71
|
-
else:
|
72
|
-
raise TypeError(f"Unsupported type {type(value)} for part '{part_name}'")
|
73
|
-
|
74
|
-
data_proto = resources_pb2.Data()
|
75
|
-
for part_name, part_value in kwargs.items():
|
76
|
-
part = data_proto.parts.add()
|
77
|
-
part.id = part_name
|
78
|
-
|
79
|
-
if isinstance(part_value, list):
|
80
|
-
_handle_list(part.data, part_value, part_name)
|
81
|
-
elif isinstance(part_value, dict):
|
82
|
-
dict_to_metadata(part.data, part_value)
|
83
|
-
else:
|
84
|
-
_process_value(part.data, part_value, part_name)
|
85
|
-
return data_proto
|
86
|
-
|
87
|
-
|
88
|
-
def proto_to_kwargs(data: resources_pb2.Data) -> dict:
|
89
|
-
"""Converts the Clarifai protobuf Data message to a dictionary."""
|
90
|
-
|
91
|
-
def process_part(part, allow_metadata: bool = True) -> object:
|
92
|
-
if part.HasField("text"):
|
93
|
-
return Text.from_proto(part.text).text
|
94
|
-
elif part.HasField("image"):
|
95
|
-
return Image(part.image)
|
96
|
-
elif part.HasField("audio"):
|
97
|
-
return Audio(part.audio)
|
98
|
-
elif part.HasField("video"):
|
99
|
-
return Video(part.video)
|
100
|
-
elif part.bytes_value != b'':
|
101
|
-
return part.bytes_value
|
102
|
-
elif part.int_value != 0:
|
103
|
-
return part.int_value
|
104
|
-
elif part.float_value != 0.0:
|
105
|
-
return part.float_value
|
106
|
-
elif part.bool_value is not False:
|
107
|
-
return part.bool_value
|
108
|
-
elif part.HasField("ndarray"):
|
109
|
-
ndarray = part.ndarray
|
110
|
-
return np.frombuffer(ndarray.buffer, dtype=np.dtype(ndarray.dtype)).reshape(ndarray.shape)
|
111
|
-
elif part.HasField("metadata"):
|
112
|
-
if not allow_metadata:
|
113
|
-
raise ValueError("Metadata in list is not supported")
|
114
|
-
return metadata_to_dict(part)
|
115
|
-
elif part.parts:
|
116
|
-
return [process_part(p.data,) for p in part.parts]
|
117
|
-
else:
|
118
|
-
raise ValueError(f"Unknown part data: {part}")
|
119
|
-
|
120
|
-
kwargs = {}
|
121
|
-
part_names = [part.id for part in data.parts]
|
122
|
-
assert "return" not in part_names, "The key 'return' is reserved"
|
123
|
-
for part in data.parts:
|
124
|
-
part_name = part.id
|
125
|
-
part_data = part.data
|
126
|
-
kwargs[part_name] = process_part(part_data)
|
127
|
-
args = [kwargs.pop(f"_arg_{i}") for i in range(len(kwargs)) if f"_arg_{i}" in kwargs]
|
128
|
-
return args, kwargs
|
129
|
-
|
130
|
-
|
131
|
-
class Output:
|
132
|
-
|
133
|
-
def __init__(self, *args, **kwargs: Any):
|
134
|
-
|
135
|
-
if not kwargs:
|
136
|
-
raise ValueError("Output must have at least one key-value pair")
|
137
|
-
if isinstance(kwargs, dict):
|
138
|
-
kwargs = kwargs
|
139
|
-
else:
|
140
|
-
raise ValueError("Output must be a dictionary")
|
141
|
-
self.parts = kwargs
|
142
|
-
self.args = args
|
143
|
-
|
144
|
-
def __repr__(self):
|
145
|
-
args_str = ', '.join(repr(arg) for arg in self.args)
|
146
|
-
kwargs_str = ', '.join(f"{k}={v!r}" for k, v in self.parts.items())
|
147
|
-
parts = []
|
148
|
-
if args_str:
|
149
|
-
parts.append(args_str)
|
150
|
-
if kwargs_str:
|
151
|
-
parts.append(kwargs_str)
|
152
|
-
return f"Output({', '.join(parts)})"
|
153
|
-
|
154
|
-
def to_proto(self) -> resources_pb2.Output:
|
155
|
-
"""Converts the Output instance to a Clarifai protobuf Output message."""
|
156
|
-
data_proto = kwargs_to_proto(*self.args, **self.parts)
|
157
|
-
|
158
|
-
return resources_pb2.Output(
|
159
|
-
data=data_proto, status=status_pb2.Status(code=status_code_pb2.SUCCESS))
|
160
|
-
|
161
|
-
|
162
|
-
class Text:
|
163
|
-
|
164
|
-
def __init__(self, text: str):
|
165
|
-
self.text = text
|
166
|
-
|
167
|
-
def to_proto(self) -> TextProto:
|
168
|
-
return TextProto(raw=self.text)
|
6
|
+
from PIL import Image
|
169
7
|
|
170
|
-
|
171
|
-
def from_proto(cls, proto: TextProto) -> "Text":
|
172
|
-
return cls(proto.raw)
|
8
|
+
from clarifai.client.auth.helper import ClarifaiAuthHelper
|
173
9
|
|
10
|
+
from .data_utils import bytes_to_image, image_to_bytes
|
174
11
|
|
175
|
-
class Image:
|
176
12
|
|
177
|
-
|
178
|
-
self.proto = proto_image
|
13
|
+
class BaseDataHandler:
|
179
14
|
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
183
20
|
|
184
|
-
|
185
|
-
def
|
186
|
-
self.
|
21
|
+
#
|
22
|
+
def to_python(self):
|
23
|
+
return dict(text=self.text, image=self.image, audio=self.audio)
|
187
24
|
|
25
|
+
# ---------------- Start get/setters ---------------- #
|
26
|
+
# Proto
|
188
27
|
@property
|
189
|
-
def
|
190
|
-
return self.
|
191
|
-
|
192
|
-
@bytes.setter
|
193
|
-
def bytes(self, value: bytes):
|
194
|
-
self.proto.base64 = value
|
195
|
-
|
196
|
-
def __repr__(self) -> str:
|
197
|
-
attrs = []
|
198
|
-
if self.url:
|
199
|
-
attrs.append(f"url={self.url!r}")
|
200
|
-
if self.bytes:
|
201
|
-
attrs.append(f"bytes=<{len(self.bytes)} bytes>")
|
202
|
-
return f"Image({', '.join(attrs)})"
|
203
|
-
|
204
|
-
@classmethod
|
205
|
-
def from_url(cls, url: str) -> "Image":
|
206
|
-
proto_image = ImageProto(url=url)
|
207
|
-
return cls(proto_image)
|
208
|
-
|
209
|
-
@classmethod
|
210
|
-
def from_pil(cls, pil_image: PILImage.Image) -> "Image":
|
211
|
-
with io.BytesIO() as output:
|
212
|
-
pil_image.save(output, format="PNG")
|
213
|
-
image_bytes = output.getvalue()
|
214
|
-
proto_image = ImageProto(base64=image_bytes)
|
215
|
-
return cls(proto_image)
|
216
|
-
|
217
|
-
def to_pil(self) -> PILImage.Image:
|
218
|
-
return PILImage.open(io.BytesIO(self.proto.base64))
|
219
|
-
|
220
|
-
def to_numpy(self) -> np.ndarray:
|
221
|
-
# below is very slow, need to find a better way
|
222
|
-
# return np.array(self.to_pil())
|
223
|
-
pass
|
224
|
-
|
225
|
-
def to_proto(self) -> ImageProto:
|
226
|
-
return self.proto
|
227
|
-
|
228
|
-
|
229
|
-
class Audio:
|
230
|
-
|
231
|
-
def __init__(self, proto_audio: AudioProto):
|
232
|
-
self.proto = proto_audio
|
28
|
+
def proto(self):
|
29
|
+
return self._proto
|
233
30
|
|
31
|
+
# Status
|
234
32
|
@property
|
235
|
-
def
|
236
|
-
return self.
|
33
|
+
def status(self) -> status_pb2.Status:
|
34
|
+
return self._proto.status
|
237
35
|
|
238
|
-
|
239
|
-
|
240
|
-
self.
|
36
|
+
def set_status(self, code: str, description: str = ""):
|
37
|
+
self._proto.status.code = code
|
38
|
+
self._proto.status.description = description
|
241
39
|
|
40
|
+
# Text
|
242
41
|
@property
|
243
|
-
def
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
def
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
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]
|
263
172
|
|
264
|
-
def
|
265
|
-
|
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)))
|
266
179
|
|
267
|
-
|
268
|
-
def url(self) -> str:
|
269
|
-
return self.proto.url
|
180
|
+
# ---------------- End get/setters ---------------- #
|
270
181
|
|
271
|
-
|
272
|
-
|
273
|
-
|
182
|
+
# Constructors
|
183
|
+
@classmethod
|
184
|
+
def from_proto(cls, proto):
|
185
|
+
clss = cls(proto=proto)
|
186
|
+
return clss
|
274
187
|
|
275
|
-
@
|
276
|
-
def
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
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)
|
@@ -160,8 +160,8 @@ class Text(MessageData):
|
|
160
160
|
|
161
161
|
class Concept(MessageData):
|
162
162
|
|
163
|
-
def __init__(self,
|
164
|
-
self.id =
|
163
|
+
def __init__(self, name: str, value: float = 1):
|
164
|
+
self.id = name
|
165
165
|
self.name = name
|
166
166
|
self.value = value
|
167
167
|
|
@@ -173,7 +173,7 @@ class Concept(MessageData):
|
|
173
173
|
|
174
174
|
@classmethod
|
175
175
|
def from_proto(cls, proto: ConceptProto) -> "Concept":
|
176
|
-
return cls(proto.
|
176
|
+
return cls(proto.name, proto.value)
|
177
177
|
|
178
178
|
|
179
179
|
class Region(MessageData):
|
@@ -68,14 +68,14 @@ class InputField(MessageData):
|
|
68
68
|
min_value=None,
|
69
69
|
max_value=None,
|
70
70
|
choices=None,
|
71
|
-
|
71
|
+
is_param=True
|
72
72
|
):
|
73
73
|
self.default = default
|
74
74
|
self.description = description
|
75
75
|
self.min_value = min_value
|
76
76
|
self.max_value = max_value
|
77
77
|
self.choices = choices
|
78
|
-
|
78
|
+
self.is_param = is_param
|
79
79
|
|
80
80
|
def __repr__(self) -> str:
|
81
81
|
attrs = []
|
@@ -89,7 +89,7 @@ class InputField(MessageData):
|
|
89
89
|
attrs.append(f"max_value={self.max_value!r}")
|
90
90
|
if self.choices is not None:
|
91
91
|
attrs.append(f"choices={self.choices!r}")
|
92
|
-
|
92
|
+
attrs.append(f"is_param={self.is_param!r}")
|
93
93
|
return f"InputField({', '.join(attrs)})"
|
94
94
|
|
95
95
|
def to_proto(self, proto=None) -> InputFieldProto:
|
@@ -112,7 +112,7 @@ class InputField(MessageData):
|
|
112
112
|
if self.max_value is not None:
|
113
113
|
range_info.max = float(self.max_value)
|
114
114
|
proto.model_type_range_info.CopyFrom(range_info)
|
115
|
-
|
115
|
+
proto.is_param = self.is_param
|
116
116
|
|
117
117
|
if self.default is not None:
|
118
118
|
proto = self.set_default(proto, self.default)
|
@@ -159,7 +159,7 @@ class InputField(MessageData):
|
|
159
159
|
min_value=min_value,
|
160
160
|
max_value=max_value,
|
161
161
|
choices=choices,
|
162
|
-
|
162
|
+
is_param=proto.is_param
|
163
163
|
)
|
164
164
|
|
165
165
|
@classmethod
|
@@ -171,12 +171,13 @@ class InputField(MessageData):
|
|
171
171
|
if default is not None:
|
172
172
|
proto.default = json.dumps(default)
|
173
173
|
return proto
|
174
|
-
except
|
174
|
+
except Exception:
|
175
175
|
if default is not None:
|
176
176
|
proto.default = str(default)
|
177
177
|
return proto
|
178
178
|
except Exception as e:
|
179
|
-
raise ValueError(
|
179
|
+
raise ValueError(
|
180
|
+
f"Error setting default value of type, {type(default)} and value: {default}: {e}")
|
180
181
|
|
181
182
|
@classmethod
|
182
183
|
def get_default(cls, proto):
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import collections.abc as abc
|
2
2
|
import inspect
|
3
3
|
import json
|
4
|
-
import logging
|
5
4
|
from collections import namedtuple
|
6
5
|
from typing import Dict, List, Tuple, get_args, get_origin
|
7
6
|
|
@@ -313,13 +312,6 @@ def deserialize(proto, signatures, inference_params={}, is_output=False):
|
|
313
312
|
kwargs[sig.name] = serializer.deserialize(part.data)
|
314
313
|
elif inference_params_value is not None:
|
315
314
|
kwargs[sig.name] = inference_params_value
|
316
|
-
elif sig.default and (sig.required is False) and (not is_output):
|
317
|
-
try:
|
318
|
-
kwargs[sig.name] = data_utils.InputField.get_default(sig)
|
319
|
-
except Exception as e:
|
320
|
-
# default is not set, so ignore
|
321
|
-
logging.exception('Default value not set for %s: %s', sig.name, e)
|
322
|
-
pass
|
323
315
|
else:
|
324
316
|
if sig_i == 0:
|
325
317
|
# possible inlined first value
|
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
|