clarifai 11.1.5rc7__py3-none-any.whl → 11.1.6__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/cli/model.py +40 -50
- clarifai/client/model.py +365 -95
- clarifai/runners/__init__.py +7 -2
- clarifai/runners/dockerfile_template/Dockerfile.template +1 -4
- clarifai/runners/models/base_typed_model.py +238 -0
- clarifai/runners/models/model_builder.py +9 -26
- clarifai/runners/models/model_class.py +28 -273
- clarifai/runners/models/model_run_locally.py +78 -3
- clarifai/runners/models/model_runner.py +0 -2
- clarifai/runners/models/model_servicer.py +2 -11
- clarifai/runners/utils/data_handler.py +205 -308
- {clarifai-11.1.5rc7.dist-info → clarifai-11.1.6.dist-info}/METADATA +26 -16
- clarifai-11.1.6.dist-info/RECORD +101 -0
- {clarifai-11.1.5rc7.dist-info → clarifai-11.1.6.dist-info}/WHEEL +1 -1
- clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/__pycache__/errors.cpython-310.pyc +0 -0
- clarifai/__pycache__/versions.cpython-310.pyc +0 -0
- clarifai/cli/__main__.py~ +0 -4
- clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/__main__.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/runner.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
- clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
- clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
- clarifai/client/model_client.py +0 -432
- clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
- clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
- clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/datasets/upload/loaders/__pycache__/coco_detection.cpython-310.pyc +0 -0
- clarifai/models/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/__pycache__/constants.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/_utils.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/build.cpython-310.pyc +0 -0
- clarifai/models/model_serving/cli/__pycache__/create.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/base.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/config.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/inference_parameter.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/__pycache__/output.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/serializer.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/triton_config.cpython-310.pyc +0 -0
- clarifai/models/model_serving/model_config/triton/__pycache__/wrappers.cpython-310.pyc +0 -0
- clarifai/models/model_serving/repo_build/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/models/model_serving/repo_build/__pycache__/build.cpython-310.pyc +0 -0
- clarifai/models/model_serving/repo_build/static_files/__pycache__/base_test.cpython-310-pytest-7.2.0.pyc +0 -0
- clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
- clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/__pycache__/server.cpython-310.pyc +0 -0
- clarifai/runners/dockerfile_template/Dockerfile.debug +0 -11
- clarifai/runners/dockerfile_template/Dockerfile.debug~ +0 -9
- clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_builder.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_servicer.cpython-310.pyc +0 -0
- clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_types.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/method_signatures.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/serializers.cpython-310.pyc +0 -0
- clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
- clarifai/runners/utils/data_types.py +0 -334
- clarifai/runners/utils/method_signatures.py +0 -452
- clarifai/runners/utils/serializers.py +0 -132
- clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
- clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
- clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/helpers.cpython-310.pyc +0 -0
- clarifai/utils/evaluation/__pycache__/main.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
- clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
- clarifai-11.1.5rc7.dist-info/RECORD +0 -203
- {clarifai-11.1.5rc7.dist-info → clarifai-11.1.6.dist-info}/LICENSE +0 -0
- {clarifai-11.1.5rc7.dist-info → clarifai-11.1.6.dist-info}/entry_points.txt +0 -0
- {clarifai-11.1.5rc7.dist-info → clarifai-11.1.6.dist-info}/top_level.txt +0 -0
@@ -1,334 +1,231 @@
|
|
1
|
-
import
|
2
|
-
from typing import Iterable, List, get_args, get_origin
|
1
|
+
from typing import Dict, List, Tuple, Union
|
3
2
|
|
4
3
|
import numpy as np
|
5
|
-
from clarifai_grpc.grpc.api
|
6
|
-
from clarifai_grpc.grpc.api.
|
7
|
-
from
|
8
|
-
from clarifai_grpc.grpc.api.resources_pb2 import Image as ImageProto
|
9
|
-
from clarifai_grpc.grpc.api.resources_pb2 import Region as RegionProto
|
10
|
-
from clarifai_grpc.grpc.api.resources_pb2 import Text as TextProto
|
11
|
-
from clarifai_grpc.grpc.api.resources_pb2 import Video as VideoProto
|
12
|
-
from PIL import Image as PILImage
|
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
|
13
7
|
|
8
|
+
from clarifai.client.auth.helper import ClarifaiAuthHelper
|
14
9
|
|
15
|
-
|
10
|
+
from .data_utils import bytes_to_image, image_to_bytes
|
16
11
|
|
17
|
-
def to_proto(self):
|
18
|
-
raise NotImplementedError
|
19
12
|
|
20
|
-
|
21
|
-
def from_proto(cls, proto):
|
22
|
-
raise NotImplementedError
|
23
|
-
|
24
|
-
def cast(self, python_type):
|
25
|
-
if python_type == self.__class__:
|
26
|
-
return self
|
27
|
-
raise TypeError(f'Incompatible type for {self.__class__.__name__}: {python_type}')
|
28
|
-
|
29
|
-
|
30
|
-
class Output(dict):
|
31
|
-
__getattr__ = dict.__getitem__
|
32
|
-
__setattr__ = dict.__setitem__
|
33
|
-
|
34
|
-
def __origin__(self):
|
35
|
-
return self
|
36
|
-
|
37
|
-
def __args__(self):
|
38
|
-
return list(self.keys())
|
39
|
-
|
40
|
-
|
41
|
-
class Input(dict):
|
42
|
-
__getattr__ = dict.__getitem__
|
43
|
-
__setattr__ = dict.__setitem__
|
44
|
-
|
45
|
-
def __origin__(self):
|
46
|
-
return self
|
47
|
-
|
48
|
-
def __args__(self):
|
49
|
-
return list(self.keys())
|
50
|
-
|
51
|
-
|
52
|
-
class Stream(Iterable):
|
53
|
-
pass
|
54
|
-
|
55
|
-
|
56
|
-
class Text(MessageData):
|
57
|
-
|
58
|
-
def __init__(self, text: str, url: str = None):
|
59
|
-
self.text = text
|
60
|
-
self.url = url
|
61
|
-
|
62
|
-
def to_proto(self) -> TextProto:
|
63
|
-
return TextProto(raw=self.text or '', self_url=self.url or '')
|
64
|
-
|
65
|
-
@classmethod
|
66
|
-
def from_proto(cls, proto: TextProto) -> "Text":
|
67
|
-
return cls(proto.raw, proto.url or None)
|
68
|
-
|
69
|
-
def cast(self, python_type):
|
70
|
-
if python_type == str:
|
71
|
-
return self.text
|
72
|
-
if python_type == Text:
|
73
|
-
return self
|
74
|
-
raise TypeError(f'Incompatible type for Text: {python_type}')
|
75
|
-
|
76
|
-
|
77
|
-
class Concept(MessageData):
|
13
|
+
class BaseDataHandler:
|
78
14
|
|
79
|
-
def __init__(self,
|
80
|
-
|
81
|
-
|
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
|
82
20
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
def to_proto(self):
|
87
|
-
return ConceptProto(name=self.name, value=self.value)
|
88
|
-
|
89
|
-
@classmethod
|
90
|
-
def from_proto(cls, proto: ConceptProto) -> "Concept":
|
91
|
-
return cls(proto.name, proto.value)
|
92
|
-
|
93
|
-
|
94
|
-
class Region(MessageData):
|
95
|
-
|
96
|
-
def __init__(self, proto_region: RegionProto):
|
97
|
-
self.proto = proto_region
|
21
|
+
#
|
22
|
+
def to_python(self):
|
23
|
+
return dict(text=self.text, image=self.image, audio=self.audio)
|
98
24
|
|
25
|
+
# ---------------- Start get/setters ---------------- #
|
26
|
+
# Proto
|
99
27
|
@property
|
100
|
-
def
|
101
|
-
|
102
|
-
return [bbox.left_col, bbox.top_row, bbox.right_col, bbox.bottom_row] # x1, y1, x2, y2
|
103
|
-
|
104
|
-
@box.setter
|
105
|
-
def box(self, value: List[float]):
|
106
|
-
bbox = self.proto.region_info.bounding_box
|
107
|
-
bbox.left_col, bbox.top_row, bbox.right_col, bbox.bottom_row = value
|
28
|
+
def proto(self):
|
29
|
+
return self._proto
|
108
30
|
|
31
|
+
# Status
|
109
32
|
@property
|
110
|
-
def
|
111
|
-
return
|
112
|
-
|
113
|
-
@concepts.setter
|
114
|
-
def concepts(self, value: List[Concept]):
|
115
|
-
self.proto.data.concepts.extend([concept.to_proto() for concept in value])
|
116
|
-
|
117
|
-
def __repr__(self) -> str:
|
118
|
-
return f"Region(box={self.box}, concepts={self.concepts})"
|
119
|
-
|
120
|
-
def to_proto(self) -> RegionProto:
|
121
|
-
return self.proto
|
122
|
-
|
123
|
-
@classmethod
|
124
|
-
def from_proto(cls, proto: RegionProto) -> "Region":
|
125
|
-
return cls(proto)
|
126
|
-
|
127
|
-
|
128
|
-
class Image(MessageData):
|
129
|
-
|
130
|
-
def __init__(self, proto_image: ImageProto = None, url: str = None, bytes: bytes = None):
|
131
|
-
if proto_image is None:
|
132
|
-
proto_image = ImageProto()
|
133
|
-
self.proto = proto_image
|
134
|
-
# use setters for init vals
|
135
|
-
if url:
|
136
|
-
self.url = url
|
137
|
-
if bytes:
|
138
|
-
self.bytes = bytes
|
139
|
-
|
140
|
-
@property
|
141
|
-
def url(self) -> str:
|
142
|
-
return self.proto.url
|
143
|
-
|
144
|
-
@url.setter
|
145
|
-
def url(self, value: str):
|
146
|
-
self.proto.url = value
|
147
|
-
|
148
|
-
@property
|
149
|
-
def bytes(self) -> bytes:
|
150
|
-
return self.proto.base64
|
151
|
-
|
152
|
-
@bytes.setter
|
153
|
-
def bytes(self, value: bytes):
|
154
|
-
self.proto.base64 = value
|
33
|
+
def status(self) -> status_pb2.Status:
|
34
|
+
return self._proto.status
|
155
35
|
|
156
|
-
def
|
157
|
-
|
158
|
-
|
159
|
-
attrs.append(f"url={self.url!r}")
|
160
|
-
if self.bytes:
|
161
|
-
attrs.append(f"bytes=<{len(self.bytes)} bytes>")
|
162
|
-
return f"Image({', '.join(attrs)})"
|
163
|
-
|
164
|
-
@classmethod
|
165
|
-
def from_url(cls, url: str) -> "Image":
|
166
|
-
proto_image = ImageProto(url=url)
|
167
|
-
return cls(proto_image)
|
168
|
-
|
169
|
-
@classmethod
|
170
|
-
def from_pil(cls, pil_image: PILImage.Image) -> "Image":
|
171
|
-
with io.BytesIO() as output:
|
172
|
-
pil_image.save(output, format="PNG")
|
173
|
-
image_bytes = output.getvalue()
|
174
|
-
proto_image = ImageProto(base64=image_bytes)
|
175
|
-
return cls(proto_image)
|
176
|
-
|
177
|
-
def to_pil(self) -> PILImage.Image:
|
178
|
-
if not self.proto.base64:
|
179
|
-
raise ValueError("Image has no bytes")
|
180
|
-
return PILImage.open(io.BytesIO(self.proto.base64))
|
181
|
-
|
182
|
-
def to_numpy(self) -> np.ndarray:
|
183
|
-
return np.asarray(self.to_pil())
|
184
|
-
|
185
|
-
def to_proto(self) -> ImageProto:
|
186
|
-
return self.proto
|
187
|
-
|
188
|
-
@classmethod
|
189
|
-
def from_proto(cls, proto: ImageProto) -> "Image":
|
190
|
-
return cls(proto)
|
191
|
-
|
192
|
-
def cast(self, python_type):
|
193
|
-
if python_type == Image:
|
194
|
-
return self
|
195
|
-
if python_type in (PILImage.Image, PILImage):
|
196
|
-
return self.to_pil()
|
197
|
-
if python_type == np.ndarray or get_origin(python_type) == np.ndarray:
|
198
|
-
return self.to_numpy()
|
199
|
-
raise TypeError(f'Incompatible type for Image: {python_type}')
|
200
|
-
|
201
|
-
|
202
|
-
class Audio(MessageData):
|
203
|
-
|
204
|
-
def __init__(self, proto_audio: AudioProto):
|
205
|
-
self.proto = proto_audio
|
36
|
+
def set_status(self, code: str, description: str = ""):
|
37
|
+
self._proto.status.code = code
|
38
|
+
self._proto.status.description = description
|
206
39
|
|
40
|
+
# Text
|
207
41
|
@property
|
208
|
-
def
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
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
|
215
56
|
@property
|
216
|
-
def
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
if
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
def to_proto(self) -> AudioProto:
|
237
|
-
return self.proto
|
238
|
-
|
239
|
-
@classmethod
|
240
|
-
def from_proto(cls, proto: AudioProto) -> "Audio":
|
241
|
-
return cls(proto)
|
242
|
-
|
243
|
-
|
244
|
-
class Frame(MessageData):
|
245
|
-
|
246
|
-
def __init__(self, proto_frame: FrameProto):
|
247
|
-
self.proto = proto_frame
|
248
|
-
|
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
|
249
76
|
@property
|
250
|
-
def
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
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
|
259
89
|
@property
|
260
|
-
def
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
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
|
267
151
|
@property
|
268
|
-
def
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
def __init__(self, proto_video: VideoProto):
|
286
|
-
self.proto = proto_video
|
287
|
-
|
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
|
288
169
|
@property
|
289
|
-
def
|
290
|
-
return self.proto.
|
170
|
+
def embeddings(self) -> List[List[float]]:
|
171
|
+
return [each.vector for each in self.proto.data.embeddings]
|
291
172
|
|
292
|
-
|
293
|
-
|
294
|
-
|
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)))
|
295
179
|
|
296
|
-
|
297
|
-
def bytes(self) -> bytes:
|
298
|
-
return self.proto.base64
|
299
|
-
|
300
|
-
@bytes.setter
|
301
|
-
def bytes(self, value: bytes):
|
302
|
-
self.proto.base64 = value
|
180
|
+
# ---------------- End get/setters ---------------- #
|
303
181
|
|
182
|
+
# Constructors
|
304
183
|
@classmethod
|
305
|
-
def
|
306
|
-
|
307
|
-
return
|
308
|
-
|
309
|
-
def __repr__(self) -> str:
|
310
|
-
attrs = []
|
311
|
-
if self.url:
|
312
|
-
attrs.append(f"url={self.url!r}")
|
313
|
-
if self.bytes:
|
314
|
-
attrs.append(f"bytes=<{len(self.bytes)} bytes>")
|
315
|
-
return f"Video({', '.join(attrs)})"
|
316
|
-
|
317
|
-
def to_proto(self) -> VideoProto:
|
318
|
-
return self.proto
|
184
|
+
def from_proto(cls, proto):
|
185
|
+
clss = cls(proto=proto)
|
186
|
+
return clss
|
319
187
|
|
320
188
|
@classmethod
|
321
|
-
def
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
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)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: clarifai
|
3
|
-
Version: 11.1.
|
3
|
+
Version: 11.1.6
|
4
4
|
Summary: Clarifai Python SDK
|
5
5
|
Home-page: https://github.com/Clarifai/clarifai-python
|
6
6
|
Author: Clarifai
|
@@ -20,21 +20,31 @@ Classifier: Operating System :: OS Independent
|
|
20
20
|
Requires-Python: >=3.8
|
21
21
|
Description-Content-Type: text/markdown
|
22
22
|
License-File: LICENSE
|
23
|
-
Requires-Dist: clarifai-grpc
|
24
|
-
Requires-Dist: clarifai-protocol
|
25
|
-
Requires-Dist: numpy
|
26
|
-
Requires-Dist: tqdm
|
27
|
-
Requires-Dist: rich
|
28
|
-
Requires-Dist: PyYAML
|
29
|
-
Requires-Dist: schema
|
30
|
-
Requires-Dist: Pillow
|
31
|
-
Requires-Dist: tabulate
|
32
|
-
Requires-Dist: fsspec
|
33
|
-
Requires-Dist: click
|
34
|
-
Requires-Dist: requests
|
35
|
-
Requires-Dist: aiohttp >=3.8.1
|
23
|
+
Requires-Dist: clarifai-grpc>=11.1.3
|
24
|
+
Requires-Dist: clarifai-protocol>=0.0.16
|
25
|
+
Requires-Dist: numpy>=1.22.0
|
26
|
+
Requires-Dist: tqdm>=4.65.0
|
27
|
+
Requires-Dist: rich>=13.4.2
|
28
|
+
Requires-Dist: PyYAML>=6.0.1
|
29
|
+
Requires-Dist: schema==0.7.5
|
30
|
+
Requires-Dist: Pillow>=9.5.0
|
31
|
+
Requires-Dist: tabulate>=0.9.0
|
32
|
+
Requires-Dist: fsspec>=2024.6.1
|
33
|
+
Requires-Dist: click>=8.1.7
|
34
|
+
Requires-Dist: requests>=2.32.3
|
36
35
|
Provides-Extra: all
|
37
|
-
Requires-Dist: pycocotools
|
36
|
+
Requires-Dist: pycocotools==2.0.6; extra == "all"
|
37
|
+
Dynamic: author
|
38
|
+
Dynamic: author-email
|
39
|
+
Dynamic: classifier
|
40
|
+
Dynamic: description
|
41
|
+
Dynamic: description-content-type
|
42
|
+
Dynamic: home-page
|
43
|
+
Dynamic: license
|
44
|
+
Dynamic: provides-extra
|
45
|
+
Dynamic: requires-dist
|
46
|
+
Dynamic: requires-python
|
47
|
+
Dynamic: summary
|
38
48
|
|
39
49
|
<h1 align="center">
|
40
50
|
<a href="https://www.clarifai.com/"><img alt="Clarifai" title="Clarifai" src="https://github.com/user-attachments/assets/623b883b-7fe5-4b95-bbfa-8691f5779af4"></a>
|