volcengine-python-sdk-aicc 0.0.41__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.
- bytedance/__init__.py +4 -0
- bytedance/jeddak_secure_channel/__init__.py +28 -0
- bytedance/jeddak_secure_channel/client.py +305 -0
- bytedance/jeddak_secure_channel/config.py +171 -0
- bytedance/jeddak_secure_channel/consts.py +5 -0
- bytedance/jeddak_secure_channel/crypto/__init__.py +14 -0
- bytedance/jeddak_secure_channel/crypto/aes.py +174 -0
- bytedance/jeddak_secure_channel/crypto/envelope.py +395 -0
- bytedance/jeddak_secure_channel/crypto/rsa.py +164 -0
- bytedance/jeddak_secure_channel/error.py +131 -0
- bytedance/jeddak_secure_channel/log/__init__.py +23 -0
- bytedance/jeddak_secure_channel/log/config.py +31 -0
- bytedance/jeddak_secure_channel/log/logger.py +88 -0
- bytedance/jeddak_secure_channel/logger_factory.py +134 -0
- bytedance/jeddak_secure_channel/ra.py +772 -0
- bytedance/jeddak_secure_channel/server.py +745 -0
- bytedance/jeddak_secure_channel/service/__init__.py +16 -0
- bytedance/jeddak_secure_channel/service/eps.py +133 -0
- bytedance/jeddak_secure_channel/service/eps_models.py +47 -0
- bytedance/jeddak_secure_channel/service/ras.py +88 -0
- bytedance/jeddak_secure_channel/service/tks.py +51 -0
- bytedance/jeddak_secure_channel/service/tks_models.py +334 -0
- bytedance/jeddak_secure_channel/utils.py +469 -0
- bytedance/jeddak_secure_model/model_automation_tool.py +181 -0
- bytedance/jeddak_secure_model/model_encryption.py +416 -0
- bytedance/jeddak_secure_model/model_hub_admin.py +116 -0
- bytedance/jeddak_secure_model/pcc_utils.py +279 -0
- bytedance/jeddak_secure_model/rds_utils.py +63 -0
- bytedance/tks/attester.py +41 -0
- bytedance/tks/client.py +629 -0
- bytedance/tks/consts.py +122 -0
- bytedance/tks/crypto/aes.py +47 -0
- bytedance/tks/crypto/ec.py +39 -0
- bytedance/tks/exceptions.py +22 -0
- bytedance/volcengine_aicc_sdk/__init__.py +14 -0
- bytedance/volcengine_aicc_sdk/aicc_client.py +277 -0
- bytedance/volcengine_aicc_sdk/aicc_inference.py +64 -0
- bytedance/volcengine_aicc_sdk/ark_inference_client.py +343 -0
- bytedance/volcengine_aicc_sdk/asr_inference_client.py +158 -0
- bytedance/volcengine_aicc_sdk/asr_websocket_client.py +705 -0
- bytedance/volcengine_aicc_sdk/auc_inference_client.py +305 -0
- bytedance/volcengine_aicc_sdk/common/__init__.py +0 -0
- bytedance/volcengine_aicc_sdk/common/aes.py +136 -0
- bytedance/volcengine_aicc_sdk/common/constant.py +4 -0
- bytedance/volcengine_aicc_sdk/common/error.py +21 -0
- bytedance/volcengine_aicc_sdk/common/log/__init__.py +24 -0
- bytedance/volcengine_aicc_sdk/common/log/config.py +31 -0
- bytedance/volcengine_aicc_sdk/common/log/logger.py +88 -0
- bytedance/volcengine_aicc_sdk/common/tos_utils.py +341 -0
- bytedance/volcengine_aicc_sdk/common/utils.py +45 -0
- bytedance/volcengine_aicc_sdk/cu_inference_client.py +292 -0
- bytedance/volcengine_aicc_sdk/deepseek_inference_client.py +501 -0
- bytedance/volcengine_aicc_sdk/secure_http_client.py +406 -0
- bytedance/volcengine_aicc_sdk/seedance_inference_client.py +500 -0
- bytedance/volcengine_aicc_sdk/seedream_inference_client.py +213 -0
- volcengine_python_sdk_aicc-0.0.41.dist-info/METADATA +79 -0
- volcengine_python_sdk_aicc-0.0.41.dist-info/RECORD +60 -0
- volcengine_python_sdk_aicc-0.0.41.dist-info/WHEEL +5 -0
- volcengine_python_sdk_aicc-0.0.41.dist-info/licenses/LICENSE +202 -0
- volcengine_python_sdk_aicc-0.0.41.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
__all__ = [
|
|
2
|
+
"RepeatTimer",
|
|
3
|
+
"WeakMethod",
|
|
4
|
+
"weak_repeat_timer",
|
|
5
|
+
"request_bytedance_gateway",
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
import hashlib
|
|
9
|
+
import hmac
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import urllib.parse
|
|
13
|
+
import weakref
|
|
14
|
+
from datetime import datetime, timezone
|
|
15
|
+
from threading import Timer
|
|
16
|
+
from typing import Dict
|
|
17
|
+
|
|
18
|
+
import requests
|
|
19
|
+
import volcenginesdkcore
|
|
20
|
+
import volcenginesdksts
|
|
21
|
+
from typing_extensions import (
|
|
22
|
+
Any,
|
|
23
|
+
Callable,
|
|
24
|
+
Concatenate,
|
|
25
|
+
Generic,
|
|
26
|
+
Iterable,
|
|
27
|
+
Mapping,
|
|
28
|
+
Optional,
|
|
29
|
+
ParamSpec,
|
|
30
|
+
Protocol,
|
|
31
|
+
TypeVar,
|
|
32
|
+
)
|
|
33
|
+
from volcenginesdkcore.rest import ApiException
|
|
34
|
+
|
|
35
|
+
from . import error
|
|
36
|
+
from .log import logger
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class RepeatTimer(Timer):
|
|
40
|
+
"""
|
|
41
|
+
定时重复执行函数.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def run(self):
|
|
45
|
+
while not self.finished.wait(self.interval):
|
|
46
|
+
self.function(*self.args, **self.kwargs)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
T = TypeVar("T")
|
|
50
|
+
P = ParamSpec("P")
|
|
51
|
+
R = TypeVar("R")
|
|
52
|
+
R_co = TypeVar("R_co", covariant=True)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class MethodProtocol(Protocol[T, P, R]):
|
|
56
|
+
__self__: T
|
|
57
|
+
|
|
58
|
+
__func__: Callable[Concatenate[T, P], R]
|
|
59
|
+
|
|
60
|
+
__call__: Callable[P, R]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class WeakMethod(Generic[T, P, R_co]):
|
|
64
|
+
"""
|
|
65
|
+
对方法 (bound method) 的弱引用.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
# instance: weakref.ReferenceType[T]
|
|
69
|
+
# func: weakref.ReferenceType[Callable[Concatenate[T, P], R_co]]
|
|
70
|
+
|
|
71
|
+
def __init__(self, method: Callable[P, R_co]):
|
|
72
|
+
# Type checkers do not differentiate methods from callables, so
|
|
73
|
+
# we have to ignore the casting error
|
|
74
|
+
_method: MethodProtocol[T, P, R_co] = method # pyright: ignore
|
|
75
|
+
|
|
76
|
+
self.instance = weakref.ref(_method.__self__)
|
|
77
|
+
self.func = weakref.ref(_method.__func__)
|
|
78
|
+
|
|
79
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Optional[R_co]:
|
|
80
|
+
instance = self.instance()
|
|
81
|
+
func = self.func()
|
|
82
|
+
|
|
83
|
+
if instance is None or func is None:
|
|
84
|
+
logger.info("Weak method called on freed object")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
return func(instance, *args, **kwargs)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def weak_repeat_timer(
|
|
91
|
+
interval: float,
|
|
92
|
+
method: Callable[P, None],
|
|
93
|
+
args: Optional[Iterable[Any]] = None,
|
|
94
|
+
kwargs: Optional[Mapping[str, Any]] = None,
|
|
95
|
+
) -> RepeatTimer:
|
|
96
|
+
"""
|
|
97
|
+
定时重复执行对象上的方法. 在对象被垃圾回收时自动结束线程.
|
|
98
|
+
"""
|
|
99
|
+
# Due to limitations of 'ParamSpec', we cannot annotate 'args' and 'kwargs' precisely
|
|
100
|
+
timer = RepeatTimer(interval, WeakMethod(method), args, kwargs)
|
|
101
|
+
weakref.finalize(method.__self__, timer.cancel) # pyright: ignore
|
|
102
|
+
|
|
103
|
+
return timer
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class TopRequester:
|
|
107
|
+
def __init__(
|
|
108
|
+
self,
|
|
109
|
+
ak,
|
|
110
|
+
sk,
|
|
111
|
+
token=None,
|
|
112
|
+
host="open.volcengineapi.com",
|
|
113
|
+
region="cn-beijing",
|
|
114
|
+
use_tls=True,
|
|
115
|
+
service="pcc",
|
|
116
|
+
version="2024-12-24",
|
|
117
|
+
debug=False,
|
|
118
|
+
):
|
|
119
|
+
volc_config = volcenginesdkcore.Configuration()
|
|
120
|
+
volc_config.host = host
|
|
121
|
+
volc_config.ak = ak
|
|
122
|
+
volc_config.sk = sk
|
|
123
|
+
volc_config.session_token = token
|
|
124
|
+
volc_config.region = region
|
|
125
|
+
volc_config.debug = debug
|
|
126
|
+
if use_tls:
|
|
127
|
+
volc_config.scheme = "https"
|
|
128
|
+
else:
|
|
129
|
+
volc_config.scheme = "http"
|
|
130
|
+
self._api_client = volcenginesdkcore.ApiClient(configuration=volc_config)
|
|
131
|
+
self._service = service
|
|
132
|
+
self._version = version
|
|
133
|
+
|
|
134
|
+
def _construct_resource_path(
|
|
135
|
+
self,
|
|
136
|
+
action: str,
|
|
137
|
+
version: str,
|
|
138
|
+
service: str,
|
|
139
|
+
method: str = "post",
|
|
140
|
+
content_type: str = "application_json",
|
|
141
|
+
) -> str:
|
|
142
|
+
return f"/{action}/{version}/{service}/{method.lower()}/{content_type}/"
|
|
143
|
+
|
|
144
|
+
def request(
|
|
145
|
+
self,
|
|
146
|
+
method,
|
|
147
|
+
query,
|
|
148
|
+
header,
|
|
149
|
+
param,
|
|
150
|
+
action,
|
|
151
|
+
body,
|
|
152
|
+
service=None,
|
|
153
|
+
version=None,
|
|
154
|
+
content_type="application/json",
|
|
155
|
+
):
|
|
156
|
+
resp = self._api_client.call_api(
|
|
157
|
+
self._construct_resource_path(
|
|
158
|
+
action=action,
|
|
159
|
+
version=self._version if not version else version,
|
|
160
|
+
service=self._service if not service else service,
|
|
161
|
+
method=method,
|
|
162
|
+
content_type=content_type.replace("/", "_"),
|
|
163
|
+
),
|
|
164
|
+
method,
|
|
165
|
+
body=body,
|
|
166
|
+
auth_settings=["volcengineSign"],
|
|
167
|
+
header_params={
|
|
168
|
+
"Accept": "application/json",
|
|
169
|
+
"Content-Type": content_type,
|
|
170
|
+
**header,
|
|
171
|
+
},
|
|
172
|
+
path_params=param,
|
|
173
|
+
query_params=query,
|
|
174
|
+
post_params=[],
|
|
175
|
+
files={},
|
|
176
|
+
response_type=bytes,
|
|
177
|
+
collection_formats={},
|
|
178
|
+
_return_http_data_only=False,
|
|
179
|
+
_preload_content=True,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
status, headers, data = resp[1], resp[2], resp[0]
|
|
183
|
+
logger.info(f"Top request response,status={status}, headers: {headers}")
|
|
184
|
+
|
|
185
|
+
return data
|
|
186
|
+
|
|
187
|
+
def request_with_assume_role(
|
|
188
|
+
self,
|
|
189
|
+
method,
|
|
190
|
+
query,
|
|
191
|
+
header,
|
|
192
|
+
param,
|
|
193
|
+
service,
|
|
194
|
+
action,
|
|
195
|
+
body,
|
|
196
|
+
version,
|
|
197
|
+
target_uid,
|
|
198
|
+
target_resource=None,
|
|
199
|
+
region="cn-beijing",
|
|
200
|
+
content_type="application/json",
|
|
201
|
+
use_tls=True,
|
|
202
|
+
host="open.volcengineapi.com",
|
|
203
|
+
):
|
|
204
|
+
data = {
|
|
205
|
+
"TargetAccount": target_uid,
|
|
206
|
+
"TargetResource": os.getenv("PCC_SERVICE", "pcc")
|
|
207
|
+
if not target_resource
|
|
208
|
+
else target_resource,
|
|
209
|
+
}
|
|
210
|
+
access_info = self.request("POST", [], {}, {}, "UpdateUserAccessInfo", data)
|
|
211
|
+
ak = access_info["Ak"]
|
|
212
|
+
sk = access_info["Sk"]
|
|
213
|
+
sts_token = access_info["StsToken"]
|
|
214
|
+
|
|
215
|
+
customer_requester = TopRequester(
|
|
216
|
+
ak=ak, sk=sk, token=sts_token, region=region, use_tls=use_tls, host=host
|
|
217
|
+
)
|
|
218
|
+
return customer_requester.request(
|
|
219
|
+
method, query, header, param, action, body, service, version, content_type
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _hmac_sha256(key: bytes, content: str):
|
|
224
|
+
return hmac.new(key, content.encode(), hashlib.sha256).digest()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def _hash_sha256(content: str):
|
|
228
|
+
return hashlib.sha256(content.encode()).hexdigest()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _format_query(params: Dict[str, str]) -> str:
|
|
232
|
+
return "&".join(
|
|
233
|
+
urllib.parse.quote(key, safe="-_.~")
|
|
234
|
+
+ "="
|
|
235
|
+
+ urllib.parse.quote(value, safe="-_.~")
|
|
236
|
+
for key, value in params.items()
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def top_request(
|
|
241
|
+
ra_url: str,
|
|
242
|
+
body: Any,
|
|
243
|
+
additional_headers: Optional[Dict[str, str]],
|
|
244
|
+
top_config: Dict[str, str],
|
|
245
|
+
) -> requests.Response:
|
|
246
|
+
top_ak = top_config["ak"]
|
|
247
|
+
top_sk = top_config["sk"]
|
|
248
|
+
top_service = top_config["service"]
|
|
249
|
+
top_region = top_config.get("region", "cn-beijing")
|
|
250
|
+
top_method = top_config.get("method", "POST").upper()
|
|
251
|
+
top_action = top_config.get("action", "GetAttestationBackend")
|
|
252
|
+
top_version = top_config.get("version", "2024-12-24")
|
|
253
|
+
use_tls: bool = top_config.get("use_tls", True) # type: ignore
|
|
254
|
+
sts_token = top_config.get("sts_token", None)
|
|
255
|
+
target_uid = top_config.get("target_uid", None)
|
|
256
|
+
target_resource = top_config.get("target_resource", "pcc")
|
|
257
|
+
|
|
258
|
+
if ra_url:
|
|
259
|
+
top_host = ra_url
|
|
260
|
+
else:
|
|
261
|
+
top_host = top_config.get("url", "open.volcengineapi.com")
|
|
262
|
+
|
|
263
|
+
requester = TopRequester(
|
|
264
|
+
ak=top_ak,
|
|
265
|
+
sk=top_sk,
|
|
266
|
+
token=sts_token,
|
|
267
|
+
region=top_region,
|
|
268
|
+
use_tls=use_tls,
|
|
269
|
+
host=top_host,
|
|
270
|
+
service=top_service,
|
|
271
|
+
version=top_version,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
resp = None
|
|
275
|
+
if not target_uid:
|
|
276
|
+
try:
|
|
277
|
+
resp = requester.request(
|
|
278
|
+
top_method, [], additional_headers, {}, top_action, body
|
|
279
|
+
)
|
|
280
|
+
except ApiException as e:
|
|
281
|
+
logger.error(
|
|
282
|
+
"status: {}, reason: {}, body: {}, headers: {}".format(
|
|
283
|
+
e.status, e.reason, e.body, e.headers
|
|
284
|
+
)
|
|
285
|
+
)
|
|
286
|
+
raise e
|
|
287
|
+
except Exception as e:
|
|
288
|
+
logger.error("request error: {}".format(e))
|
|
289
|
+
raise e
|
|
290
|
+
else:
|
|
291
|
+
try:
|
|
292
|
+
resp = requester.request_with_assume_role(
|
|
293
|
+
top_method,
|
|
294
|
+
[],
|
|
295
|
+
additional_headers,
|
|
296
|
+
{},
|
|
297
|
+
top_service,
|
|
298
|
+
top_action,
|
|
299
|
+
body,
|
|
300
|
+
top_version,
|
|
301
|
+
target_uid,
|
|
302
|
+
target_resource,
|
|
303
|
+
top_region,
|
|
304
|
+
use_tls=use_tls,
|
|
305
|
+
host=top_host
|
|
306
|
+
)
|
|
307
|
+
except ApiException as e:
|
|
308
|
+
logger.error(
|
|
309
|
+
"status: {}, reason: {}, body: {}, headers: {}".format(
|
|
310
|
+
e.status, e.reason, e.body, e.headers
|
|
311
|
+
)
|
|
312
|
+
)
|
|
313
|
+
raise e
|
|
314
|
+
except Exception as e:
|
|
315
|
+
logger.error("request error: {}".format(e))
|
|
316
|
+
raise e
|
|
317
|
+
|
|
318
|
+
return resp
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def get_top_access_key(top_config: Dict[str, str]) -> tuple:
|
|
322
|
+
try:
|
|
323
|
+
configuration = volcenginesdkcore.Configuration()
|
|
324
|
+
configuration.ak = top_config.get("ak")
|
|
325
|
+
configuration.sk = top_config.get("sk")
|
|
326
|
+
configuration.region = top_config.get("region", "cn-beijing")
|
|
327
|
+
|
|
328
|
+
duration_seconds = int(top_config.get("duration_seconds", "3600"))
|
|
329
|
+
role_session_name = top_config.get("role_session_name", "temp_")
|
|
330
|
+
role_trn = top_config.get("aicc_saas_trn")
|
|
331
|
+
|
|
332
|
+
volcenginesdkcore.Configuration.set_default(configuration)
|
|
333
|
+
|
|
334
|
+
api_instance = volcenginesdksts.STSApi()
|
|
335
|
+
assume_role_request = volcenginesdksts.AssumeRoleRequest(
|
|
336
|
+
duration_seconds=duration_seconds,
|
|
337
|
+
role_session_name=role_session_name,
|
|
338
|
+
role_trn=role_trn,
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
ret = api_instance.assume_role(assume_role_request)
|
|
342
|
+
if ret and ret.credentials:
|
|
343
|
+
ak = ret.credentials.access_key_id
|
|
344
|
+
sk = ret.credentials.secret_access_key
|
|
345
|
+
session_token = ret.credentials.session_token
|
|
346
|
+
|
|
347
|
+
return ak, sk, session_token
|
|
348
|
+
else:
|
|
349
|
+
return None, None, None
|
|
350
|
+
|
|
351
|
+
except Exception as e:
|
|
352
|
+
logger.error("get_top_access_key: {}".format(e))
|
|
353
|
+
raise e
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
# The first parameter was url, and is now unused
|
|
357
|
+
def request_bytedance_gateway(
|
|
358
|
+
url: str,
|
|
359
|
+
body: Any,
|
|
360
|
+
additional_headers: Optional[Dict[str, str]],
|
|
361
|
+
top_config: Dict[str, str],
|
|
362
|
+
) -> requests.Response:
|
|
363
|
+
top_ak = top_config["ak"]
|
|
364
|
+
top_sk = top_config["sk"]
|
|
365
|
+
|
|
366
|
+
if not additional_headers:
|
|
367
|
+
additional_headers = dict()
|
|
368
|
+
|
|
369
|
+
if top_config.get("aicc_saas_trn"):
|
|
370
|
+
ak, sk, session_token = get_top_access_key(top_config)
|
|
371
|
+
if ak and sk and session_token:
|
|
372
|
+
top_ak = ak
|
|
373
|
+
top_sk = sk
|
|
374
|
+
additional_headers["X-Security-Token"] = session_token
|
|
375
|
+
additional_headers["sts_token"] = session_token
|
|
376
|
+
if top_config.get("target_uid"):
|
|
377
|
+
additional_headers["UID"] = top_config.get("target_uid")
|
|
378
|
+
|
|
379
|
+
top_service = top_config["service"]
|
|
380
|
+
top_region = top_config.get("region", "cn-beijing")
|
|
381
|
+
top_method = top_config.get("method", "POST").upper()
|
|
382
|
+
top_action = top_config.get("action", "GetAttestationBackend")
|
|
383
|
+
top_version = top_config.get("version", "2024-12-24")
|
|
384
|
+
url_rewrite = top_config.get("url_rewrite", "")
|
|
385
|
+
http_scheme = top_config.get("http_scheme", "https")
|
|
386
|
+
|
|
387
|
+
top_url = top_config.get("url", "") if top_config.get("url", "") else url
|
|
388
|
+
if not top_url:
|
|
389
|
+
top_url = url_rewrite
|
|
390
|
+
if not top_url:
|
|
391
|
+
logger.error("ra request error url=None")
|
|
392
|
+
raise error.ParamError("top_url", "top_url is None")
|
|
393
|
+
|
|
394
|
+
if top_url.startswith("http"):
|
|
395
|
+
url_parsed = urllib.parse.urlparse(top_url)
|
|
396
|
+
top_host = url_parsed.hostname
|
|
397
|
+
else:
|
|
398
|
+
top_host = top_url
|
|
399
|
+
|
|
400
|
+
params = {"Action": top_action, "Version": top_version}
|
|
401
|
+
query_str = _format_query(params)
|
|
402
|
+
|
|
403
|
+
date_now = datetime.now(timezone.utc)
|
|
404
|
+
body_str = json.dumps(body, separators=(",", ":"))
|
|
405
|
+
|
|
406
|
+
x_date = date_now.strftime("%Y%m%dT%H%M%SZ")
|
|
407
|
+
short_x_date = x_date[:8]
|
|
408
|
+
x_content_sha256 = _hash_sha256(body_str)
|
|
409
|
+
|
|
410
|
+
headers = {
|
|
411
|
+
"Content-Type": "application/json",
|
|
412
|
+
"Host": top_host,
|
|
413
|
+
"X-Content-Sha256": x_content_sha256,
|
|
414
|
+
"X-Date": x_date,
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
signed_headers = ";".join(key.lower() for key in headers.keys())
|
|
418
|
+
|
|
419
|
+
canonical_request = "\n".join(
|
|
420
|
+
[
|
|
421
|
+
top_method,
|
|
422
|
+
"/",
|
|
423
|
+
query_str,
|
|
424
|
+
*[key.lower() + ":" + value for key, value in headers.items()],
|
|
425
|
+
"",
|
|
426
|
+
signed_headers,
|
|
427
|
+
x_content_sha256,
|
|
428
|
+
]
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
canonical_request_hash = _hash_sha256(canonical_request)
|
|
432
|
+
credential_scope = "/".join([short_x_date, top_region, top_service, "request"])
|
|
433
|
+
string_to_sign = "\n".join(
|
|
434
|
+
["HMAC-SHA256", x_date, credential_scope, canonical_request_hash]
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
logger.debug(
|
|
438
|
+
f"ra request={canonical_request}, hash={canonical_request_hash}, sign={string_to_sign}"
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
k_date = _hmac_sha256(top_sk.encode(), short_x_date)
|
|
442
|
+
k_region = _hmac_sha256(k_date, top_region)
|
|
443
|
+
k_service = _hmac_sha256(k_region, top_service)
|
|
444
|
+
k_signing = _hmac_sha256(k_service, "request")
|
|
445
|
+
signature = _hmac_sha256(k_signing, string_to_sign).hex()
|
|
446
|
+
|
|
447
|
+
headers["Authorization"] = (
|
|
448
|
+
f"HMAC-SHA256 Credential={top_ak}/{credential_scope}, SignedHeaders={signed_headers}, Signature={signature}"
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
if url_rewrite:
|
|
452
|
+
url_parsed = urllib.parse.urlparse(url_rewrite)
|
|
453
|
+
headers["Host"] = url_parsed.hostname or ""
|
|
454
|
+
url_final = url_rewrite + "?" + query_str
|
|
455
|
+
else:
|
|
456
|
+
if top_url.startswith("http"):
|
|
457
|
+
url_final = top_url + "?" + query_str
|
|
458
|
+
else:
|
|
459
|
+
url_final = f"{http_scheme}://{top_url}/?{query_str}"
|
|
460
|
+
|
|
461
|
+
if additional_headers:
|
|
462
|
+
headers = {**headers, **additional_headers}
|
|
463
|
+
|
|
464
|
+
r = requests.request(
|
|
465
|
+
method=top_method, url=url_final, headers=headers, data=body_str, timeout=30
|
|
466
|
+
)
|
|
467
|
+
logger.debug(f"call ra: url={url_final}, header={headers}, body={body_str}, res={json.loads(r.text).get('Result')}")
|
|
468
|
+
logger.info(f"ra response headers: X-Tt-Logid={r.headers.get('X-Tt-Logid')}")
|
|
469
|
+
return r
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
from bytedance.jeddak_secure_model.model_encryption import \
|
|
2
|
+
EncryptionConfig, JeddakModelEncrypter
|
|
3
|
+
from bytedance.jeddak_secure_model import pcc_utils
|
|
4
|
+
import bytedance
|
|
5
|
+
from bytedance.jeddak_secure_model.pcc_utils import \
|
|
6
|
+
set_tks_policy, \
|
|
7
|
+
publish_inference_model, \
|
|
8
|
+
deploy_inference_model, \
|
|
9
|
+
list_inference_model, \
|
|
10
|
+
test_inference_model, \
|
|
11
|
+
get_engine_conf
|
|
12
|
+
import argparse
|
|
13
|
+
import time
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def parser():
|
|
18
|
+
parser = argparse.ArgumentParser(description="JeddakPCC Model Automation Tool")
|
|
19
|
+
parser.add_argument("--model_path", type=str, default="", required=True, help="本地模型的文件夹路径")
|
|
20
|
+
parser.add_argument("--bucket_name", type=str, default="", help="创建TOS的存储桶")
|
|
21
|
+
parser.add_argument("--AK", type=str, default="", help="your volc access key")
|
|
22
|
+
parser.add_argument("--SK", type=str, default="", help="your volc secret key")
|
|
23
|
+
parser.add_argument("--region", type=str, default="cn-beijing", help="存储桶的区域")
|
|
24
|
+
parser.add_argument("--endpoint", type=str, default="tos-cn-beijing.volces.com", help="tos endpoint")
|
|
25
|
+
parser.add_argument("--ring_id", type=str, default="", help="密钥环ID")
|
|
26
|
+
parser.add_argument("--ring_name", type=str, default="", help="密钥环名称")
|
|
27
|
+
parser.add_argument("--ring_desc", type=str, default="", help="密钥环描述")
|
|
28
|
+
parser.add_argument("--key_name", type=str, default="", help="密钥名称")
|
|
29
|
+
parser.add_argument("--key_desc", type=str, default="", help="密钥描述")
|
|
30
|
+
parser.add_argument("--app_id", type=str, default="", help="火山页面查看自己账号的app_id")
|
|
31
|
+
parser.add_argument("--service", type=str, default="pcc", help="pcc for online, pcc_test for ppe")
|
|
32
|
+
parser.add_argument("--encrypt_flag", '-e', action='store_true', help="是否加密模型,输入此参数表示加密,不输入此参数表示不加密")
|
|
33
|
+
parser.add_argument("--tks_addr", type=str, default="pcc.volcengineapi.com", help="tks top 地址")
|
|
34
|
+
parser.add_argument("--policy_id", type=str, default="", help="策略ID")
|
|
35
|
+
parser.add_argument("--model_name", type=str, default="", help="模型名称")
|
|
36
|
+
parser.add_argument("--model_version", type=str, default="", help="模型版本")
|
|
37
|
+
parser.add_argument("--model_description", type=str, default="", help="模型描述")
|
|
38
|
+
parser.add_argument("--cu_type", type=str, default="", help="CU类型,可选值为Basic, Advanced, Enterprise")
|
|
39
|
+
parser.add_argument("--replica_count", type=int, default=1, help="副本数量,默认1")
|
|
40
|
+
parser.add_argument("--inference_engine", type=str, default="vllm", help="推理引擎,可选值为vllm, sglang")
|
|
41
|
+
parser.add_argument("--silent", '-s', action='store_true', help="h是否打印http request日志")
|
|
42
|
+
args = parser.parse_args()
|
|
43
|
+
return args
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
args = parser()
|
|
48
|
+
config = EncryptionConfig("", "")
|
|
49
|
+
encrypter = JeddakModelEncrypter(config)
|
|
50
|
+
|
|
51
|
+
# 通过 sys.modules 修改 b 中的全局变量
|
|
52
|
+
sys.modules['bytedance.jeddak_secure_model.pcc_utils'].Host = args.tks_addr
|
|
53
|
+
sys.modules['bytedance.jeddak_secure_model.pcc_utils'].Region = args.region
|
|
54
|
+
|
|
55
|
+
print("Step1: Encrypting model and uploading to TOS...")
|
|
56
|
+
res = encrypter.encrypt_model_and_upload(
|
|
57
|
+
model_path=args.model_path,
|
|
58
|
+
bucket_name=args.bucket_name,
|
|
59
|
+
volc_ak=args.AK,
|
|
60
|
+
volc_sk=args.SK,
|
|
61
|
+
region=args.region,
|
|
62
|
+
endpoint=args.endpoint,
|
|
63
|
+
ring_id=args.ring_id,
|
|
64
|
+
ring_name=args.ring_name,
|
|
65
|
+
ring_desc=args.ring_desc,
|
|
66
|
+
key_name=args.key_name,
|
|
67
|
+
key_desc=args.key_desc,
|
|
68
|
+
app_id=args.app_id,
|
|
69
|
+
service=args.service,
|
|
70
|
+
tks_addr=args.tks_addr,
|
|
71
|
+
encrypt_flag=args.encrypt_flag
|
|
72
|
+
)
|
|
73
|
+
print(f"Step1: Finished with result={res}")
|
|
74
|
+
|
|
75
|
+
# Step2: Set TKS policy
|
|
76
|
+
# 注意:需要在JeddakPCC的控制台中创建密钥环和密钥,并获取密钥环ID和密钥ID
|
|
77
|
+
# 这里的key_id是上一步中返回的密钥ID
|
|
78
|
+
# policy_id是你在JeddakPCC控制台中创建的策略ID
|
|
79
|
+
# 你需要在JeddakPCC控制台中创建策略,并获取策略ID
|
|
80
|
+
step = 1
|
|
81
|
+
if args.encrypt_flag:
|
|
82
|
+
print("Step2: Setting TKS policy...")
|
|
83
|
+
set_tks_policy(
|
|
84
|
+
AK=args.AK,
|
|
85
|
+
SK=args.SK,
|
|
86
|
+
uid=args.app_id,
|
|
87
|
+
key_id=res["key_id"],
|
|
88
|
+
policy_id=args.policy_id,
|
|
89
|
+
silent=args.silent,
|
|
90
|
+
service=args.service
|
|
91
|
+
)
|
|
92
|
+
print("Step2: Finished setting TKS policy")
|
|
93
|
+
step = 2
|
|
94
|
+
|
|
95
|
+
print("Step{}: Publishing model to JeddakPCC MMS".format(1+step))
|
|
96
|
+
ring_id = res.get("ring_id")
|
|
97
|
+
key_id = res.get("key_id")
|
|
98
|
+
if ring_id is None:
|
|
99
|
+
ring_id = "None"
|
|
100
|
+
if key_id is None:
|
|
101
|
+
key_id = "None"
|
|
102
|
+
publish_res = publish_inference_model(
|
|
103
|
+
AK=args.AK,
|
|
104
|
+
SK=args.SK,
|
|
105
|
+
model_name=args.model_name,
|
|
106
|
+
model_version=args.model_version,
|
|
107
|
+
model_description=args.model_description,
|
|
108
|
+
model_baseline=res["baseline"],
|
|
109
|
+
tos_url=res["tos_url"],
|
|
110
|
+
ring_id=ring_id,
|
|
111
|
+
key_id=key_id,
|
|
112
|
+
encrypt_flag=args.encrypt_flag,
|
|
113
|
+
silent=args.silent,
|
|
114
|
+
service=args.service
|
|
115
|
+
)
|
|
116
|
+
print("Step{}: Published model to JeddakPCC MMS with response = {}".format(1+step, publish_res))
|
|
117
|
+
|
|
118
|
+
engine_conf_res = get_engine_conf(
|
|
119
|
+
AK=args.AK,
|
|
120
|
+
SK=args.SK,
|
|
121
|
+
cu_type=args.cu_type,
|
|
122
|
+
inference_engine=args.inference_engine,
|
|
123
|
+
model_id=publish_res["Result"]["ModelID"],
|
|
124
|
+
silent=args.silent,
|
|
125
|
+
service=args.service
|
|
126
|
+
)
|
|
127
|
+
engine_conf = engine_conf_res["Result"]
|
|
128
|
+
|
|
129
|
+
# Step3: Deploy model to JeddakPCC
|
|
130
|
+
print("Step{}: Deploying model to JeddakPCC".format(2+step))
|
|
131
|
+
deploy_inference_model(
|
|
132
|
+
AK=args.AK,
|
|
133
|
+
SK=args.SK,
|
|
134
|
+
model_id=publish_res["Result"]["ModelID"],
|
|
135
|
+
cu_type=args.cu_type,
|
|
136
|
+
replica_count=args.replica_count,
|
|
137
|
+
inference_engine=args.inference_engine,
|
|
138
|
+
engine_conf=engine_conf,
|
|
139
|
+
silent=args.silent,
|
|
140
|
+
service=args.service
|
|
141
|
+
)
|
|
142
|
+
print("Step{}: Deployed model to JeddakPCC".format(2+step))
|
|
143
|
+
|
|
144
|
+
# Step4: Query model deploy status in JeddakPCC using list_inference_model
|
|
145
|
+
print("Step{}: Querying model deploy status in JeddakPCC".format(3+step))
|
|
146
|
+
deploy_status = "wait"
|
|
147
|
+
while True:
|
|
148
|
+
if deploy_status == "running":
|
|
149
|
+
break
|
|
150
|
+
list_res = list_inference_model(
|
|
151
|
+
AK=args.AK,
|
|
152
|
+
SK=args.SK,
|
|
153
|
+
silent=args.silent,
|
|
154
|
+
service=args.service
|
|
155
|
+
)
|
|
156
|
+
model_list = list_res["Result"]["ModelList"]
|
|
157
|
+
if publish_res["Result"]["ModelID"] not in [model["ModelID"] for model in model_list]:
|
|
158
|
+
print("Step{}.1: Model not found in JeddakPCC".format(3+step))
|
|
159
|
+
raise Exception("Model not found in JeddakPCC, checkout MMS to see if the model is published or deleted")
|
|
160
|
+
break
|
|
161
|
+
for model in model_list:
|
|
162
|
+
if model["ModelID"] == publish_res["Result"]["ModelID"]:
|
|
163
|
+
print(" Step{}.1: Queried model deploy status in JeddakPCC with status={}".format(3+step, model["DeployStatus"]))
|
|
164
|
+
if model["DeployStatus"] == "running":
|
|
165
|
+
deploy_status = "running"
|
|
166
|
+
break
|
|
167
|
+
time.sleep(10)
|
|
168
|
+
|
|
169
|
+
print("Step{}: model deployment succeed".format(3+step))
|
|
170
|
+
|
|
171
|
+
# Step5: Test model in JeddakPCC
|
|
172
|
+
print("Step{}: Testing model in JeddakPCC".format(4+step))
|
|
173
|
+
test_res = test_inference_model(
|
|
174
|
+
AK=args.AK,
|
|
175
|
+
SK=args.SK,
|
|
176
|
+
model_id=publish_res["Result"]["ModelID"],
|
|
177
|
+
silent=args.silent,
|
|
178
|
+
service=args.service
|
|
179
|
+
)
|
|
180
|
+
print("Step{}: model test succeed with resp = {}".format(4+step, test_res))
|
|
181
|
+
print("Step{}: Finished".format(5+step))
|