wedata-pre-code 1.0.8__py3-none-any.whl → 1.0.11__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.
@@ -1,6 +1,13 @@
1
1
  from typing import Optional
2
2
 
3
3
  from wedata_pre_code.common.base_client import BaseClient
4
+ from wedata_pre_code.wedata3.experiment import (
5
+ _create_experiment,
6
+ _delete_experiment,
7
+ _rename_experiment,
8
+ _restore_experiment
9
+ )
10
+
4
11
 
5
12
  __doc__ = """
6
13
  Wedata3预执行代码客户端
@@ -337,7 +344,7 @@ class Wedata3PreCodeClient(BaseClient):
337
344
  return wrapper
338
345
 
339
346
  # 应用装饰器
340
- MlflowClient.create_experiment = inject_workspace_tag(MlflowClient.create_experiment)
347
+ MlflowClient.create_experiment = inject_workspace_tag(_create_experiment)
341
348
  MlflowClient.create_registered_model = inject_workspace_tag(MlflowClient.create_registered_model)
342
349
  MlflowClient.create_model_version = inject_workspace_tag(MlflowClient.create_model_version)
343
350
  MlflowClient.get_experiment = validate_wedata_tag(MlflowClient.get_experiment)
@@ -345,9 +352,9 @@ class Wedata3PreCodeClient(BaseClient):
345
352
  MlflowClient.get_run = validate_wedata_tag(MlflowClient.get_run)
346
353
  MlflowClient.get_parent_run = validate_wedata_tag(MlflowClient.get_parent_run)
347
354
  MlflowClient.get_registered_model = validate_wedata_tag(MlflowClient.get_registered_model)
348
- MlflowClient.delete_experiment = validate_wedata_before_operation(MlflowClient.delete_experiment)
349
- MlflowClient.restore_experiment = validate_wedata_before_operation(MlflowClient.restore_experiment)
350
- MlflowClient.rename_experiment = validate_wedata_before_operation(MlflowClient.rename_experiment)
355
+ MlflowClient.delete_experiment = _delete_experiment
356
+ MlflowClient.restore_experiment = _restore_experiment
357
+ MlflowClient.rename_experiment = validate_wedata_before_operation(_rename_experiment)
351
358
  MlflowClient.set_experiment_tag = validate_wedata_before_operation(MlflowClient.set_experiment_tag)
352
359
  MlflowClient.set_tag = validate_wedata_before_operation(MlflowClient.set_tag)
353
360
  MlflowClient.delete_tag = validate_wedata_before_operation(MlflowClient.delete_tag)
@@ -0,0 +1,187 @@
1
+ import http
2
+ import os
3
+ import hashlib
4
+ import hmac
5
+ import json
6
+ import time
7
+ from datetime import datetime, timezone
8
+ from typing import Optional, Dict, Any
9
+ from http.client import HTTPSConnection, HTTPException
10
+ from mlflow.protos.databricks_pb2 import ABORTED, BAD_REQUEST
11
+ from mlflow import MlflowException
12
+
13
+
14
+ __doc__ = """
15
+ 实验相关云API接口
16
+ """
17
+
18
+
19
+ def _set_request_header(headers: Optional[Dict[str, str]]) -> Dict[str, str]:
20
+ if headers is None:
21
+ headers = {}
22
+
23
+ if "IS_WEDATA_TEST" in os.environ.keys():
24
+ headers["X-Qcloud-User-Id"] = os.environ["TEST_USER_ID"]
25
+
26
+ return headers
27
+
28
+
29
+ def _get_endpoint() -> str:
30
+ endpoint = os.getenv("TENCENTCLOUD_ENDPOINT")
31
+ if endpoint is None:
32
+ endpoint = "wedata.internal.tencentcloudapi.com"
33
+
34
+ return endpoint
35
+
36
+
37
+ class _DataScienceApi(object):
38
+ _version = "2025-10-10"
39
+ _service = "wedata"
40
+
41
+ def __init__(self, region: str, secret_id: str, secret_key: str, token: Optional[str] = None) -> None:
42
+ self._host = _get_endpoint()
43
+ self._region = region
44
+ self._secret_id = secret_id
45
+ self._secret_key = secret_key
46
+ self._token = token
47
+
48
+ def _sign(self, action: str, body: str, timestamp: int) -> str:
49
+ """http请求签名"""
50
+ algorithm = "TC3-HMAC-SHA256"
51
+ date = datetime.fromtimestamp(timestamp, timezone.utc).strftime("%Y-%m-%d")
52
+
53
+ # ************* 步骤 1:拼接规范请求串 *************
54
+ http_request_method = "POST"
55
+ canonical_uri = "/"
56
+ canonical_querystring = ""
57
+ ct = "application/json; charset=utf-8"
58
+ canonical_headers = "content-type:%s\nhost:%s\nx-tc-action:%s\n" % (ct, self._host, action.lower())
59
+ signed_headers = "content-type;host;x-tc-action"
60
+ hashed_request_payload = hashlib.sha256(body.encode("utf-8")).hexdigest()
61
+ canonical_request = (http_request_method + "\n" +
62
+ canonical_uri + "\n" +
63
+ canonical_querystring + "\n" +
64
+ canonical_headers + "\n" +
65
+ signed_headers + "\n" +
66
+ hashed_request_payload)
67
+
68
+ # ************* 步骤 2:拼接待签名字符串 *************
69
+ credential_scope = date + "/" + self._service + "/" + "tc3_request"
70
+ hashed_canonical_request = hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
71
+ string_to_sign = (algorithm + "\n" +
72
+ str(timestamp) + "\n" +
73
+ credential_scope + "\n" +
74
+ hashed_canonical_request)
75
+
76
+ # ************* 步骤 3:计算签名 *************
77
+ secret_date = hmac.new(("TC3" + self._secret_key).encode("utf-8"), date.encode("utf-8"), hashlib.sha256).digest()
78
+ secret_service = hmac.new(secret_date, self._service.encode("utf-8"), hashlib.sha256).digest()
79
+ secret_signing = hmac.new(secret_service, "tc3_request".encode("utf-8"), hashlib.sha256).digest()
80
+ signature = hmac.new(secret_signing, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()
81
+
82
+ # ************* 步骤 4:拼接 Authorization *************
83
+ authorization = (algorithm + " " +
84
+ "Credential=" + self._secret_id + "/" + credential_scope + ", " +
85
+ "SignedHeaders=" + signed_headers + ", " +
86
+ "Signature=" + signature)
87
+
88
+ return authorization
89
+
90
+ def _request(self, action: str, payload: Dict[str, Any], headers: Dict[str, str]):
91
+ body = json.dumps(payload)
92
+ timestamp = int(time.time())
93
+ authorization = self._sign(action, body, timestamp)
94
+
95
+ headers.update({
96
+ "Authorization": authorization,
97
+ "Content-Type": "application/json; charset=utf-8",
98
+ "Host": self._host,
99
+ "X-TC-Action": action,
100
+ "X-TC-Timestamp": str(timestamp),
101
+ "X-TC-Version": self._version,
102
+ })
103
+ if self._region:
104
+ headers["X-TC-Region"] = self._region
105
+ if self._token:
106
+ headers["X-TC-Token"] = self._token
107
+
108
+ req = HTTPSConnection(self._host, timeout=30)
109
+ try:
110
+ req.request("POST", "/", headers=headers, body=body.encode("utf-8"))
111
+ resp = req.getresponse()
112
+ finally:
113
+ req.close()
114
+ content = resp.read().decode("utf-8")
115
+
116
+ # check http status
117
+ if resp.status != http.HTTPStatus.OK:
118
+ raise HTTPException(f"ServerNetworkError, message: {content}")
119
+ try:
120
+ data = json.loads(content)
121
+ except json.JSONDecodeError:
122
+ raise HTTPException(f"ServerNetworkError, message: {content}")
123
+
124
+ # check error
125
+ if "Error" in data["Response"]:
126
+ code = data["Response"]["Error"]["Code"]
127
+ message = data["Response"]["Error"]["Message"]
128
+ req_id = data["Response"]["RequestId"]
129
+ raise HTTPException(f"code:{code} message:{message} requestId:{req_id}")
130
+
131
+ return data
132
+
133
+ def create_experiment(self, body: Dict[str, Any], headers: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
134
+ headers = _set_request_header(headers)
135
+ resp = self._request("CreateExperiment", body, headers)
136
+
137
+ return resp
138
+
139
+ def rename_experiment(self, body: Dict[str, Any], headers: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
140
+ headers = _set_request_header(headers)
141
+ resp = self._request("UpdateExperimentName", body, headers)
142
+
143
+ return resp
144
+
145
+
146
+ def _get_client() -> _DataScienceApi:
147
+ region = os.environ["KERNEL_WEDATA_REGION"]
148
+ secret_id = os.environ["KERNEL_WEDATA_CLOUD_SDK_SECRET_ID"]
149
+ secret_key = os.environ["KERNEL_WEDATA_CLOUD_SDK_SECRET_KEY"]
150
+ token = os.environ["KERNEL_WEDATA_CLOUD_SDK_SECRET_TOKEN"]
151
+ _client = _DataScienceApi(region, secret_id, secret_key, token)
152
+ return _client
153
+
154
+
155
+ def _create_experiment(
156
+ self, name: str,
157
+ artifact_location: Optional[str] = None,
158
+ tags: Optional[dict[str, Any]] = None,
159
+ ) -> str:
160
+ req_body = {
161
+ "WorkspaceId": os.environ["WEDATA_WORKSPACE_ID"],
162
+ "Name": name,
163
+ "Type": "MACHINE_LEARNING",
164
+ "Tags": [{"Key": key, "Value": value} for key, value in (tags or {}).items()]
165
+ }
166
+ _client = _get_client()
167
+ resp = _client.create_experiment(req_body)
168
+ return resp["Response"]["Data"]["ExperimentId"]
169
+
170
+ def _rename_experiment(self, experiment_id: str, new_name: str) -> None:
171
+ req_body = {
172
+ "NewName": new_name,
173
+ "ExperimentId": experiment_id,
174
+ "WorkspaceId": os.environ["WEDATA_WORKSPACE_ID"],
175
+ }
176
+ _client = _get_client()
177
+ resp = _client.rename_experiment(req_body)
178
+ if not resp["Response"]["Data"]["Status"]:
179
+ raise MlflowException("Failed to rename the experiment", BAD_REQUEST)
180
+
181
+ def _restore_experiment(self, experiment_id: str) -> None:
182
+ raise MlflowException("Please go to the WeData console to restore the experiment; "
183
+ "this operation is prohibited in scripts.", ABORTED)
184
+
185
+ def _delete_experiment(self, experiment_id: str) -> None:
186
+ raise MlflowException("Please go to the WeData console to delete the experiment; "
187
+ "this operation is prohibited in scripts.", ABORTED)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: wedata-pre-code
3
- Version: 1.0.8
3
+ Version: 1.0.11
4
4
  Summary: WeData平台的预执行代码库,为机器学习实验提供与MLflow的深度集成
5
5
  Author: WeData Team
6
6
  Author-email: WeData Team <wedata@tencent.com>
@@ -5,7 +5,8 @@ wedata_pre_code/common/base_client.py,sha256=Y9lQBOYaDOB7Zy3MR_bPvHSQjN5Onsn8TPO
5
5
  wedata_pre_code/wedata2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  wedata_pre_code/wedata2/client.py,sha256=ScAQRrT-alc2CqatiwLCNAymYfEtWKWTnrCsLTbYEoM,19535
7
7
  wedata_pre_code/wedata3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- wedata_pre_code/wedata3/client.py,sha256=CKuuHHU9JZXQeLORtPU3xXSAXzynBFN6jec8UBvrC_I,21228
9
- wedata_pre_code-1.0.8.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
10
- wedata_pre_code-1.0.8.dist-info/METADATA,sha256=3WpiDxxbZigT7G00pLE8nzOJWflPKCXmIMiLYGRGmTQ,7371
11
- wedata_pre_code-1.0.8.dist-info/RECORD,,
8
+ wedata_pre_code/wedata3/client.py,sha256=H0RB7JXeHka29xcQkyQekLR8VgSUy-9iMYRlPbRcJRg,21260
9
+ wedata_pre_code/wedata3/experiment.py,sha256=iVWmeiM-dgZrR7Cn2C0LHNMxR1BF-GAGqojHp5WrI0w,7314
10
+ wedata_pre_code-1.0.11.dist-info/WHEEL,sha256=XjEbIc5-wIORjWaafhI6vBtlxDBp7S9KiujWF1EM7Ak,79
11
+ wedata_pre_code-1.0.11.dist-info/METADATA,sha256=qCJNkdqlRxEpaYyMBK4QBUplT7sIsE3S8rDFKkZuCoU,7372
12
+ wedata_pre_code-1.0.11.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.24
2
+ Generator: uv 0.9.25
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any