clarifai 11.2.3rc4__py3-none-any.whl → 11.2.3rc6__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 CHANGED
@@ -1 +1 @@
1
- __version__ = "11.2.3rc4"
1
+ __version__ = "11.2.3rc6"
@@ -1,6 +1,5 @@
1
1
  import inspect
2
2
  import itertools
3
- import json
4
3
  import logging
5
4
  import os
6
5
  import traceback
@@ -12,6 +11,7 @@ from clarifai_grpc.grpc.api.status import status_code_pb2, status_pb2
12
11
  from google.protobuf import json_format
13
12
 
14
13
  from clarifai.runners.utils import data_types
14
+ from clarifai.runners.utils.data_utils import DataConverter
15
15
  from clarifai.runners.utils.method_signatures import (build_function_signature, deserialize,
16
16
  get_stream_from_signature, serialize,
17
17
  signatures_to_json)
@@ -71,141 +71,6 @@ class ModelClass(ABC):
71
71
  output.data.text.raw = signatures_to_json(signatures)
72
72
  return resp
73
73
 
74
- def _convert_input_data_to_new_format(
75
- self, data: resources_pb2.Data,
76
- input_fields: List[resources_pb2.ModelTypeField]) -> resources_pb2.Data:
77
- """Convert input data to new format."""
78
- new_data = resources_pb2.Data()
79
- for field in input_fields:
80
- part_data = self._convert_field(data, field)
81
- part = new_data.parts.add()
82
- part.id = field.name
83
- part.data.CopyFrom(part_data)
84
- return new_data
85
-
86
- def _convert_field(self, old_data: resources_pb2.Data,
87
- field: resources_pb2.ModelTypeField) -> resources_pb2.Data:
88
- data_type = field.type
89
- if data_type == resources_pb2.ModelTypeField.DataType.STR:
90
- new_data = resources_pb2.Data()
91
- new_data.string_value = old_data.text.raw
92
- return new_data
93
- elif data_type == resources_pb2.ModelTypeField.DataType.IMAGE:
94
- new_data = resources_pb2.Data()
95
- new_data.image.CopyFrom(old_data.image)
96
- return new_data
97
- elif data_type == resources_pb2.ModelTypeField.DataType.VIDEO:
98
- new_data = resources_pb2.Data()
99
- new_data.video.CopyFrom(old_data.video)
100
- return new_data
101
- elif data_type == resources_pb2.ModelTypeField.DataType.BOOL:
102
- new_data = resources_pb2.Data()
103
- new_data.bool_value = old_data.bool_value
104
- return new_data
105
- elif data_type == resources_pb2.ModelTypeField.DataType.INT:
106
- new_data = resources_pb2.Data()
107
- new_data.int_value = old_data.int_value
108
- return new_data
109
- elif data_type == resources_pb2.ModelTypeField.DataType.FLOAT:
110
- new_data = resources_pb2.Data()
111
- new_data.float_value = old_data.float_value
112
- return new_data
113
- elif data_type == resources_pb2.ModelTypeField.DataType.BYTES:
114
- new_data = resources_pb2.Data()
115
- new_data.bytes_value = old_data.bytes_value
116
- return new_data
117
- elif data_type == resources_pb2.ModelTypeField.DataType.NDARRAY:
118
- new_data = resources_pb2.Data()
119
- new_data.ndarray.CopyFrom(old_data.ndarray)
120
- return new_data
121
- elif data_type == resources_pb2.ModelTypeField.DataType.JSON_DATA:
122
- new_data = resources_pb2.Data()
123
- struct_dict = old_data.text.raw
124
- new_data.string_value = json.dumps(struct_dict)
125
- return new_data
126
- elif data_type == resources_pb2.ModelTypeField.DataType.TEXT:
127
- new_data = resources_pb2.Data()
128
- new_data.text.CopyFrom(old_data.text)
129
- return new_data
130
- elif data_type == resources_pb2.ModelTypeField.DataType.CONCEPT:
131
- new_data = resources_pb2.Data()
132
- new_data.concepts.extend(old_data.concepts)
133
- return new_data
134
- elif data_type == resources_pb2.ModelTypeField.DataType.REGION:
135
- new_data = resources_pb2.Data()
136
- new_data.regions.extend(old_data.regions)
137
- return new_data
138
- elif data_type == resources_pb2.ModelTypeField.DataType.FRAME:
139
- new_data = resources_pb2.Data()
140
- new_data.frames.extend(old_data.frames)
141
- return new_data
142
- elif data_type == resources_pb2.ModelTypeField.DataType.AUDIO:
143
- new_data = resources_pb2.Data()
144
- new_data.audio.CopyFrom(old_data.audio)
145
- return new_data
146
- elif data_type == resources_pb2.ModelTypeField.DataType.LIST:
147
- new_data = resources_pb2.Data()
148
- if not field.type_args:
149
- raise ValueError("LIST type requires type_args")
150
- element_field = field.type_args[0]
151
- element_data = self._convert_field(old_data, element_field)
152
- part = new_data.parts.add()
153
- part.data.CopyFrom(element_data)
154
- return new_data
155
- elif data_type == resources_pb2.ModelTypeField.DataType.TUPLE:
156
- new_data = resources_pb2.Data()
157
- for element_field in field.type_args:
158
- element_data = self._convert_field(old_data, element_field)
159
- part = new_data.parts.add()
160
- part.data.CopyFrom(element_data)
161
- return new_data
162
- elif data_type == resources_pb2.ModelTypeField.DataType.NAMED_FIELDS:
163
- new_data = resources_pb2.Data()
164
- for named_field in field.type_args:
165
- part_data = self._convert_field(old_data, named_field)
166
- part = new_data.parts.add()
167
- part.id = named_field.name
168
- part.data.CopyFrom(part_data)
169
- return new_data
170
- else:
171
- raise ValueError(f"Unsupported data type: {data_type}")
172
-
173
- def is_old_format(self, data: resources_pb2.Data) -> bool:
174
- """Check if the Data proto is in the old format (without parts)."""
175
- if len(data.parts) > 0:
176
- return False # New format uses parts
177
-
178
- # Check if any singular field is set
179
- singular_fields = [
180
- 'image', 'video', 'metadata', 'geo', 'text', 'audio', 'ndarray', 'int_value',
181
- 'float_value', 'bytes_value', 'bool_value', 'string_value'
182
- ]
183
- for field in singular_fields:
184
- if data.HasField(field):
185
- return True
186
-
187
- # Check if any repeated field has elements
188
- repeated_fields = [
189
- 'concepts', 'colors', 'clusters', 'embeddings', 'regions', 'frames', 'tracks',
190
- 'time_segments', 'hits', 'heatmaps'
191
- ]
192
- for field in repeated_fields:
193
- if getattr(data, field):
194
- return True
195
-
196
- return False
197
-
198
- def _convert_output_data_to_old_format(self, data: resources_pb2.Data) -> resources_pb2.Data:
199
- """Convert output data to old format."""
200
- old_data = resources_pb2.Data()
201
- part_data = data.parts[0].data
202
- # Handle text.raw specially (common case for text outputs)
203
- old_data = part_data
204
- if old_data.string_value:
205
- old_data.text.raw = old_data.string_value
206
-
207
- return old_data
208
-
209
74
  def _batch_predict(self, method, inputs: List[Dict[str, Any]]) -> List[Any]:
210
75
  """Batch predict method for multiple inputs."""
211
76
  outputs = []
@@ -239,10 +104,10 @@ class ModelClass(ABC):
239
104
  python_param_types = method_info.python_param_types
240
105
  for input in request.inputs:
241
106
  # check if input is in old format
242
- is_convert = self.is_old_format(input.data)
107
+ is_convert = DataConverter.is_old_format(input.data)
243
108
  if is_convert:
244
109
  # convert to new format
245
- new_data = self._convert_input_data_to_new_format(input.data, signature.input_fields)
110
+ new_data = DataConverter.convert_input_data_to_new_format(input.data, signature.input_fields)
246
111
  input.data.CopyFrom(new_data)
247
112
  # convert inputs to python types
248
113
  inputs = self._convert_input_protos_to_python(request.inputs, inference_params,
@@ -285,10 +150,10 @@ class ModelClass(ABC):
285
150
  python_param_types = method_info.python_param_types
286
151
  for input in request.inputs:
287
152
  # check if input is in old format
288
- is_convert = self.is_old_format(input.data)
153
+ is_convert = DataConverter.is_old_format(input.data)
289
154
  if is_convert:
290
155
  # convert to new format
291
- new_data = self._convert_input_data_to_new_format(input.data, signature.input_fields)
156
+ new_data = DataConverter.convert_input_data_to_new_format(input.data, signature.input_fields)
292
157
  input.data.CopyFrom(new_data)
293
158
  inputs = self._convert_input_protos_to_python(request.inputs, inference_params,
294
159
  signature.input_fields, python_param_types)
@@ -346,10 +211,10 @@ class ModelClass(ABC):
346
211
 
347
212
  for input in request.inputs:
348
213
  # check if input is in old format
349
- is_convert = self.is_old_format(input.data)
214
+ is_convert = DataConverter.is_old_format(input.data)
350
215
  if is_convert:
351
216
  # convert to new format
352
- new_data = self._convert_input_data_to_new_format(input.data, signature.input_fields)
217
+ new_data = DataConverter.convert_input_data_to_new_format(input.data, signature.input_fields)
353
218
  input.data.CopyFrom(new_data)
354
219
  # convert all inputs for the first request, including the first stream value
355
220
  inputs = self._convert_input_protos_to_python(request.inputs, inference_params,
@@ -423,7 +288,7 @@ class ModelClass(ABC):
423
288
  serialize({'return': output}, variables_signature, proto.data, is_output=True)
424
289
  if convert_old_format:
425
290
  # convert to old format
426
- data = self._convert_output_data_to_old_format(proto.data)
291
+ data = DataConverter.convert_output_data_to_old_format(proto.data)
427
292
  proto.data.CopyFrom(data)
428
293
  proto.status.code = status_code_pb2.SUCCESS
429
294
  if hasattr(self, "_prompt_tokens") and self._prompt_tokens is not None:
@@ -6,6 +6,8 @@ from clarifai_grpc.grpc.api.resources_pb2 import ModelTypeRangeInfo
6
6
  from PIL import Image
7
7
 
8
8
  from clarifai.runners.utils.data_types import MessageData
9
+ from clarifai_grpc.grpc.api import resources_pb2
10
+ from typing import List
9
11
 
10
12
 
11
13
  def image_to_bytes(img: Image.Image, format="JPEG") -> bytes:
@@ -178,3 +180,158 @@ class InputField(MessageData):
178
180
  import json
179
181
  proto.default = json.dumps(default)
180
182
  return proto
183
+
184
+
185
+ class DataConverter:
186
+ """A class that can be used to convert data to and from a specific format."""
187
+
188
+ @classmethod
189
+ def convert_input_data_to_new_format(
190
+ cls, data: resources_pb2.Data,
191
+ input_fields: List[resources_pb2.ModelTypeField]) -> resources_pb2.Data:
192
+ """Convert input data to new format."""
193
+ new_data = resources_pb2.Data()
194
+ for field in input_fields:
195
+ part_data = cls._convert_field(data, field)
196
+ if cls._is_data_set(part_data):
197
+ # if the field is set, add it to the new data part
198
+ part = new_data.parts.add()
199
+ part.id = field.name
200
+ part.data.CopyFrom(part_data)
201
+ else:
202
+ if field.required:
203
+ raise ValueError(f"Field {field.name} is required but not set")
204
+ return new_data
205
+
206
+ @classmethod
207
+ def _convert_field(cls, old_data: resources_pb2.Data,
208
+ field: resources_pb2.ModelTypeField) -> resources_pb2.Data:
209
+ data_type = field.type
210
+ new_data = resources_pb2.Data()
211
+ if data_type == resources_pb2.ModelTypeField.DataType.STR:
212
+ if old_data.HasField('text'):
213
+ new_data.string_value = old_data.text.raw
214
+ return new_data
215
+ elif data_type == resources_pb2.ModelTypeField.DataType.IMAGE:
216
+ if old_data.HasField('image'):
217
+ new_data.image.CopyFrom(old_data.image)
218
+ return new_data
219
+ elif data_type == resources_pb2.ModelTypeField.DataType.VIDEO:
220
+ if old_data.HasField('video'):
221
+ new_data.video.CopyFrom(old_data.video)
222
+ return new_data
223
+ elif data_type == resources_pb2.ModelTypeField.DataType.BOOL:
224
+ if old_data.HasField('bool_value'):
225
+ new_data.bool_value = old_data.bool_value
226
+ return new_data
227
+ elif data_type == resources_pb2.ModelTypeField.DataType.INT:
228
+ if old_data.HasField('int_value'):
229
+ new_data.int_value = old_data.int_value
230
+ return new_data
231
+ elif data_type == resources_pb2.ModelTypeField.DataType.FLOAT:
232
+ if old_data.HasField('float_value'):
233
+ new_data.float_value = old_data.float_value
234
+ return new_data
235
+ elif data_type == resources_pb2.ModelTypeField.DataType.BYTES:
236
+ if old_data.HasField('bytes_value'):
237
+ new_data.bytes_value = old_data.bytes_value
238
+ return new_data
239
+ elif data_type == resources_pb2.ModelTypeField.DataType.NDARRAY:
240
+ if old_data.HasField('ndarray'):
241
+ new_data.ndarray.CopyFrom(old_data.ndarray)
242
+ return new_data
243
+ elif data_type == resources_pb2.ModelTypeField.DataType.TEXT:
244
+ if old_data.HasField('text'):
245
+ new_data.text.CopyFrom(old_data.text)
246
+ return new_data
247
+ elif data_type == resources_pb2.ModelTypeField.DataType.AUDIO:
248
+ if old_data.HasField('audio'):
249
+ new_data.audio.CopyFrom(old_data.audio)
250
+ return new_data
251
+ elif data_type == resources_pb2.ModelTypeField.DataType.CONCEPT:
252
+ if old_data.concepts:
253
+ new_data.concepts.extend(old_data.concepts)
254
+ return new_data
255
+ elif data_type == resources_pb2.ModelTypeField.DataType.REGION:
256
+ if old_data.regions:
257
+ new_data.regions.extend(old_data.regions)
258
+ return new_data
259
+ elif data_type == resources_pb2.ModelTypeField.DataType.FRAME:
260
+ if old_data.frames:
261
+ new_data.frames.extend(old_data.frames)
262
+ return new_data
263
+ elif data_type == resources_pb2.ModelTypeField.DataType.LIST:
264
+ if not field.type_args:
265
+ raise ValueError("LIST type requires type_args")
266
+ element_field = field.type_args[0]
267
+ if element_field in (resources_pb2.ModelTypeField.DataType.CONCEPT,
268
+ resources_pb2.ModelTypeField.DataType.REGION,
269
+ resources_pb2.ModelTypeField.DataType.FRAME):
270
+ # convert to new format
271
+ new_data = cls._convert_field(old_data, element_field)
272
+ return new_data
273
+ else:
274
+ return new_data
275
+ # raise ValueError(f"Unsupported data type: {data_type}")
276
+
277
+ @classmethod
278
+ def is_old_format(cls, data: resources_pb2.Data) -> bool:
279
+ """Check if the Data proto is in the old format (without parts)."""
280
+ if len(data.parts) > 0:
281
+ return False # New format uses parts
282
+
283
+ # Check if any singular field is set
284
+ singular_fields = [
285
+ 'image', 'video', 'metadata', 'geo', 'text', 'audio', 'ndarray', 'int_value',
286
+ 'float_value', 'bytes_value', 'bool_value', 'string_value'
287
+ ]
288
+ for field in singular_fields:
289
+ if data.HasField(field):
290
+ return True
291
+
292
+ # Check if any repeated field has elements
293
+ repeated_fields = [
294
+ 'concepts', 'colors', 'clusters', 'embeddings', 'regions', 'frames', 'tracks',
295
+ 'time_segments', 'hits', 'heatmaps'
296
+ ]
297
+ for field in repeated_fields:
298
+ if getattr(data, field):
299
+ return True
300
+
301
+ return False
302
+
303
+ @classmethod
304
+ def convert_output_data_to_old_format(cls, data: resources_pb2.Data) -> resources_pb2.Data:
305
+ """Convert output data to old format."""
306
+ old_data = resources_pb2.Data()
307
+ part_data = data.parts[0].data
308
+ # Handle text.raw specially (common case for text outputs)
309
+ old_data = part_data
310
+ if old_data.string_value:
311
+ old_data.text.raw = old_data.string_value
312
+
313
+ return old_data
314
+
315
+ @classmethod
316
+ def _is_data_set(cls, data_msg):
317
+ # Singular message fields
318
+ singular_fields = ["image", "video", "metadata", "geo", "text", "audio", "ndarray"]
319
+ for field in singular_fields:
320
+ if data_msg.HasField(field):
321
+ return True
322
+
323
+ # Repeated fields
324
+ repeated_fields = [
325
+ "concepts", "colors", "clusters", "embeddings", "regions", "frames", "tracks",
326
+ "time_segments", "hits", "heatmaps", "parts"
327
+ ]
328
+ for field in repeated_fields:
329
+ if getattr(data_msg, field): # checks if the list is not empty
330
+ return True
331
+
332
+ # Scalar fields (proto3 default: 0 for numbers, empty for strings/bytes, False for bool)
333
+ if (data_msg.int_value != 0 or data_msg.float_value != 0.0 or data_msg.bytes_value != b"" or
334
+ data_msg.bool_value is True or data_msg.string_value != ""):
335
+ return True
336
+
337
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: clarifai
3
- Version: 11.2.3rc4
3
+ Version: 11.2.3rc6
4
4
  Summary: Clarifai Python SDK
5
5
  Home-page: https://github.com/Clarifai/clarifai-python
6
6
  Author: Clarifai
@@ -1,4 +1,4 @@
1
- clarifai/__init__.py,sha256=M11rm1B4Hwgzbp8nZy-JnEJfer9JDpDqQzMqNG3d39I,26
1
+ clarifai/__init__.py,sha256=Dm7rGVjbmVqBK20TBYmaDHvsteQJbwgl47LQuzh9zek,26
2
2
  clarifai/cli.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  clarifai/errors.py,sha256=RwzTajwds51wLD0MVlMC5kcpBnzRpreDLlazPSBZxrg,2605
4
4
  clarifai/versions.py,sha256=jctnczzfGk_S3EnVqb2FjRKfSREkNmvNEwAAa_VoKiQ,222
@@ -139,7 +139,7 @@ clarifai/runners/dockerfile_template/Dockerfile.template,sha256=5cjv7U8PmWa3DB_5
139
139
  clarifai/runners/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
140
140
  clarifai/runners/models/base_typed_model.py,sha256=0QCWxch8CcyJSKvE1D4PILd2RSnQZHTmx4DXlQQ6dpo,7856
141
141
  clarifai/runners/models/model_builder.py,sha256=vJXYrxBwuayanMquAPwFOv9z7U5EQ2aIdppl8DfTGgQ,36900
142
- clarifai/runners/models/model_class.py,sha256=clowWGQ9Kh3Q25K0StnL4RUPsOW59T0q7HvcLgNAT5w,19801
142
+ clarifai/runners/models/model_class.py,sha256=JVgUAeVeQTAoE09k2uQZXPpMCEcmAyAwaQvKXrxNFpI,14458
143
143
  clarifai/runners/models/model_class_refract.py,sha256=HxuozxSW7ag5yWCPxjNwgLArQ6dORhyGXlnpPaZz2-c,3211
144
144
  clarifai/runners/models/model_run_locally.py,sha256=m5uLlXpWVGuQIJv-XBt-sHGx1gD8w6d77f9b85DOZqs,18170
145
145
  clarifai/runners/models/model_runner.py,sha256=T4Qn_x0vky7XdeS54bvipzEmKZMra1tQdAu_u01yyjc,6503
@@ -161,7 +161,7 @@ clarifai/runners/utils/const.py,sha256=bwj-Pcw558-pasdIFbNhnkn-9oiCdojYH1fNTTUG2
161
161
  clarifai/runners/utils/data_handler.py,sha256=b7k6MWYPXSgjrfw6wsDf82xFYa0D7UjYmjE4mw5HzHM,8499
162
162
  clarifai/runners/utils/data_handler_refract.py,sha256=3M-V4hkOoF-9Ix4hE6ocXWiTJPc9dewtu6FMtddd-jQ,6343
163
163
  clarifai/runners/utils/data_types.py,sha256=bFRKVl2s6Mmx0bQn_lKwbqxBET9wtIEf0Tk6PAIc6ko,12465
164
- clarifai/runners/utils/data_utils.py,sha256=RoPsi5szPvYLxU5DSO0ZmF-zA33QH7mJpQhZ7It4Y4Q,5289
164
+ clarifai/runners/utils/data_utils.py,sha256=OE0yyx9TF0tTIdva-sQDmTxoARLjOdgE6SFXQ-rnODM,11375
165
165
  clarifai/runners/utils/loader.py,sha256=SgNHMwRmCCymFQm8aDp73NmIUHhM-N60CBlTKbPzmVc,7470
166
166
  clarifai/runners/utils/logger.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
167
  clarifai/runners/utils/method_signatures.py,sha256=mr0d0hs-og2icwZn7DmiZqzOMnEqY-ZBW0mheselsZE,18134
@@ -230,9 +230,9 @@ clarifai/workflows/__pycache__/__init__.cpython-39.pyc,sha256=9nA--jULSW7OFrYOcs
230
230
  clarifai/workflows/__pycache__/export.cpython-310.pyc,sha256=phEGwi2gAojCUhRTqjZVeTDn7Gk6LCVBeSTjAj4m9iY,2418
231
231
  clarifai/workflows/__pycache__/utils.cpython-310.pyc,sha256=M9_KTM7GOOS5SPrWwAzqHDqyGvgKi3xuSGvyw6MNf-I,1925
232
232
  clarifai/workflows/__pycache__/validate.cpython-310.pyc,sha256=c18Jgp_-CAm8RD_tmUpDCPoqZeexaoWELG0yBzb9rjw,2149
233
- clarifai-11.2.3rc4.dist-info/LICENSE,sha256=mUqF_d12-qE2n41g7C5_sq-BMLOcj6CNN-jevr15YHU,555
234
- clarifai-11.2.3rc4.dist-info/METADATA,sha256=dcuOr9_2JIzWPcooBh_qUCMUGByy7TqQuBaPi4DINw0,22453
235
- clarifai-11.2.3rc4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
236
- clarifai-11.2.3rc4.dist-info/entry_points.txt,sha256=X9FZ4Z-i_r2Ud1RpZ9sNIFYuu_-9fogzCMCRUD9hyX0,51
237
- clarifai-11.2.3rc4.dist-info/top_level.txt,sha256=wUMdCQGjkxaynZ6nZ9FAnvBUCgp5RJUVFSy2j-KYo0s,9
238
- clarifai-11.2.3rc4.dist-info/RECORD,,
233
+ clarifai-11.2.3rc6.dist-info/LICENSE,sha256=mUqF_d12-qE2n41g7C5_sq-BMLOcj6CNN-jevr15YHU,555
234
+ clarifai-11.2.3rc6.dist-info/METADATA,sha256=992jW3H0kdqAE8KffQoOFM7DalzjHEnf7MLixhJubns,22453
235
+ clarifai-11.2.3rc6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
236
+ clarifai-11.2.3rc6.dist-info/entry_points.txt,sha256=X9FZ4Z-i_r2Ud1RpZ9sNIFYuu_-9fogzCMCRUD9hyX0,51
237
+ clarifai-11.2.3rc6.dist-info/top_level.txt,sha256=wUMdCQGjkxaynZ6nZ9FAnvBUCgp5RJUVFSy2j-KYo0s,9
238
+ clarifai-11.2.3rc6.dist-info/RECORD,,