clarifai 11.2.3rc9__py3-none-any.whl → 11.2.4rc2__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.3rc9"
1
+ __version__ = "11.2.4rc2"
@@ -60,28 +60,28 @@ class ModelClient:
60
60
  Dict: The method signatures.
61
61
  '''
62
62
  try:
63
- response = self.client.STUB.GetModelVersion(
63
+ response = self.STUB.GetModelVersion(
64
64
  service_pb2.GetModelVersionRequest(
65
65
  user_app_id=self.request_template.user_app_id,
66
- model_id= self.request_template.model_id,
67
- version_id=self.request_template.model_version.id,
66
+ model_id=self.request_template.model_id,
67
+ version_id=self.request_template.version_id,
68
68
  ))
69
+
69
70
  method_signatures = None
70
71
  if response.status.code == status_code_pb2.SUCCESS:
71
72
  method_signatures = response.model_version.method_signatures
72
73
  if response.status.code != status_code_pb2.SUCCESS:
73
74
  raise Exception(f"Model failed with response {response!r}")
74
- self._method_signatures= {}
75
+ self._method_signatures = {}
75
76
  for method_signature in method_signatures:
76
77
  method_name = method_signature.name
77
78
  # check for duplicate method names
78
79
  if method_name in self._method_signatures:
79
80
  raise ValueError(f"Duplicate method name {method_name}")
80
81
  self._method_signatures[method_name] = method_signature
81
- if not self._method_signatures: # if no method signatures, try to fetch from the model
82
+ if not self._method_signatures: # if no method signatures, try to fetch from the model
82
83
  self._fetch_signatures_backup()
83
- except Exception as e:
84
- logger.info(f"Failed to fetch method signatures from model: {e}")
84
+ except Exception:
85
85
  # try to fetch from the model
86
86
  self._fetch_signatures_backup()
87
87
  if not self._method_signatures:
@@ -259,7 +259,6 @@ class ModelClient:
259
259
  inputs, # TODO set up functions according to fetched signatures?
260
260
  method_name: str = 'predict',
261
261
  ) -> Any:
262
-
263
262
  input_signature = self._method_signatures[method_name].input_fields
264
263
  output_signature = self._method_signatures[method_name].output_fields
265
264
 
@@ -328,7 +327,7 @@ class ModelClient:
328
327
  response = self.STUB.PostModelOutputs(request)
329
328
  if status_is_retryable(
330
329
  response.status.code) and time.time() - start_time < 60 * 10: # 10 minutes
331
- logger.info(f"Model predict failed with response {response!r}")
330
+ logger.info("Model is still deploying, please wait...")
332
331
  time.sleep(next(backoff_iterator))
333
332
  continue
334
333
 
@@ -23,6 +23,7 @@ from clarifai.runners.utils.const import (
23
23
  DEFAULT_DOWNLOAD_CHECKPOINT_WHEN, DEFAULT_PYTHON_VERSION, DEFAULT_RUNTIME_DOWNLOAD_PATH,
24
24
  PYTHON_BASE_IMAGE, TORCH_BASE_IMAGE)
25
25
  from clarifai.runners.utils.loader import HuggingFaceLoader
26
+ from clarifai.runners.utils import data_utils
26
27
  from clarifai.runners.utils.method_signatures import signatures_to_yaml
27
28
  from clarifai.urls.helper import ClarifaiUrlHelper
28
29
  from clarifai.utils.logging import logger
@@ -336,6 +337,16 @@ class ModelBuilder:
336
337
  method_info = model_class._get_method_info()
337
338
  signatures = [method.signature for method in method_info.values()]
338
339
  return signatures
340
+
341
+ def get_methods_defaults(self):
342
+ """
343
+ Returns the inference parameters for the model class.
344
+ """
345
+ model_class = self.load_model_class(mocking=True)
346
+ method_info = model_class._get_method_info()
347
+ python_param_defaults = [method.python_param_types for method in method_info.values()]
348
+ return python_param_defaults
349
+
339
350
 
340
351
  @property
341
352
  def client(self):
@@ -622,14 +633,58 @@ class ModelBuilder:
622
633
  concepts = config.get('concepts')
623
634
  logger.info(f"Updated config.yaml with {len(concepts)} concepts.")
624
635
 
636
+ def filled_params_specs_with_inference_params(self, method_signatures: list[resources_pb2.MethodSignature], methods_defaults) -> list[resources_pb2.ModelTypeField]:
637
+ """
638
+ Fills the params_specs with the inference params.
639
+ """
640
+ inference_params = set()
641
+ for i, method_defaults in enumerate(methods_defaults):
642
+ for name, default in method_defaults.items():
643
+ if isinstance(default, data_utils.InputField):
644
+ if i==0:
645
+ inference_params.add(name)
646
+ else:
647
+ # if field.name not in inference_params then remove from inference_params
648
+ if name not in inference_params:
649
+ inference_params.remove(field.name)
650
+ output=[]
651
+ for signature in method_signatures:
652
+ for field in signature.input_fields:
653
+ if field.name in inference_params:
654
+ field.path = field.name
655
+ if field.type == resources_pb2.ModelTypeField.DataType.STR:
656
+ field.default_value= str(field.default)
657
+ field.field_type = resources_pb2.ModelTypeField.ModelTypeFieldType.STRING
658
+ elif field.type == resources_pb2.ModelTypeField.DataType.INT:
659
+ field.default_value= int(field.default)
660
+ field.field_type = resources_pb2.ModelTypeField.ModelTypeFieldType.NUMBER
661
+ elif field.type == resources_pb2.ModelTypeField.DataType.FLOAT:
662
+ field.default_value= float(field.default)
663
+ field.field_type = resources_pb2.ModelTypeField.ModelTypeFieldType.NUMBER
664
+ elif field.type == resources_pb2.ModelTypeField.DataType.BOOL:
665
+ field.default_value= bool(field.default)
666
+ field.field_type = resources_pb2.ModelTypeField.ModelTypeFieldType.BOOLEAN
667
+ else:
668
+ field.default_value= field.default
669
+ field.field_type = resources_pb2.ModelTypeField.ModelTypeFieldType.STRING
670
+ output.append(field)
671
+ return output
672
+
673
+
625
674
  def get_model_version_proto(self):
626
675
  signatures = self.get_method_signatures()
676
+ methods_defaults = self.get_methods_defaults()
677
+
627
678
  model_version_proto = resources_pb2.ModelVersion(
628
679
  pretrained_model_config=resources_pb2.PretrainedModelConfig(),
629
680
  inference_compute_info=self.inference_compute_info,
630
681
  method_signatures=signatures,
682
+ output_info= resources_pb2.OutputInfo(
683
+ params_specs=self.filled_params_specs_with_inference_params(signatures, methods_defaults),
684
+ )
631
685
  )
632
686
 
687
+
633
688
  model_type_id = self.config.get('model').get('model_type_id')
634
689
  if model_type_id in CONCEPTS_REQUIRED_MODEL_TYPE:
635
690
 
@@ -354,4 +354,9 @@ class _MethodInfo:
354
354
  for p in inspect.signature(method).parameters.values()
355
355
  if p.annotation != inspect.Parameter.empty
356
356
  }
357
+ self.python_param_defaults = {
358
+ p.name: p.default
359
+ for p in inspect.signature(method).parameters.values()
360
+ if p.default != inspect.Parameter.empty
361
+ }
357
362
  self.python_param_types.pop('self', None)
@@ -115,12 +115,7 @@ class InputField(MessageData):
115
115
  # proto.is_param = self.is_param
116
116
 
117
117
  if self.default is not None:
118
- if isinstance(self.default, str) or isinstance(self.default, bool) or isinstance(
119
- self.default, (int, float)):
120
- proto.default = str(self.default)
121
- else:
122
- import json
123
- proto.default = json.dumps(self.default)
118
+ proto = self.set_default(proto, self.default)
124
119
 
125
120
  return proto
126
121
 
@@ -169,17 +164,58 @@ class InputField(MessageData):
169
164
 
170
165
  @classmethod
171
166
  def set_default(cls, proto=None, default=None):
172
-
173
- if proto is None:
174
- proto = InputFieldProto()
175
- if default is not None:
176
- if isinstance(default, str) or isinstance(default, bool) or isinstance(
177
- default, (int, float)):
178
- proto.default = str(default)
179
- else:
180
- import json
167
+ try:
168
+ import json
169
+ if proto is None:
170
+ proto = InputFieldProto()
171
+ if default is not None:
181
172
  proto.default = json.dumps(default)
182
- return proto
173
+ return proto
174
+ except json.JSONDecodeError:
175
+ if default is not None:
176
+ proto.default = str(default)
177
+ return proto
178
+ except Exception as e:
179
+ raise ValueError(f"Error setting default value: {e}")
180
+
181
+ @classmethod
182
+ def get_default(cls, proto):
183
+ default_str = proto.default
184
+ default = None
185
+ import json
186
+ try:
187
+ # Attempt to parse as JSON first (for complex types)
188
+ return json.loads(default_str)
189
+ except json.JSONDecodeError:
190
+ pass
191
+ # Check for boolean values stored as "True" or "False"
192
+ if proto.type == resources_pb2.ModelTypeField.DataType.BOOL:
193
+ try:
194
+ default = bool(default_str)
195
+ except ValueError:
196
+ pass
197
+ # Try to parse as integer
198
+ elif proto.type == resources_pb2.ModelTypeField.DataType.INT:
199
+ try:
200
+ default = int(default_str)
201
+ except ValueError:
202
+ pass
203
+
204
+ # Try to parse as float
205
+ elif proto.type == resources_pb2.ModelTypeField.DataType.FLOAT:
206
+ try:
207
+ default = float(default_str)
208
+ except ValueError:
209
+ pass
210
+ elif proto.type == resources_pb2.ModelTypeField.DataType.STR:
211
+ default = default_str
212
+
213
+ if default is None:
214
+ # If all parsing fails, return the string value
215
+ default = default_str
216
+ return default
217
+
218
+
183
219
 
184
220
 
185
221
  class DataConverter:
@@ -211,54 +247,68 @@ class DataConverter:
211
247
  if data_type == resources_pb2.ModelTypeField.DataType.STR:
212
248
  if old_data.HasField('text'):
213
249
  new_data.string_value = old_data.text.raw
250
+ old_data.ClearField('text')
214
251
  return new_data
215
252
  elif data_type == resources_pb2.ModelTypeField.DataType.IMAGE:
216
253
  if old_data.HasField('image'):
217
254
  new_data.image.CopyFrom(old_data.image)
255
+ # Clear the old field to avoid duplication
256
+ old_data.ClearField('image')
218
257
  return new_data
219
258
  elif data_type == resources_pb2.ModelTypeField.DataType.VIDEO:
220
259
  if old_data.HasField('video'):
221
260
  new_data.video.CopyFrom(old_data.video)
261
+ old_data.ClearField('video')
222
262
  return new_data
223
263
  elif data_type == resources_pb2.ModelTypeField.DataType.BOOL:
224
264
  if old_data.bool_value is not False:
225
265
  new_data.bool_value = old_data.bool_value
266
+ old_data.bool_value = False
226
267
  return new_data
227
268
  elif data_type == resources_pb2.ModelTypeField.DataType.INT:
228
269
  if old_data.int_value != 0:
229
270
  new_data.int_value = old_data.int_value
271
+ old_data.int_value = 0
230
272
  return new_data
231
273
  elif data_type == resources_pb2.ModelTypeField.DataType.FLOAT:
232
274
  if old_data.float_value != 0.0:
233
275
  new_data.float_value = old_data.float_value
276
+ old_data.float_value = 0.0
234
277
  return new_data
235
278
  elif data_type == resources_pb2.ModelTypeField.DataType.BYTES:
236
279
  if old_data.bytes_value != b"":
237
280
  new_data.bytes_value = old_data.bytes_value
281
+ old_data.bytes_value = b""
238
282
  return new_data
239
283
  elif data_type == resources_pb2.ModelTypeField.DataType.NDARRAY:
240
284
  if old_data.HasField('ndarray'):
241
285
  new_data.ndarray.CopyFrom(old_data.ndarray)
286
+ old_data.ClearField('ndarray')
242
287
  return new_data
243
288
  elif data_type == resources_pb2.ModelTypeField.DataType.TEXT:
244
289
  if old_data.HasField('text'):
245
290
  new_data.text.CopyFrom(old_data.text)
291
+ old_data.ClearField('text')
246
292
  return new_data
247
293
  elif data_type == resources_pb2.ModelTypeField.DataType.AUDIO:
248
294
  if old_data.HasField('audio'):
249
295
  new_data.audio.CopyFrom(old_data.audio)
296
+ old_data.ClearField('audio')
250
297
  return new_data
251
298
  elif data_type == resources_pb2.ModelTypeField.DataType.CONCEPT:
252
299
  if old_data.concepts:
253
300
  new_data.concepts.extend(old_data.concepts)
301
+ old_data.ClearField('concepts')
254
302
  return new_data
255
303
  elif data_type == resources_pb2.ModelTypeField.DataType.REGION:
256
304
  if old_data.regions:
257
305
  new_data.regions.extend(old_data.regions)
306
+ old_data.ClearField('regions')
258
307
  return new_data
259
308
  elif data_type == resources_pb2.ModelTypeField.DataType.FRAME:
260
309
  if old_data.frames:
261
310
  new_data.frames.extend(old_data.frames)
311
+ old_data.ClearField('frames')
262
312
  return new_data
263
313
  elif data_type == resources_pb2.ModelTypeField.DataType.LIST:
264
314
  if not field.type_args:
@@ -1,5 +1,6 @@
1
1
  import collections.abc as abc
2
2
  import inspect
3
+ import logging
3
4
  import json
4
5
  from collections import namedtuple
5
6
  from typing import Dict, List, Tuple, get_args, get_origin
@@ -312,6 +313,13 @@ def deserialize(proto, signatures, inference_params={}, is_output=False):
312
313
  kwargs[sig.name] = serializer.deserialize(part.data)
313
314
  elif inference_params_value is not None:
314
315
  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
315
323
  else:
316
324
  if sig_i == 0:
317
325
  # possible inlined first value
@@ -0,0 +1,227 @@
1
+ import time
2
+ import uuid
3
+
4
+ def generate_id():
5
+ return f"chatcmpl-{uuid.uuid4().hex}"
6
+
7
+ def _format_non_streaming_response(
8
+ generated_text,
9
+ model="custom-model",
10
+ id=None,
11
+ created=None,
12
+ usage=None,
13
+ finish_reason="stop",
14
+ ):
15
+ if id is None:
16
+ id = generate_id()
17
+ if created is None:
18
+ created = int(time.time())
19
+
20
+ response = {
21
+ "id": id,
22
+ "object": "chat.completion",
23
+ "created": created,
24
+ "model": model,
25
+ "choices": [
26
+ {
27
+ "index": 0,
28
+ "message": {
29
+ "role": "assistant",
30
+ "content": generated_text,
31
+ },
32
+ "finish_reason": finish_reason,
33
+ "logprobs": None,
34
+ }
35
+ ],
36
+ }
37
+
38
+ if usage is not None:
39
+ response["usage"] = usage
40
+
41
+ return response
42
+
43
+ def _format_streaming_response(
44
+ generated_chunks,
45
+ model="custom-model",
46
+ id=None,
47
+ created=None,
48
+ finish_reason="stop",
49
+ ):
50
+ if id is None:
51
+ id = generate_id()
52
+ if created is None:
53
+ created = int(time.time())
54
+
55
+ for chunk in generated_chunks:
56
+ yield {
57
+ "id": id,
58
+ "object": "chat.completion.chunk",
59
+ "created": created,
60
+ "model": model,
61
+ "choices": [
62
+ {
63
+ "index": 0,
64
+ "delta": {
65
+ "content": chunk,
66
+ },
67
+ "finish_reason": None,
68
+ "logprobs": None,
69
+ }
70
+ ],
71
+ }
72
+
73
+ # Final chunk indicating completion
74
+ yield {
75
+ "id": id,
76
+ "object": "chat.completion.chunk",
77
+ "created": created,
78
+ "model": model,
79
+ "choices": [
80
+ {
81
+ "index": 0,
82
+ "delta": {},
83
+ "finish_reason": finish_reason,
84
+ "logprobs": None,
85
+ }
86
+ ],
87
+ }
88
+
89
+ def openai_response_format(
90
+ generated_text,
91
+ model="custom-model",
92
+ id=None,
93
+ created=None,
94
+ usage=None,
95
+ finish_reason="stop",
96
+ stream=True,
97
+ ):
98
+ if stream:
99
+ return _format_streaming_response(
100
+ generated_text, model, id, created, finish_reason
101
+ )
102
+ else:
103
+ return _format_non_streaming_response(
104
+ generated_text, model, id, created, usage, finish_reason
105
+ )
106
+ from typing import List, Dict, Union, Optional
107
+ import base64
108
+ from PIL import Image
109
+ import io
110
+
111
+ def openai_to_hf_chat_messages(
112
+ messages: List[Dict[str, str]],
113
+ tokenizer: Optional[object] = None
114
+ ) -> List[Dict[str, Union[str, Dict]]]:
115
+ """
116
+ Converts OpenAI-style chat messages into Hugging Face chat template format.
117
+
118
+ Args:
119
+ messages: List of OpenAI-style messages (e.g., [{"role": "user", "content": "Hello"}]).
120
+ model_family: Optional model family (e.g., "llava", "llama") for special handling.
121
+ tokenizer: Optional tokenizer to check for chat template support.
122
+
123
+ Returns:
124
+ List of messages in Hugging Face chat format.
125
+ """
126
+ hf_messages = []
127
+
128
+ for msg in messages:
129
+ role = msg["role"]
130
+ content = msg["content"]
131
+
132
+ # Handle multimodal content (e.g., images in OpenAI format)
133
+ if isinstance(content, list):
134
+ # OpenAI-style multimodal: [{"type": "text", "text": "..."}, {"type": "image_url", "image_url": "..."}]
135
+ new_content = []
136
+ for item in content:
137
+ if item["type"] == "text":
138
+ new_content.append(item["text"])
139
+ elif item["type"] == "image_url":
140
+ # Handle image (extract base64 or URL)
141
+ image_url = item["image_url"]["url"]
142
+ if image_url.startswith("data:image"):
143
+ # Base64-encoded image
144
+ image_data = image_url.split(",")[1]
145
+ image_bytes = base64.b64decode(image_data)
146
+ image = Image.open(io.BytesIO(image_bytes))
147
+ new_content.append({"image": image})
148
+ else:
149
+ # URL (model must handle downloads)
150
+ new_content.append({"url": image_url})
151
+ content = " ".join(new_content) if all(isinstance(c, str) for c in new_content) else new_content
152
+ elif not isinstance(content, str):
153
+ raise ValueError(f"Unsupported content type: {type(content)}")
154
+
155
+ # Add to HF messages
156
+ hf_messages.append({"role": role, "content": content})
157
+
158
+ # Apply model-specific adjustments
159
+ if tokenizer is not None and hasattr(tokenizer, "apply_chat_template"):
160
+ # Let Hugging Face tokenizer handle further formatting if needed
161
+ try:
162
+ return tokenizer.apply_chat_template(hf_messages, tokenize=False)
163
+ except:
164
+ pass # Fall back to manual formatting
165
+
166
+ return hf_messages
167
+
168
+ def convert_openai_to_hf_messages(openai_messages):
169
+ """
170
+ Converts OpenAI-style chat messages into a format compatible with Hugging Face's
171
+ `tokenizer.apply_chat_template()` function, supporting all modalities (text, images, etc.).
172
+
173
+ Args:
174
+ openai_messages (list): List of OpenAI-style messages, where each message is a dict with
175
+ 'role' (str) and 'content' (str or list of parts).
176
+
177
+ Returns:
178
+ list: Hugging Face-compatible messages. Each message is a dict with 'role' and 'content'.
179
+ Content is a string (text-only) or a list of parts (multimodal).
180
+ """
181
+ hf_messages = []
182
+ for msg in openai_messages:
183
+ role = msg['role']
184
+ content = msg['content']
185
+
186
+ if isinstance(content, list):
187
+ # Handle multimodal content (e.g., text + images)
188
+ converted_content = []
189
+ for part in content:
190
+ if part['type'] == 'text':
191
+ converted_content.append({'type': 'text', 'text': part['text']})
192
+ elif part['type'] == 'image_url':
193
+ # Handle image (extract base64 or URL)
194
+ image_url = part["image_url"]["url"]
195
+ if image_url.startswith("data:image"):
196
+ # Base64-encoded image
197
+ b64_img = image_url.split(",")[1]
198
+ converted_content.append({
199
+ 'type': 'image',
200
+ 'base64': b64_img
201
+ })
202
+ else:
203
+ # URL (model must handle downloads)
204
+ converted_content.append({
205
+ 'type': 'image',
206
+ 'url': image_url
207
+ })
208
+ elif part['type'] == 'video_url':
209
+ video_url = part["video_url"]["url"]
210
+ if video_url.startswith("data:video"):
211
+ ValueError("Base64 video data is not supported in HF format.")
212
+ else:
213
+ # URL (model must handle downloads)
214
+ converted_content.append({
215
+ 'type': 'video',
216
+ 'url': video_url
217
+ })
218
+ else:
219
+ raise ValueError(f"Unsupported content type: {part['type']} for conversion.")
220
+ hf_content = converted_content
221
+ else:
222
+ # Text-only content (string)
223
+ hf_content = content
224
+
225
+ hf_messages.append({'role': role, 'content': hf_content})
226
+
227
+ return hf_messages
@@ -0,0 +1,87 @@
1
+ import time
2
+ import uuid
3
+
4
+ def generate_id():
5
+ return f"chatcmpl-{uuid.uuid4().hex}"
6
+
7
+ def format_non_streaming_response(
8
+ generated_text,
9
+ model="custom-model",
10
+ id=None,
11
+ created=None,
12
+ usage=None,
13
+ finish_reason="stop",
14
+ ):
15
+ if id is None:
16
+ id = generate_id()
17
+ if created is None:
18
+ created = int(time.time())
19
+
20
+ response = {
21
+ "id": id,
22
+ "object": "chat.completion",
23
+ "created": created,
24
+ "model": model,
25
+ "choices": [
26
+ {
27
+ "index": 0,
28
+ "message": {
29
+ "role": "assistant",
30
+ "content": generated_text,
31
+ },
32
+ "finish_reason": finish_reason,
33
+ "logprobs": None,
34
+ }
35
+ ],
36
+ }
37
+
38
+ if usage is not None:
39
+ response["usage"] = usage
40
+
41
+ return response
42
+
43
+ def format_streaming_response(
44
+ generated_chunks,
45
+ model="custom-model",
46
+ id=None,
47
+ created=None,
48
+ finish_reason="stop",
49
+ ):
50
+ if id is None:
51
+ id = generate_id()
52
+ if created is None:
53
+ created = int(time.time())
54
+
55
+ for chunk in generated_chunks:
56
+ yield {
57
+ "id": id,
58
+ "object": "chat.completion.chunk",
59
+ "created": created,
60
+ "model": model,
61
+ "choices": [
62
+ {
63
+ "index": 0,
64
+ "delta": {
65
+ "content": chunk,
66
+ },
67
+ "finish_reason": None,
68
+ "logprobs": None,
69
+ }
70
+ ],
71
+ }
72
+
73
+ # Final chunk indicating completion
74
+ yield {
75
+ "id": id,
76
+ "object": "chat.completion.chunk",
77
+ "created": created,
78
+ "model": model,
79
+ "choices": [
80
+ {
81
+ "index": 0,
82
+ "delta": {},
83
+ "finish_reason": finish_reason,
84
+ "logprobs": None,
85
+ }
86
+ ],
87
+ }
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: clarifai
3
- Version: 11.2.3rc9
3
+ Version: 11.2.4rc2
4
4
  Summary: Clarifai Python SDK
5
5
  Home-page: https://github.com/Clarifai/clarifai-python
6
6
  Author: Clarifai
@@ -35,6 +35,17 @@ Requires-Dist: requests>=2.32.3
35
35
  Requires-Dist: aiohttp>=3.10.0
36
36
  Provides-Extra: all
37
37
  Requires-Dist: pycocotools==2.0.6; extra == "all"
38
+ Dynamic: author
39
+ Dynamic: author-email
40
+ Dynamic: classifier
41
+ Dynamic: description
42
+ Dynamic: description-content-type
43
+ Dynamic: home-page
44
+ Dynamic: license
45
+ Dynamic: provides-extra
46
+ Dynamic: requires-dist
47
+ Dynamic: requires-python
48
+ Dynamic: summary
38
49
 
39
50
  <h1 align="center">
40
51
  <a href="https://www.clarifai.com/"><img alt="Clarifai" title="Clarifai" src="https://github.com/user-attachments/assets/623b883b-7fe5-4b95-bbfa-8691f5779af4"></a>
@@ -1,4 +1,4 @@
1
- clarifai/__init__.py,sha256=CmYBra4AgDpzolVzilVcAea5NOufiy_WgIfu7o35JW4,26
1
+ clarifai/__init__.py,sha256=MifEmQdTShs6F9sPHBKRleuDIhSTAInWoN8okWqMJPs,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
@@ -31,7 +31,7 @@ clarifai/client/deployment.py,sha256=w7Y6pA1rYG4KRK1SwusRZc2sQRXlG8wezuVdzSWpCo0
31
31
  clarifai/client/input.py,sha256=obMAHMDU1OwfXZ8KraOnGFlWzlW-3F7Ob_2lcOQMlhY,46339
32
32
  clarifai/client/lister.py,sha256=03KGMvs5RVyYqxLsSrWhNc34I8kiF1Ph0NeyEwu7nMU,2082
33
33
  clarifai/client/model.py,sha256=HLTzCoGhZ5Ifm5x5nSFa4YULnLLlBpZF-29nfOcwFuY,76995
34
- clarifai/client/model_client.py,sha256=P3YC2s5LkwztuuUFPguPeAGMlexOok3BhMVyvXcxC0s,20068
34
+ clarifai/client/model_client.py,sha256=X0RndVfTdfa4PZaOtSick0VKC3AkQakT-qrkPqaFKuI,19971
35
35
  clarifai/client/module.py,sha256=FTkm8s9m-EaTKN7g9MnLhGJ9eETUfKG7aWZ3o1RshYs,4204
36
36
  clarifai/client/nodepool.py,sha256=la3vTFrO4LX8zm2eQ5jqf2L0-kQ63Dano8FibadoZbk,10152
37
37
  clarifai/client/search.py,sha256=GaPWN6JmTQGZaCHr6U1yv0zqR6wKFl7i9IVLg2ul1CI,14254
@@ -138,8 +138,8 @@ clarifai/runners/dockerfile_template/Dockerfile.nim,sha256=CSdUAehj3uOwminioLnT5
138
138
  clarifai/runners/dockerfile_template/Dockerfile.template,sha256=5cjv7U8PmWa3DB_5B1CqSYh_6GE0E0np52TIAa7EIDE,2312
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
- clarifai/runners/models/model_builder.py,sha256=vIUZII9n5wL0SGV4xR6wfsdRvrMv4pSHr6P-KdYpikI,36343
142
- clarifai/runners/models/model_class.py,sha256=2l7AZ2MrwR8tMIIV7KQSagZIzSwydyIFUOu0uFo-4gI,14742
141
+ clarifai/runners/models/model_builder.py,sha256=6ezRfKxXYI7jwWUiXdsy2L72Q3dvarqikvQuE5ZraVQ,38849
142
+ clarifai/runners/models/model_class.py,sha256=j3oyOCmh-XfFg3UhdquMZ-DxrNSlOGnFlQMNT3fNQSI,14920
143
143
  clarifai/runners/models/model_class_refract.py,sha256=HxuozxSW7ag5yWCPxjNwgLArQ6dORhyGXlnpPaZz2-c,3211
144
144
  clarifai/runners/models/model_run_locally.py,sha256=H7FKUBzZ_EPPj1b6P59qbOYr3mUJjJTlD5gavH5e80o,17746
145
145
  clarifai/runners/models/model_runner.py,sha256=T4Qn_x0vky7XdeS54bvipzEmKZMra1tQdAu_u01yyjc,6503
@@ -161,10 +161,12 @@ clarifai/runners/utils/const.py,sha256=9qnOC1Bt6SGLQ9XCQEQ6519XhW4gzcztsV1Rgej67
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=CtcYoW4EFE1EG6JkcP2rcRast9Eac8hFoYRHHCuwl2w,12432
164
- clarifai/runners/utils/data_utils.py,sha256=GmFRRI2xcULEUPGmTTDsEXaVHrs65Nplbxl-7toOeIc,11354
164
+ clarifai/runners/utils/data_utils.py,sha256=BuIxcQOudFEle8V6ZvycrYd-6X0i__EQbXxKKF1n7mA,12911
165
165
  clarifai/runners/utils/loader.py,sha256=Sl0m29RDtMPx2cIiSbbDFtKHQj2ktXQ5CnkvaHi-zDc,8804
166
166
  clarifai/runners/utils/logger.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
- clarifai/runners/utils/method_signatures.py,sha256=2SSStcBuBUbIgvFgAJFt4By0ZHos2c7bDWJOiUxQxZQ,18190
167
+ clarifai/runners/utils/method_signatures.py,sha256=HypEj1EN7pzRPzn-KUu1oOZcKlwfarvYTZXUZ-DEEYQ,18509
168
+ clarifai/runners/utils/openai_convertor.py,sha256=tFFNkjcdsNi73DfT_JOqdZZAu8fDYQwpbToWcr62OOw,7650
169
+ clarifai/runners/utils/openai_format.py,sha256=vOrpgqVWmQZGGFANZf0hmR_ksZXsr2-S9WUxvkG5lZs,1980
168
170
  clarifai/runners/utils/serializers.py,sha256=S4sRsOVvH191vAGTRTAAdwLlQwlK4T5QVRDGPptg9nQ,7191
169
171
  clarifai/runners/utils/url_fetcher.py,sha256=v_8JOWmkyFAzsBulsieKX7Nfjy1Yg7wGSZeqfEvw2cg,1640
170
172
  clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc,sha256=0GGbXIecXlOZmQKMCkSRhEBY_a1zvoimv-mHG4pJuNA,167
@@ -231,9 +233,9 @@ clarifai/workflows/__pycache__/__init__.cpython-39.pyc,sha256=9nA--jULSW7OFrYOcs
231
233
  clarifai/workflows/__pycache__/export.cpython-310.pyc,sha256=phEGwi2gAojCUhRTqjZVeTDn7Gk6LCVBeSTjAj4m9iY,2418
232
234
  clarifai/workflows/__pycache__/utils.cpython-310.pyc,sha256=M9_KTM7GOOS5SPrWwAzqHDqyGvgKi3xuSGvyw6MNf-I,1925
233
235
  clarifai/workflows/__pycache__/validate.cpython-310.pyc,sha256=c18Jgp_-CAm8RD_tmUpDCPoqZeexaoWELG0yBzb9rjw,2149
234
- clarifai-11.2.3rc9.dist-info/LICENSE,sha256=mUqF_d12-qE2n41g7C5_sq-BMLOcj6CNN-jevr15YHU,555
235
- clarifai-11.2.3rc9.dist-info/METADATA,sha256=M4q8Tg6mYzsGwJOWobZxe-Q889PVtkIkj_Lbe_dWmGo,22215
236
- clarifai-11.2.3rc9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
237
- clarifai-11.2.3rc9.dist-info/entry_points.txt,sha256=X9FZ4Z-i_r2Ud1RpZ9sNIFYuu_-9fogzCMCRUD9hyX0,51
238
- clarifai-11.2.3rc9.dist-info/top_level.txt,sha256=wUMdCQGjkxaynZ6nZ9FAnvBUCgp5RJUVFSy2j-KYo0s,9
239
- clarifai-11.2.3rc9.dist-info/RECORD,,
236
+ clarifai-11.2.4rc2.dist-info/LICENSE,sha256=mUqF_d12-qE2n41g7C5_sq-BMLOcj6CNN-jevr15YHU,555
237
+ clarifai-11.2.4rc2.dist-info/METADATA,sha256=2NQ4ajyyei0MMGHMBZimPeO7qxqoxMfMvlq1TaNzLRI,22453
238
+ clarifai-11.2.4rc2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
239
+ clarifai-11.2.4rc2.dist-info/entry_points.txt,sha256=X9FZ4Z-i_r2Ud1RpZ9sNIFYuu_-9fogzCMCRUD9hyX0,51
240
+ clarifai-11.2.4rc2.dist-info/top_level.txt,sha256=wUMdCQGjkxaynZ6nZ9FAnvBUCgp5RJUVFSy2j-KYo0s,9
241
+ clarifai-11.2.4rc2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.45.1)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5