clarifai 11.2.4rc2__py3-none-any.whl → 11.3.0__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.
Files changed (152) hide show
  1. clarifai/__init__.py +1 -1
  2. clarifai/client/deployment.py +3 -1
  3. clarifai/client/model.py +7 -3
  4. clarifai/runners/models/model_builder.py +0 -55
  5. clarifai/runners/models/model_class.py +4 -7
  6. clarifai/runners/utils/data_types.py +3 -3
  7. clarifai/runners/utils/data_utils.py +35 -36
  8. clarifai/runners/utils/method_signatures.py +0 -8
  9. clarifai/runners/utils/openai_convertor.py +126 -186
  10. clarifai/utils/protobuf.py +143 -0
  11. {clarifai-11.2.4rc2.dist-info → clarifai-11.3.0.dist-info}/METADATA +4 -3
  12. clarifai-11.3.0.dist-info/RECORD +107 -0
  13. {clarifai-11.2.4rc2.dist-info → clarifai-11.3.0.dist-info}/WHEEL +1 -1
  14. clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
  15. clarifai/__pycache__/__init__.cpython-39.pyc +0 -0
  16. clarifai/__pycache__/errors.cpython-310.pyc +0 -0
  17. clarifai/__pycache__/versions.cpython-310.pyc +0 -0
  18. clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  19. clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
  20. clarifai/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
  21. clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
  22. clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
  23. clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
  24. clarifai/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
  25. clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
  26. clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
  27. clarifai/client/__pycache__/__init__.cpython-39.pyc +0 -0
  28. clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
  29. clarifai/client/__pycache__/app.cpython-39.pyc +0 -0
  30. clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
  31. clarifai/client/__pycache__/compute_cluster.cpython-310.pyc +0 -0
  32. clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
  33. clarifai/client/__pycache__/deployment.cpython-310.pyc +0 -0
  34. clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
  35. clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
  36. clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
  37. clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
  38. clarifai/client/__pycache__/nodepool.cpython-310.pyc +0 -0
  39. clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
  40. clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
  41. clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
  42. clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
  43. clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
  44. clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
  45. clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
  46. clarifai/client/cli/__init__.py +0 -0
  47. clarifai/client/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  48. clarifai/client/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
  49. clarifai/client/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
  50. clarifai/client/cli/base_cli.py +0 -88
  51. clarifai/client/cli/model_cli.py +0 -29
  52. clarifai/constants/__pycache__/base.cpython-310.pyc +0 -0
  53. clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
  54. clarifai/constants/__pycache__/input.cpython-310.pyc +0 -0
  55. clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
  56. clarifai/constants/__pycache__/rag.cpython-310.pyc +0 -0
  57. clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
  58. clarifai/constants/__pycache__/workflow.cpython-310.pyc +0 -0
  59. clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
  60. clarifai/datasets/__pycache__/__init__.cpython-39.pyc +0 -0
  61. clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
  62. clarifai/datasets/export/__pycache__/__init__.cpython-39.pyc +0 -0
  63. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
  64. clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
  65. clarifai/datasets/upload/__pycache__/__init__.cpython-39.pyc +0 -0
  66. clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
  67. clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
  68. clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
  69. clarifai/datasets/upload/__pycache__/multimodal.cpython-310.pyc +0 -0
  70. clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
  71. clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
  72. clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-39.pyc +0 -0
  73. clarifai/models/__pycache__/__init__.cpython-39.pyc +0 -0
  74. clarifai/modules/__pycache__/__init__.cpython-39.pyc +0 -0
  75. clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
  76. clarifai/rag/__pycache__/__init__.cpython-39.pyc +0 -0
  77. clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
  78. clarifai/rag/__pycache__/rag.cpython-39.pyc +0 -0
  79. clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
  80. clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
  81. clarifai/runners/__pycache__/__init__.cpython-39.pyc +0 -0
  82. clarifai/runners/dockerfile_template/Dockerfile.cpu.template +0 -31
  83. clarifai/runners/dockerfile_template/Dockerfile.cuda.template +0 -42
  84. clarifai/runners/dockerfile_template/Dockerfile.nim +0 -71
  85. clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
  86. clarifai/runners/models/__pycache__/__init__.cpython-39.pyc +0 -0
  87. clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
  88. clarifai/runners/models/__pycache__/base_typed_model.cpython-39.pyc +0 -0
  89. clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
  90. clarifai/runners/models/__pycache__/model_run_locally.cpython-310-pytest-7.1.2.pyc +0 -0
  91. clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
  92. clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
  93. clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
  94. clarifai/runners/models/base_typed_model.py +0 -238
  95. clarifai/runners/models/model_class_refract.py +0 -80
  96. clarifai/runners/models/model_upload.py +0 -607
  97. clarifai/runners/models/temp.py +0 -25
  98. clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  99. clarifai/runners/utils/__pycache__/__init__.cpython-38.pyc +0 -0
  100. clarifai/runners/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  101. clarifai/runners/utils/__pycache__/buffered_stream.cpython-310.pyc +0 -0
  102. clarifai/runners/utils/__pycache__/buffered_stream.cpython-38.pyc +0 -0
  103. clarifai/runners/utils/__pycache__/buffered_stream.cpython-39.pyc +0 -0
  104. clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
  105. clarifai/runners/utils/__pycache__/constants.cpython-310.pyc +0 -0
  106. clarifai/runners/utils/__pycache__/constants.cpython-38.pyc +0 -0
  107. clarifai/runners/utils/__pycache__/constants.cpython-39.pyc +0 -0
  108. clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
  109. clarifai/runners/utils/__pycache__/data_handler.cpython-38.pyc +0 -0
  110. clarifai/runners/utils/__pycache__/data_handler.cpython-39.pyc +0 -0
  111. clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
  112. clarifai/runners/utils/__pycache__/data_utils.cpython-38.pyc +0 -0
  113. clarifai/runners/utils/__pycache__/data_utils.cpython-39.pyc +0 -0
  114. clarifai/runners/utils/__pycache__/grpc_server.cpython-310.pyc +0 -0
  115. clarifai/runners/utils/__pycache__/grpc_server.cpython-38.pyc +0 -0
  116. clarifai/runners/utils/__pycache__/grpc_server.cpython-39.pyc +0 -0
  117. clarifai/runners/utils/__pycache__/health.cpython-310.pyc +0 -0
  118. clarifai/runners/utils/__pycache__/health.cpython-38.pyc +0 -0
  119. clarifai/runners/utils/__pycache__/health.cpython-39.pyc +0 -0
  120. clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
  121. clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
  122. clarifai/runners/utils/__pycache__/logging.cpython-38.pyc +0 -0
  123. clarifai/runners/utils/__pycache__/logging.cpython-39.pyc +0 -0
  124. clarifai/runners/utils/__pycache__/stream_source.cpython-310.pyc +0 -0
  125. clarifai/runners/utils/__pycache__/stream_source.cpython-39.pyc +0 -0
  126. clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
  127. clarifai/runners/utils/__pycache__/url_fetcher.cpython-38.pyc +0 -0
  128. clarifai/runners/utils/__pycache__/url_fetcher.cpython-39.pyc +0 -0
  129. clarifai/runners/utils/data_handler.py +0 -292
  130. clarifai/runners/utils/data_handler_refract.py +0 -213
  131. clarifai/runners/utils/logger.py +0 -0
  132. clarifai/runners/utils/openai_format.py +0 -87
  133. clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
  134. clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
  135. clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  136. clarifai/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  137. clarifai/utils/__pycache__/cli.cpython-310.pyc +0 -0
  138. clarifai/utils/__pycache__/constants.cpython-310.pyc +0 -0
  139. clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
  140. clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
  141. clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
  142. clarifai/utils/evaluation/__pycache__/__init__.cpython-39.pyc +0 -0
  143. clarifai/utils/evaluation/__pycache__/main.cpython-39.pyc +0 -0
  144. clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
  145. clarifai/workflows/__pycache__/__init__.cpython-39.pyc +0 -0
  146. clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
  147. clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
  148. clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
  149. clarifai-11.2.4rc2.dist-info/RECORD +0 -241
  150. {clarifai-11.2.4rc2.dist-info → clarifai-11.3.0.dist-info}/entry_points.txt +0 -0
  151. {clarifai-11.2.4rc2.dist-info → clarifai-11.3.0.dist-info/licenses}/LICENSE +0 -0
  152. {clarifai-11.2.4rc2.dist-info → clarifai-11.3.0.dist-info}/top_level.txt +0 -0
@@ -1,292 +0,0 @@
1
- import io
2
- from typing import Any
3
-
4
- import numpy as np
5
- from clarifai_grpc.grpc.api import resources_pb2
6
- from clarifai_grpc.grpc.api.resources_pb2 import Audio as AudioProto
7
- from clarifai_grpc.grpc.api.resources_pb2 import Image as ImageProto
8
- from clarifai_grpc.grpc.api.resources_pb2 import Text as TextProto
9
- from clarifai_grpc.grpc.api.resources_pb2 import Video as VideoProto
10
- from clarifai_grpc.grpc.api.status import status_code_pb2, status_pb2
11
- from google.protobuf.json_format import MessageToDict, ParseDict
12
- from google.protobuf.struct_pb2 import Struct
13
- from PIL import Image as PILImage
14
-
15
-
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)
169
-
170
- @classmethod
171
- def from_proto(cls, proto: TextProto) -> "Text":
172
- return cls(proto.raw)
173
-
174
-
175
- class Image:
176
-
177
- def __init__(self, proto_image: ImageProto):
178
- self.proto = proto_image
179
-
180
- @property
181
- def url(self) -> str:
182
- return self.proto.url
183
-
184
- @url.setter
185
- def url(self, value: str):
186
- self.proto.url = value
187
-
188
- @property
189
- def bytes(self) -> bytes:
190
- return self.proto.base64
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
233
-
234
- @property
235
- def url(self) -> str:
236
- return self.proto.url
237
-
238
- @url.setter
239
- def url(self, value: str):
240
- self.proto.url = value
241
-
242
- @property
243
- def bytes(self) -> bytes:
244
- return self.proto.base64
245
-
246
- @bytes.setter
247
- def bytes(self, value: bytes):
248
- self.proto.base64 = value
249
-
250
- def __repr__(self) -> str:
251
- attrs = []
252
- if self.url:
253
- attrs.append(f"url={self.url!r}")
254
- if self.bytes:
255
- attrs.append(f"bytes=<{len(self.bytes)} bytes>")
256
- return f"Audio({', '.join(attrs)})"
257
-
258
- def to_proto(self) -> AudioProto:
259
- return self.proto
260
-
261
-
262
- class Video:
263
-
264
- def __init__(self, proto_video: VideoProto):
265
- self.proto = proto_video
266
-
267
- @property
268
- def url(self) -> str:
269
- return self.proto.url
270
-
271
- @url.setter
272
- def url(self, value: str):
273
- self.proto.url = value
274
-
275
- @property
276
- def bytes(self) -> bytes:
277
- return self.proto.base64
278
-
279
- @bytes.setter
280
- def bytes(self, value: bytes):
281
- self.proto.base64 = value
282
-
283
- def __repr__(self) -> str:
284
- attrs = []
285
- if self.url:
286
- attrs.append(f"url={self.url!r}")
287
- if self.bytes:
288
- attrs.append(f"bytes=<{len(self.bytes)} bytes>")
289
- return f"Video({', '.join(attrs)})"
290
-
291
- def to_proto(self) -> VideoProto:
292
- return self.proto
@@ -1,213 +0,0 @@
1
- import io
2
- from typing import Any, Callable, Dict, Type
3
-
4
- import numpy as np
5
- from clarifai_grpc.grpc.api import resources_pb2
6
- from clarifai_grpc.grpc.api.resources_pb2 import Audio as AudioProto
7
- from clarifai_grpc.grpc.api.resources_pb2 import Image as ImageProto
8
- from clarifai_grpc.grpc.api.resources_pb2 import NDArray
9
- from clarifai_grpc.grpc.api.resources_pb2 import Text as TextProto
10
- from clarifai_grpc.grpc.api.resources_pb2 import Video as VideoProto
11
- from google.protobuf.json_format import MessageToDict, ParseDict
12
- from google.protobuf.struct_pb2 import Struct
13
- from PIL import Image as PILImage
14
-
15
- # Type registry for conversion between Python types and protobuf
16
- _TYPE_HANDLERS: Dict[Type, Callable] = {
17
- # Python type: (to_proto, from_proto)
18
- TextProto: (
19
- lambda value: value.to_proto(),
20
- lambda proto: Text.from_proto(proto)
21
- ),
22
- ImageProto: (
23
- lambda value: value.to_proto(),
24
- lambda proto: Image(proto)
25
- ),
26
- AudioProto: (
27
- lambda value: value.to_proto(),
28
- lambda proto: Audio(proto)
29
- ),
30
- VideoProto: (
31
- lambda value: value.to_proto(),
32
- lambda proto: Video(proto)
33
- ),
34
- str: (
35
- lambda value: TextProto(raw=value),
36
- lambda proto: proto.raw
37
- ),
38
- bytes: (
39
- lambda value: resources_pb2.Data(base64=value),
40
- lambda proto: proto.base64
41
- ),
42
- int: (
43
- lambda value: resources_pb2.Data(int_value=value),
44
- lambda proto: proto.int_value
45
- ),
46
- float: (
47
- lambda value: resources_pb2.Data(float_value=value),
48
- lambda proto: proto.float_value
49
- ),
50
- bool: (
51
- lambda value: resources_pb2.Data(boolean=value),
52
- lambda proto: proto.boolean
53
- ),
54
- np.ndarray: (
55
- lambda value: NDArray(buffer=value.tobytes(), shape=value.shape, dtype=str(value.dtype)),
56
- lambda proto: np.frombuffer(proto.buffer, dtype=np.dtype(proto.dtype)).reshape(proto.shape)
57
- ),
58
- PILImage.Image: (
59
- lambda value: Image.from_pil(value).to_proto(),
60
- lambda proto: Image(proto).to_pil()
61
- ),
62
- dict: (
63
- lambda value: _dict_to_metadata(value),
64
- lambda proto: MessageToDict(proto.metadata)
65
- )
66
- }
67
-
68
-
69
- def _dict_to_metadata(metadata: dict) -> Struct:
70
- struct = Struct()
71
- ParseDict(metadata, struct)
72
- return struct
73
-
74
-
75
- def _value_to_proto(value: Any) -> resources_pb2.Data:
76
- """Convert a Python value to a protobuf Data message."""
77
- data = resources_pb2.Data()
78
- for py_type, (to_proto, _) in _TYPE_HANDLERS.items():
79
- if isinstance(value, py_type):
80
- handler = to_proto
81
- break
82
- else:
83
- if isinstance(value, (Text, Image, Audio, Video)):
84
- data_part = getattr(data, type(value).__name__.lower())
85
- data_part.CopyFrom(value.to_proto())
86
- return data
87
- raise TypeError(f"Unsupported type: {type(value)}")
88
-
89
- result = handler(value)
90
- if isinstance(result, resources_pb2.Data):
91
- data.CopyFrom(result)
92
- else:
93
- field_name = type(result).DESCRIPTOR.name.lower()
94
- getattr(data, field_name).CopyFrom(result)
95
- return data
96
-
97
-
98
- def _proto_to_value(proto: resources_pb2.Data) -> Any:
99
- """Convert a protobuf Data message to a Python value."""
100
- for field in proto.DESCRIPTOR.fields:
101
- if proto.HasField(field.name):
102
- _, from_proto = _TYPE_HANDLERS.get(field.type, (None, None))
103
- if from_proto:
104
- return from_proto(getattr(proto, field.name))
105
- if proto.parts:
106
- return [_proto_to_value(part.data) for part in proto.parts]
107
- return None
108
-
109
-
110
- def kwargs_to_proto(**kwargs) -> resources_pb2.Data:
111
- """Convert keyword arguments to a Data proto."""
112
- data_proto = resources_pb2.Data()
113
- for part_name, part_value in kwargs.items():
114
- part = data_proto.parts.add()
115
- part.id = part_name
116
-
117
- if isinstance(part_value, list):
118
- for item in part_value:
119
- item_proto = _value_to_proto(item)
120
- part_part = part.data.parts.add()
121
- part_part.data.CopyFrom(item_proto)
122
- else:
123
- part_proto = _value_to_proto(part_value)
124
- part.data.CopyFrom(part_proto)
125
- return data_proto
126
-
127
-
128
- def proto_to_kwargs(data: resources_pb2.Data) -> dict:
129
- """Convert a Data proto to keyword arguments."""
130
- kwargs = {}
131
- for part in data.parts:
132
- part_name = part.id
133
- if part.data.parts:
134
- kwargs[part_name] = [_proto_to_value(part.data) for _ in part.data.parts]
135
- else:
136
- kwargs[part_name] = _proto_to_value(part.data)
137
- return kwargs
138
-
139
-
140
- class Output:
141
-
142
- def __init__(self, **kwargs: Any):
143
- if not kwargs:
144
- raise ValueError("Output must have at least one key-value pair")
145
- self.parts = kwargs
146
-
147
- def to_proto(self) -> resources_pb2.Output:
148
- data_proto = kwargs_to_proto(**self.parts)
149
- return resources_pb2.Output(data=data_proto)
150
-
151
-
152
- class Text:
153
-
154
- def __init__(self, text: str):
155
- self.text = text
156
-
157
- def to_proto(self) -> TextProto:
158
- return TextProto(raw=self.text)
159
-
160
- @classmethod
161
- def from_proto(cls, proto: TextProto) -> "Text":
162
- return cls(proto.raw)
163
-
164
-
165
- class Image:
166
-
167
- def __init__(self, proto_image: ImageProto):
168
- self.proto = proto_image
169
-
170
- @classmethod
171
- def from_url(cls, url: str) -> "Image":
172
- return cls(ImageProto(url=url))
173
-
174
- @classmethod
175
- def from_pil(cls, pil_image: PILImage.Image) -> "Image":
176
- with io.BytesIO() as output:
177
- pil_image.save(output, format="PNG")
178
- return cls(ImageProto(base64=output.getvalue()))
179
-
180
- def to_pil(self) -> PILImage.Image:
181
- return PILImage.open(io.BytesIO(self.proto.base64))
182
-
183
- def to_proto(self) -> ImageProto:
184
- return self.proto
185
-
186
-
187
- class Audio:
188
-
189
- def __init__(self, proto_audio: AudioProto):
190
- self.proto = proto_audio
191
-
192
- def to_proto(self) -> AudioProto:
193
- return self.proto
194
-
195
-
196
- class Video:
197
-
198
- def __init__(self, proto_video: VideoProto):
199
- self.proto = proto_video
200
-
201
- def to_proto(self) -> VideoProto:
202
- return self.proto
203
-
204
-
205
- '''
206
- Type Handling Registry: Centralized conversion logic reduces duplication and enhances extensibility.
207
- Simplified Conversion Functions: _value_to_proto and _proto_to_value handle all type conversions using the registry.
208
- Streamlined Wrapper Methods: Common processing logic extracted into _process_request, reducing code duplication.
209
- Improved Batch Processing: Uses ThreadPoolExecutor.map for cleaner batch prediction.
210
- Error Handling: Clearer error messages and validation of required parameters.
211
- Removed Redundant Checks: Simplified Output class initialization.
212
-
213
- '''
File without changes
@@ -1,87 +0,0 @@
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
- }