tamar-model-client 0.1.2__py3-none-any.whl → 0.1.3__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.
- tamar_model_client/async_client.py +81 -86
- {tamar_model_client-0.1.2.dist-info → tamar_model_client-0.1.3.dist-info}/METADATA +1 -1
- {tamar_model_client-0.1.2.dist-info → tamar_model_client-0.1.3.dist-info}/RECORD +5 -5
- {tamar_model_client-0.1.2.dist-info → tamar_model_client-0.1.3.dist-info}/WHEEL +0 -0
- {tamar_model_client-0.1.2.dist-info → tamar_model_client-0.1.3.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
import asyncio
|
2
2
|
import atexit
|
3
|
+
import base64
|
3
4
|
import json
|
4
5
|
import logging
|
5
6
|
import os
|
@@ -27,6 +28,72 @@ if not logging.getLogger().hasHandlers():
|
|
27
28
|
logger = logging.getLogger(__name__)
|
28
29
|
|
29
30
|
|
31
|
+
def is_effective_value(value) -> bool:
|
32
|
+
"""
|
33
|
+
递归判断value是否是有意义的有效值
|
34
|
+
"""
|
35
|
+
if value is None or value is NOT_GIVEN:
|
36
|
+
return False
|
37
|
+
|
38
|
+
if isinstance(value, str):
|
39
|
+
return value.strip() != ""
|
40
|
+
|
41
|
+
if isinstance(value, bytes):
|
42
|
+
return len(value) > 0
|
43
|
+
|
44
|
+
if isinstance(value, dict):
|
45
|
+
for v in value.values():
|
46
|
+
if is_effective_value(v):
|
47
|
+
return True
|
48
|
+
return False
|
49
|
+
|
50
|
+
if isinstance(value, list):
|
51
|
+
for item in value:
|
52
|
+
if is_effective_value(item):
|
53
|
+
return True
|
54
|
+
return False
|
55
|
+
|
56
|
+
return True # 其他类型(int/float/bool)只要不是None就算有效
|
57
|
+
|
58
|
+
|
59
|
+
def serialize_value(value):
|
60
|
+
"""递归处理单个值,处理BaseModel, dict, list, bytes"""
|
61
|
+
if not is_effective_value(value):
|
62
|
+
return None
|
63
|
+
if isinstance(value, BaseModel):
|
64
|
+
return serialize_value(value.model_dump())
|
65
|
+
if hasattr(value, "dict") and callable(value.dict):
|
66
|
+
return serialize_value(value.dict())
|
67
|
+
if isinstance(value, dict):
|
68
|
+
return {k: serialize_value(v) for k, v in value.items()}
|
69
|
+
if isinstance(value, list) or (isinstance(value, Iterable) and not isinstance(value, (str, bytes))):
|
70
|
+
return [serialize_value(v) for v in value]
|
71
|
+
if isinstance(value, bytes):
|
72
|
+
return f"bytes:{base64.b64encode(value).decode('utf-8')}"
|
73
|
+
return value
|
74
|
+
|
75
|
+
|
76
|
+
from typing import Any
|
77
|
+
|
78
|
+
|
79
|
+
def remove_none_from_dict(data: Any) -> Any:
|
80
|
+
"""
|
81
|
+
遍历 dict/list,递归删除 value 为 None 的字段
|
82
|
+
"""
|
83
|
+
if isinstance(data, dict):
|
84
|
+
new_dict = {}
|
85
|
+
for key, value in data.items():
|
86
|
+
if value is None:
|
87
|
+
continue
|
88
|
+
cleaned_value = remove_none_from_dict(value)
|
89
|
+
new_dict[key] = cleaned_value
|
90
|
+
return new_dict
|
91
|
+
elif isinstance(data, list):
|
92
|
+
return [remove_none_from_dict(item) for item in data]
|
93
|
+
else:
|
94
|
+
return data
|
95
|
+
|
96
|
+
|
30
97
|
class AsyncTamarModelClient:
|
31
98
|
def __init__(
|
32
99
|
self,
|
@@ -177,51 +244,15 @@ class AsyncTamarModelClient:
|
|
177
244
|
if field in model_request_dict:
|
178
245
|
value = model_request_dict[field]
|
179
246
|
|
180
|
-
#
|
181
|
-
if
|
247
|
+
# 跳过无效的值
|
248
|
+
if not is_effective_value(value):
|
182
249
|
continue
|
183
250
|
|
184
|
-
#
|
185
|
-
|
186
|
-
|
187
|
-
#
|
188
|
-
|
189
|
-
grpc_request_kwargs[field] = value.dict()
|
190
|
-
# 如果是 list,需要处理里面元素也是自定义对象的情况
|
191
|
-
elif isinstance(value, Iterable) and not isinstance(value, (str, bytes, dict)):
|
192
|
-
new_list = []
|
193
|
-
for item in value:
|
194
|
-
if isinstance(item, BaseModel):
|
195
|
-
new_list.append(item.model_dump())
|
196
|
-
elif hasattr(item, "dict") and callable(item.dict):
|
197
|
-
new_list.append(item.dict())
|
198
|
-
elif isinstance(item, dict):
|
199
|
-
# Handle nested dictionaries
|
200
|
-
nested_dict = {}
|
201
|
-
for k, v in item.items():
|
202
|
-
if isinstance(v, BaseModel):
|
203
|
-
nested_dict[k] = v.model_dump()
|
204
|
-
elif hasattr(v, "dict") and callable(v.dict):
|
205
|
-
nested_dict[k] = v.dict()
|
206
|
-
else:
|
207
|
-
nested_dict[k] = v
|
208
|
-
new_list.append(nested_dict)
|
209
|
-
else:
|
210
|
-
new_list.append(item)
|
211
|
-
grpc_request_kwargs[field] = new_list
|
212
|
-
# 如果是 dict,同理处理内部元素
|
213
|
-
elif isinstance(value, dict):
|
214
|
-
new_dict = {}
|
215
|
-
for k, v in value.items():
|
216
|
-
if isinstance(v, BaseModel):
|
217
|
-
new_dict[k] = v.model_dump()
|
218
|
-
elif hasattr(v, "dict") and callable(v.dict):
|
219
|
-
new_dict[k] = v.dict()
|
220
|
-
else:
|
221
|
-
new_dict[k] = v
|
222
|
-
grpc_request_kwargs[field] = new_dict
|
223
|
-
else:
|
224
|
-
grpc_request_kwargs[field] = value
|
251
|
+
# 序列化grpc不支持的类型
|
252
|
+
grpc_request_kwargs[field] = serialize_value(value)
|
253
|
+
|
254
|
+
# 清理 serialize后的 grpc_request_kwargs
|
255
|
+
grpc_request_kwargs = remove_none_from_dict(grpc_request_kwargs)
|
225
256
|
|
226
257
|
request = model_service_pb2.ModelRequestItem(
|
227
258
|
provider=model_request.provider.value,
|
@@ -300,51 +331,15 @@ class AsyncTamarModelClient:
|
|
300
331
|
if field in model_request_dict:
|
301
332
|
value = model_request_dict[field]
|
302
333
|
|
303
|
-
#
|
304
|
-
if
|
334
|
+
# 跳过无效的值
|
335
|
+
if not is_effective_value(value):
|
305
336
|
continue
|
306
337
|
|
307
|
-
#
|
308
|
-
|
309
|
-
|
310
|
-
#
|
311
|
-
|
312
|
-
grpc_request_kwargs[field] = value.dict()
|
313
|
-
# 如果是 list,需要处理里面元素也是自定义对象的情况
|
314
|
-
elif isinstance(value, Iterable) and not isinstance(value, (str, bytes, dict)):
|
315
|
-
new_list = []
|
316
|
-
for item in value:
|
317
|
-
if isinstance(item, BaseModel):
|
318
|
-
new_list.append(item.model_dump())
|
319
|
-
elif hasattr(item, "dict") and callable(item.dict):
|
320
|
-
new_list.append(item.dict())
|
321
|
-
elif isinstance(item, dict):
|
322
|
-
# Handle nested dictionaries
|
323
|
-
nested_dict = {}
|
324
|
-
for k, v in item.items():
|
325
|
-
if isinstance(v, BaseModel):
|
326
|
-
nested_dict[k] = v.model_dump()
|
327
|
-
elif hasattr(v, "dict") and callable(v.dict):
|
328
|
-
nested_dict[k] = v.dict()
|
329
|
-
else:
|
330
|
-
nested_dict[k] = v
|
331
|
-
new_list.append(nested_dict)
|
332
|
-
else:
|
333
|
-
new_list.append(item)
|
334
|
-
grpc_request_kwargs[field] = new_list
|
335
|
-
# 如果是 dict,同理处理内部元素
|
336
|
-
elif isinstance(value, dict):
|
337
|
-
new_dict = {}
|
338
|
-
for k, v in value.items():
|
339
|
-
if isinstance(v, BaseModel):
|
340
|
-
new_dict[k] = v.model_dump()
|
341
|
-
elif hasattr(v, "dict") and callable(v.dict):
|
342
|
-
new_dict[k] = v.dict()
|
343
|
-
else:
|
344
|
-
new_dict[k] = v
|
345
|
-
grpc_request_kwargs[field] = new_dict
|
346
|
-
else:
|
347
|
-
grpc_request_kwargs[field] = value
|
338
|
+
# 序列化grpc不支持的类型
|
339
|
+
grpc_request_kwargs[field] = serialize_value(value)
|
340
|
+
|
341
|
+
# 清理 serialize后的 grpc_request_kwargs
|
342
|
+
grpc_request_kwargs = remove_none_from_dict(grpc_request_kwargs)
|
348
343
|
|
349
344
|
items.append(model_service_pb2.ModelRequestItem(
|
350
345
|
provider=model_request_item.provider.value,
|
@@ -14,7 +14,7 @@ model_manager_client/schemas/__init__.py,sha256=AxuI-TcvA4OMTj2FtK4wAItvz9LrK_29
|
|
14
14
|
model_manager_client/schemas/inputs.py,sha256=gXaifquIhSgUdbteRXsW9jxiJn0aOGDJ4UGCsrYdhPI,14323
|
15
15
|
model_manager_client/schemas/outputs.py,sha256=M_fcqUtXPJnfiLabHlyA8BorlC5pYkf5KLjXO1ysKIQ,1031
|
16
16
|
tamar_model_client/__init__.py,sha256=LMECAuDARWHV1XzH3msoDXcyurS2eihRQmBy26_PUE0,328
|
17
|
-
tamar_model_client/async_client.py,sha256=
|
17
|
+
tamar_model_client/async_client.py,sha256=R_3u3z55QB-FFsPuP2FHNFW35ZqRnMD756H4Pm4nj7Q,17875
|
18
18
|
tamar_model_client/auth.py,sha256=gbwW5Aakeb49PMbmYvrYlVx1mfyn1LEDJ4qQVs-9DA4,438
|
19
19
|
tamar_model_client/exceptions.py,sha256=jYU494OU_NeIa4X393V-Y73mTNm0JZ9yZApnlOM9CJQ,332
|
20
20
|
tamar_model_client/sync_client.py,sha256=o8b20fQUvtMq1gWax3_dfOpputYT4l9pRTz6cHdB0lg,4006
|
@@ -28,7 +28,7 @@ tamar_model_client/generated/model_service_pb2_grpc.py,sha256=KW1UEGUim_kmSi_fCI
|
|
28
28
|
tamar_model_client/schemas/__init__.py,sha256=AxuI-TcvA4OMTj2FtK4wAItvz9LrK_293pu3cmMLE7k,394
|
29
29
|
tamar_model_client/schemas/inputs.py,sha256=tXkBy19gm-ms8YE8GKn374uYY85hT7iT3BgivJGOJ4A,14319
|
30
30
|
tamar_model_client/schemas/outputs.py,sha256=M_fcqUtXPJnfiLabHlyA8BorlC5pYkf5KLjXO1ysKIQ,1031
|
31
|
-
tamar_model_client-0.1.
|
32
|
-
tamar_model_client-0.1.
|
33
|
-
tamar_model_client-0.1.
|
34
|
-
tamar_model_client-0.1.
|
31
|
+
tamar_model_client-0.1.3.dist-info/METADATA,sha256=uYyMheN2rY9gnsqBHinS-sKJ2TfQdTyNMhVWImJZfV4,16608
|
32
|
+
tamar_model_client-0.1.3.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
33
|
+
tamar_model_client-0.1.3.dist-info/top_level.txt,sha256=_LfDhPv_fvON0PoZgQuo4M7EjoWtxPRoQOBJziJmip8,19
|
34
|
+
tamar_model_client-0.1.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|