dts-dance 0.2.1__tar.gz → 0.2.2__tar.gz

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 (25) hide show
  1. {dts_dance-0.2.1 → dts_dance-0.2.2}/PKG-INFO +2 -2
  2. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/bytecloud.py +20 -12
  3. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/dflow.py +5 -5
  4. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/dsyncer.py +7 -7
  5. dts_dance-0.2.1/dtsdance/spacex.py → dts_dance-0.2.2/dtsdance/spacex_bytedts.py +9 -4
  6. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/tcc_inner.py +1 -1
  7. {dts_dance-0.2.1 → dts_dance-0.2.2}/pyproject.toml +2 -2
  8. dts_dance-0.2.2/tests/config.py +51 -0
  9. {dts_dance-0.2.1 → dts_dance-0.2.2}/tests/test_dflow.py +2 -4
  10. {dts_dance-0.2.1 → dts_dance-0.2.2}/tests/test_spacex.py +5 -8
  11. {dts_dance-0.2.1 → dts_dance-0.2.2}/tests/test_tcc.py +8 -6
  12. {dts_dance-0.2.1 → dts_dance-0.2.2}/uv.lock +8 -8
  13. dts_dance-0.2.1/tests/config.py +0 -30
  14. {dts_dance-0.2.1 → dts_dance-0.2.2}/.gitignore +0 -0
  15. {dts_dance-0.2.1 → dts_dance-0.2.2}/.python-version +0 -0
  16. {dts_dance-0.2.1 → dts_dance-0.2.2}/CLAUDE.md +0 -0
  17. {dts_dance-0.2.1 → dts_dance-0.2.2}/DEV.md +0 -0
  18. {dts_dance-0.2.1 → dts_dance-0.2.2}/README.md +0 -0
  19. {dts_dance-0.2.1 → dts_dance-0.2.2}/config.yaml +0 -0
  20. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/__init__.py +0 -0
  21. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/feishu_base.py +0 -0
  22. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/feishu_table.py +0 -0
  23. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/metrics_fe.py +0 -0
  24. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/s3.py +0 -0
  25. {dts_dance-0.2.1 → dts_dance-0.2.2}/dtsdance/tcc_open.py +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dts-dance
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: dts dance lib
5
5
  Keywords: observation,tools
6
6
  Requires-Python: >=3.12
7
- Requires-Dist: boto3<2.0.0,>=1.42.27
7
+ Requires-Dist: boto3<2.0.0,>=1.42.29
8
8
  Requires-Dist: loguru<0.8.0,>=0.7.3
9
9
  Requires-Dist: pyyaml<7.0.0,>=6.0.3
10
10
  Requires-Dist: requests<3.0.0,>=2.32.5
@@ -22,13 +22,14 @@ class ByteCloudClient:
22
22
  # 每小时刷新一次,单位为秒
23
23
  _REFRESH_INTERVAL = 1 * 60 * 60
24
24
 
25
- def __init__(self, sites: dict[str, SiteConfig]):
25
+ def __init__(self, enable_jwt_cache: bool, sites: dict[str, SiteConfig] | None = None) -> None:
26
26
  """
27
27
  初始化 ByteCloud Client
28
28
  从配置文件加载所有环境的信息,并为每个环境初始化 JWT 令牌
29
29
  sites 中保存内容 list[(name, endpoint, svc_account, svc_secret)]
30
30
  """
31
- self.sites = sites
31
+ self.enable_jwt_cache = enable_jwt_cache
32
+ self.sites = sites if sites is not None else {}
32
33
 
33
34
  # 初始化线程锁,用于保护 jwt_tokens 的并发访问
34
35
  self.token_lock = threading.Lock()
@@ -36,11 +37,14 @@ class ByteCloudClient:
36
37
  # 初始化 JWT 令牌缓存,按环境名称索引
37
38
  self.jwt_tokens: Dict[str, str] = {}
38
39
 
39
- # 更新所有环境的 JWT 令牌
40
- self._refresh_tokens()
40
+ if enable_jwt_cache:
41
+ logger.info("启用 JWT 令牌缓存")
41
42
 
42
- # 启动 JWT 令牌刷新线程
43
- self._start_refresh_thread()
43
+ # 更新所有环境的 JWT 令牌
44
+ self._refresh_tokens()
45
+
46
+ # 启动 JWT 令牌刷新线程
47
+ self._start_refresh_thread()
44
48
 
45
49
  def _start_refresh_thread(self):
46
50
  """
@@ -131,11 +135,15 @@ class ByteCloudClient:
131
135
  """
132
136
  获取指定站点的 JWT 令牌
133
137
  """
134
- # 使用线程锁保护并发访问
135
- with self.token_lock:
136
- if site not in self.jwt_tokens:
137
- raise KeyError(f"站点 {site} JWT 令牌不存在")
138
- return self.jwt_tokens[site]
138
+ if self.enable_jwt_cache:
139
+ # 使用线程锁保护并发访问
140
+ with self.token_lock:
141
+ if site not in self.jwt_tokens:
142
+ raise KeyError(f"站点 {site} 的 JWT 令牌不存在")
143
+ return self.jwt_tokens[site]
144
+ else:
145
+ site_config = self.get_site_config(site)
146
+ return self._acquire_jwt_token(site_config.endpoint, site_config.svc_secret)
139
147
 
140
148
  def build_request_headers(self, site: str) -> dict[str, str]:
141
149
  """
@@ -150,7 +158,7 @@ class ByteCloudClient:
150
158
  jwt_token = self.get_jwt_token(site)
151
159
  return {"Content-Type": "application/json", "x-jwt-token": jwt_token}
152
160
 
153
- def get_site_info(self, site: str) -> SiteConfig:
161
+ def get_site_config(self, site: str) -> SiteConfig:
154
162
  """
155
163
  获取指定环境的信息
156
164
 
@@ -64,7 +64,7 @@ class DFlowClient:
64
64
  dict[str, Any]: DFlow 任务信息,包含 create_time 等字段
65
65
  """
66
66
  # 构建 API URL
67
- site_info = self.bytecloud_client.get_site_info(site)
67
+ site_info = self.bytecloud_client.get_site_config(site)
68
68
  url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeTaskInfo"
69
69
 
70
70
  # 构建请求数据
@@ -106,7 +106,7 @@ class DFlowClient:
106
106
  dict[str, Any]: DFlow 进程信息,包含 create_time 等字段
107
107
  """
108
108
  # 构建 API URL
109
- site_info = self.bytecloud_client.get_site_info(site)
109
+ site_info = self.bytecloud_client.get_site_config(site)
110
110
  url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeDFlowDetail"
111
111
 
112
112
  # 构建请求数据
@@ -149,7 +149,7 @@ class DFlowClient:
149
149
  str: DFlow 任务详情页面的 URL
150
150
  """
151
151
  # 根据环境生成对应的 scope 参数
152
- site_info = self.bytecloud_client.get_site_info(site)
152
+ site_info = self.bytecloud_client.get_site_config(site)
153
153
  return f"{site_info.endpoint}/bytedts/datasync/detail/{task_id}?scope={site}"
154
154
 
155
155
  def init_resources(self, site: str, ctrl_env: str) -> bool:
@@ -164,7 +164,7 @@ class DFlowClient:
164
164
  bool: CTRL 环境资源初始化结果
165
165
  """
166
166
  # 构建 API URL
167
- site_info = self.bytecloud_client.get_site_info(site)
167
+ site_info = self.bytecloud_client.get_site_config(site)
168
168
  url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/InitSystemResource"
169
169
 
170
170
  # 构建请求数据
@@ -189,7 +189,7 @@ class DFlowClient:
189
189
  list[str]: CTRL 环境资源列表
190
190
  """
191
191
  # 构建 API URL
192
- site_info = self.bytecloud_client.get_site_info(site)
192
+ site_info = self.bytecloud_client.get_site_config(site)
193
193
  url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeResources"
194
194
 
195
195
  # 构建请求数据
@@ -89,7 +89,7 @@ class DSyncerClient:
89
89
  dict[str, str]: DSyncer 任务的 rocket_mq_connection 信息,只包含 cluster、topic 和 group 字段
90
90
  """
91
91
  # 构建 API URL
92
- site_info = self.bytecloud_client.get_site_info(site)
92
+ site_info = self.bytecloud_client.get_site_config(site)
93
93
  url = f"{site_info.endpoint}/api/v1/dsyncer/openapi/taskinfo/{task_id}/"
94
94
 
95
95
  # 准备请求头
@@ -102,7 +102,7 @@ class DSyncerClient:
102
102
  获取迁移后的 DFlow 任务信息
103
103
  """
104
104
  # 构建 API URL
105
- site_info = self.bytecloud_client.get_site_info(site)
105
+ site_info = self.bytecloud_client.get_site_config(site)
106
106
  url = f"{site_info.endpoint}/api/v1/dsyncer/openapi/taskinfo/{task_id}/migrate/"
107
107
 
108
108
  # 准备请求头
@@ -144,7 +144,7 @@ class DSyncerClient:
144
144
  Returns:
145
145
  str: DSyncer 任务详情页面的 URL
146
146
  """
147
- site_info = self.bytecloud_client.get_site_info(site)
147
+ site_info = self.bytecloud_client.get_site_config(site)
148
148
  return DSyncer_Task_Detail_URL.format(endpoint=site_info.endpoint, task_id=task_id)
149
149
 
150
150
  def generate_task_grafana_url(self, task_id: str, change_time: str) -> str:
@@ -208,7 +208,7 @@ class DSyncerClient:
208
208
  bool: 如果任务正在迁移中,返回 True;否则返回 False
209
209
  """
210
210
  # 构建 API URL
211
- site_info = self.bytecloud_client.get_site_info(site)
211
+ site_info = self.bytecloud_client.get_site_config(site)
212
212
  url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/migrate/check"
213
213
 
214
214
  # 准备请求头
@@ -230,7 +230,7 @@ class DSyncerClient:
230
230
  执行回滚
231
231
  """
232
232
  # 构建 API URL
233
- site_info = self.bytecloud_client.get_site_info(site)
233
+ site_info = self.bytecloud_client.get_site_config(site)
234
234
  url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/rollback_migrate2dsyncer/"
235
235
 
236
236
  # 准备请求头
@@ -249,7 +249,7 @@ class DSyncerClient:
249
249
  标记迁移成功
250
250
  """
251
251
  # 构建 API URL
252
- site_info = self.bytecloud_client.get_site_info(site)
252
+ site_info = self.bytecloud_client.get_site_config(site)
253
253
  url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/mark_migrate_success/"
254
254
 
255
255
  # 准备请求头
@@ -271,7 +271,7 @@ class DSyncerClient:
271
271
  Optional[str]: 错误信息,成功时返回None,失败时返回错误信息
272
272
  """
273
273
  # 构建 API URL
274
- site_info = self.bytecloud_client.get_site_info(site)
274
+ site_info = self.bytecloud_client.get_site_config(site)
275
275
  url = f"{site_info.endpoint}/api/v1/dsyncer/secret_api/task/migrate2dflow/single"
276
276
 
277
277
  # 准备请求头
@@ -5,7 +5,7 @@ from loguru import logger
5
5
 
6
6
 
7
7
  class GatewayInfo(NamedTuple):
8
- mgr_env: str
8
+ mgr_name: str
9
9
  ctrl_name: str
10
10
  gateway_endpoint: str
11
11
  auth_user: str
@@ -26,7 +26,7 @@ class SpaceXClient:
26
26
  self.bytecloud_client = bytecloud_client
27
27
 
28
28
  def list_mgr(self, site: str) -> list[Any]:
29
- site_info = self.bytecloud_client.get_site_info(site)
29
+ site_info = self.bytecloud_client.get_site_config(site)
30
30
  url = f"{site_info.endpoint_bytedts_spacex}/bytedts/v1/queryServerMeta"
31
31
 
32
32
  try:
@@ -41,10 +41,11 @@ class SpaceXClient:
41
41
  raise
42
42
 
43
43
  def register_gateway(self, site: str, gateway_info: GatewayInfo) -> bool:
44
- site_info = self.bytecloud_client.get_site_info(site)
44
+ site_info = self.bytecloud_client.get_site_config(site)
45
45
  url = f"{site_info.endpoint_bytedts_spacex}/bytedts/v1/registryGateway"
46
46
  data_raw = {
47
- "server_region": gateway_info.mgr_env,
47
+ "region": gateway_info.mgr_name,
48
+ "server_region": gateway_info.mgr_name,
48
49
  "cluster_region": gateway_info.ctrl_name,
49
50
  "cluster_name": gateway_info.ctrl_name,
50
51
  "server_domain": gateway_info.gateway_endpoint,
@@ -55,6 +56,10 @@ class SpaceXClient:
55
56
  "frontend_password": gateway_info.auth_password,
56
57
  "gw_meta_db": gateway_info.gw_meta_db,
57
58
  "gateway_type": "psm",
59
+ "runtime_psm": "bytedts.dflow.rownott",
60
+ "tao_service_name": "inf.bytedts.agent",
61
+ "tao_service_node_id": 1071,
62
+ "unified_tao_service": 1,
58
63
  }
59
64
  try:
60
65
  response = requests.post(url, json=data_raw, headers=self.bytecloud_client.build_request_headers(site))
@@ -24,7 +24,7 @@ class TCCInnerClient:
24
24
  """
25
25
  List TCC configurations.
26
26
  """
27
- site_info = self.bytecloud_client.get_site_info(site)
27
+ site_info = self.bytecloud_client.get_site_config(site)
28
28
  url = f"{site_info.endpoint}/api/v3/tcc/bcc/config/list_v2"
29
29
 
30
30
  data_raw = {
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dts-dance"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "dts dance lib"
9
9
  readme = "README.md"
10
10
  keywords = ["tools", "observation"]
@@ -12,7 +12,7 @@ requires-python = ">=3.12"
12
12
  dependencies = [
13
13
  "requests>=2.32.5,<3.0.0",
14
14
  "loguru>=0.7.3,<0.8.0",
15
- "boto3>=1.42.27,<2.0.0",
15
+ "boto3>=1.42.29,<2.0.0",
16
16
  "pyyaml>=6.0.3,<7.0.0",
17
17
  ]
18
18
 
@@ -0,0 +1,51 @@
1
+ import os
2
+ import yaml
3
+ from dtsdance.bytecloud import SiteConfig
4
+
5
+
6
+ class ConfigLoader:
7
+
8
+ _instance: "ConfigLoader | None" = None
9
+
10
+ def __init__(self):
11
+ self._site_configs: dict[str, SiteConfig] = {}
12
+
13
+ @classmethod
14
+ def get_instance(cls) -> "ConfigLoader":
15
+ """获取单例实例"""
16
+ if cls._instance is None:
17
+ cls._instance = cls()
18
+
19
+ return cls._instance
20
+
21
+ def load_from_file(self, sites: list[str] | None = None) -> None:
22
+ """从配置文件加载配置"""
23
+ config_path = os.environ.get("CONFIG_PATH", "config.yaml")
24
+
25
+ try:
26
+ with open(config_path, "r", encoding="utf-8") as f:
27
+ configs = yaml.safe_load(f)
28
+ except Exception as e:
29
+ raise ValueError(f"加载配置失败: {e}")
30
+
31
+ self._site_configs.update(
32
+ {
33
+ k: SiteConfig(k, v["endpoint"], v["svc_account"], v["svc_secret"], v.get("endpoint_bytedts_spacex", None))
34
+ for k, v in configs["sites"].items()
35
+ if sites is None or k in sites
36
+ }
37
+ )
38
+
39
+ def get(self, site: str) -> SiteConfig:
40
+ """获取指定站点的配置"""
41
+ if not self._site_configs:
42
+ raise RuntimeError("配置未加载,请先调用 load_from_file()")
43
+
44
+ if site not in self._site_configs:
45
+ raise KeyError(f"站点 {site} 不存在")
46
+
47
+ return self._site_configs[site]
48
+
49
+ def get_site_configs(self) -> dict[str, SiteConfig]:
50
+ """获取所有配置"""
51
+ return self._site_configs
@@ -1,10 +1,7 @@
1
1
  from dtsdance.dflow import DFlowClient
2
2
  from dtsdance.bytecloud import ByteCloudClient
3
3
 
4
- from config import load_site_configs
5
-
6
- site_configs = load_site_configs(["boe", "cn"])
7
- bytecloud_client = ByteCloudClient(site_configs)
4
+ bytecloud_client = ByteCloudClient(False)
8
5
  dflow_client = DFlowClient(bytecloud_client)
9
6
 
10
7
 
@@ -13,6 +10,7 @@ def test_get_task_info():
13
10
  info = dflow_client.get_task_info("cn", "106037095986690")
14
11
  print(f"DFlow Info: {info}")
15
12
 
13
+
16
14
  # pytest tests/test_dflow.py::test_get_dflow_info -s
17
15
  def test_get_dflow_info():
18
16
  info = dflow_client.get_dflow_info("cn", "106029334786818")
@@ -1,24 +1,21 @@
1
1
  import json
2
2
  from dtsdance.bytecloud import ByteCloudClient
3
- from dtsdance.spacex import GatewayInfo, SpaceXClient
4
- from config import load_site_configs
3
+ from dtsdance.spacex_bytedts import GatewayInfo, SpaceXClient
5
4
 
6
- site = "boe"
7
- site_configs = load_site_configs([site])
8
- bytecloud_client = ByteCloudClient(site_configs)
5
+ bytecloud_client = ByteCloudClient(False)
9
6
  spacex = SpaceXClient(bytecloud_client)
10
7
 
11
8
 
12
9
  # pytest tests/test_spacex.py::test_list_mgr -s
13
10
  def test_list_mgr():
14
- mgr_list = spacex.list_mgr(site)
11
+ mgr_list = spacex.list_mgr("boe")
15
12
  print(f"mgr_list: {json.dumps(mgr_list, indent=2, ensure_ascii=False)}")
16
13
 
17
14
 
18
15
  # pytest tests/test_spacex.py::test_register_gateway -s
19
16
  def test_register_gateway():
20
17
  gateway_info = GatewayInfo(
21
- mgr_env="boe",
18
+ mgr_name="boe",
22
19
  ctrl_name="boe_halo_test",
23
20
  gateway_endpoint="volc.dts.gateway.service.boe:cluster:boe_halo_test:family:v6",
24
21
  auth_user="bytedts_backend",
@@ -26,5 +23,5 @@ def test_register_gateway():
26
23
  root_secret_key="97oscH5k",
27
24
  gw_meta_db="bytedts_sre_halo",
28
25
  )
29
- result = spacex.register_gateway(site, gateway_info)
26
+ result = spacex.register_gateway("boe", gateway_info)
30
27
  print(f"result: {result}")
@@ -1,22 +1,24 @@
1
- from config import load_site_configs
2
1
  from dtsdance.bytecloud import ByteCloudClient
3
2
  from dtsdance.tcc_open import TCCClient
4
3
  from dtsdance.tcc_inner import TCCInnerClient
4
+ from config import ConfigLoader
5
5
 
6
- site_configs = load_site_configs(["boe", "us-ttp"])
7
- bytecloud_client = ByteCloudClient(site_configs)
8
- client_inner = TCCInnerClient(bytecloud_client)
6
+ loader = ConfigLoader.get_instance()
7
+ loader.load_from_file(["boe"])
8
+ site_configs = loader.get_site_configs()
9
9
 
10
10
 
11
11
  # pytest tests/test_tcc.py::test_get_config -s
12
12
  def test_get_config():
13
13
  site_info = site_configs["boe"]
14
14
  client_open = TCCClient(site_info.svc_account, site_info.svc_secret, endpoint=site_info.endpoint)
15
- config_ctrl_env = client_open.get_config(ns_name="bytedts.mgr.api", region="China-BOE", dir="/default", conf_name="ctrl_env1")
15
+ config_ctrl_env = client_open.get_config(ns_name="bytedts.mgr.api", region="China-BOE", dir="/default", conf_name="ctrl_env")
16
16
  print(f"ctrl_env: {config_ctrl_env}")
17
17
 
18
18
 
19
19
  # pytest tests/test_tcc.py::test_list_configs -s
20
20
  def test_list_configs():
21
- configs = client_inner.list_configs(site="us-ttp", ns_name="bytedts.mgr.api", region="US-TTP", dir="/default", conf_name="ctrl_env")
21
+ bytecloud_client = ByteCloudClient(False, site_configs)
22
+ client_inner = TCCInnerClient(bytecloud_client)
23
+ configs = client_inner.list_configs(site="boe", ns_name="bytedts.mgr.api", region="China-BOE", dir="/default", conf_name="ctrl_env")
22
24
  print(f"configs: {configs}")
@@ -4,30 +4,30 @@ requires-python = ">=3.12"
4
4
 
5
5
  [[package]]
6
6
  name = "boto3"
7
- version = "1.42.27"
7
+ version = "1.42.29"
8
8
  source = { registry = "https://pypi.org/simple" }
9
9
  dependencies = [
10
10
  { name = "botocore" },
11
11
  { name = "jmespath" },
12
12
  { name = "s3transfer" },
13
13
  ]
14
- sdist = { url = "https://files.pythonhosted.org/packages/8d/99/65569052c911160702ad371b0b08b751bb1df29deeef0c5c117528074c29/boto3-1.42.27.tar.gz", hash = "sha256:a8a53abb98ff1a24d9a88d9d8c0285bf02d23189666130456e8951ede2f7db98", size = 112765, upload-time = "2026-01-13T20:35:11.971Z" }
14
+ sdist = { url = "https://files.pythonhosted.org/packages/5c/24/1dd85b64004103c2e60476d0fa8d78435f5fed9db1129cd2cd332784037a/boto3-1.42.29.tar.gz", hash = "sha256:247e54f24116ad6792cfc14b274288383af3ec3433b0547da8a14a8bd6e81950", size = 112810, upload-time = "2026-01-15T20:36:39.404Z" }
15
15
  wheels = [
16
- { url = "https://files.pythonhosted.org/packages/44/9e/9554a8c1d7610ec8ea55bec0dac87ad894c83cada2ea2c05fc45f14d0cde/boto3-1.42.27-py3-none-any.whl", hash = "sha256:39dfec51aff3f9356e8c7331195f324cb498ec75b2601a902fc62aa127b8fd00", size = 140577, upload-time = "2026-01-13T20:35:09.35Z" },
16
+ { url = "https://files.pythonhosted.org/packages/51/30/2c25d7be8418e7f137ffece6097c68199dbd6996da645ec9b5a5a9647123/boto3-1.42.29-py3-none-any.whl", hash = "sha256:6c9c4dece67bf72d82ba7dff48e33a56a87cdf9b16c8887f88ca7789a95d3317", size = 140574, upload-time = "2026-01-15T20:36:37.206Z" },
17
17
  ]
18
18
 
19
19
  [[package]]
20
20
  name = "botocore"
21
- version = "1.42.27"
21
+ version = "1.42.29"
22
22
  source = { registry = "https://pypi.org/simple" }
23
23
  dependencies = [
24
24
  { name = "jmespath" },
25
25
  { name = "python-dateutil" },
26
26
  { name = "urllib3" },
27
27
  ]
28
- sdist = { url = "https://files.pythonhosted.org/packages/65/90/55b003d38f947c90c0d7e306d377dcdfd9cd0dc1e184082b2d1a6adb0eec/botocore-1.42.27.tar.gz", hash = "sha256:c8e1e3ffb6c871622b1c8054f064d60cbc786aa5ca1f97f5f9fd5fa0a9d82d05", size = 14880030, upload-time = "2026-01-13T20:35:00.31Z" }
28
+ sdist = { url = "https://files.pythonhosted.org/packages/70/08/8a8e0255949845f764c5126f97b1bc09a6484077f124c2177b979ecfbbff/botocore-1.42.29.tar.gz", hash = "sha256:0fe869227a1dfe818f691a31b8c1693e39be8056a6dff5d6d4b3fc5b3a5e7d42", size = 14890916, upload-time = "2026-01-15T20:36:28.241Z" }
29
29
  wheels = [
30
- { url = "https://files.pythonhosted.org/packages/bf/32/8a4a0447432425cd2f772c757d988742685f46796cf5d68aeaf6bcb6bc37/botocore-1.42.27-py3-none-any.whl", hash = "sha256:d51fb3b8dd1a944c8d238d2827a0dd6e5528d6da49a3bd9eccad019c533e4c9c", size = 14555236, upload-time = "2026-01-13T20:34:55.918Z" },
30
+ { url = "https://files.pythonhosted.org/packages/94/76/cfa6a934ee5a8a87f626b38275193a046da894d2f9021e001587fc2e8c7d/botocore-1.42.29-py3-none-any.whl", hash = "sha256:b45f8dfc1de5106a9d040c5612f267582e68b2b2c5237477dff85c707c1c5d11", size = 14563947, upload-time = "2026-01-15T20:36:23.828Z" },
31
31
  ]
32
32
 
33
33
  [[package]]
@@ -107,7 +107,7 @@ wheels = [
107
107
 
108
108
  [[package]]
109
109
  name = "dts-dance"
110
- version = "0.2.1"
110
+ version = "0.2.2"
111
111
  source = { editable = "." }
112
112
  dependencies = [
113
113
  { name = "boto3" },
@@ -118,7 +118,7 @@ dependencies = [
118
118
 
119
119
  [package.metadata]
120
120
  requires-dist = [
121
- { name = "boto3", specifier = ">=1.42.27,<2.0.0" },
121
+ { name = "boto3", specifier = ">=1.42.29,<2.0.0" },
122
122
  { name = "loguru", specifier = ">=0.7.3,<0.8.0" },
123
123
  { name = "pyyaml", specifier = ">=6.0.3,<7.0.0" },
124
124
  { name = "requests", specifier = ">=2.32.5,<3.0.0" },
@@ -1,30 +0,0 @@
1
- import os
2
- from typing import Any
3
- import yaml
4
- from dtsdance.bytecloud import SiteConfig
5
-
6
-
7
- def load_site_configs(sites: list[str] | None = None) -> dict[str, SiteConfig]:
8
- """从配置文件加载配置
9
-
10
- Returns:
11
- dict[str, Any]: 应用配置字典
12
-
13
- Raises:
14
- ValueError: 配置文件加载错误
15
- """
16
- config_path = os.environ.get("CONFIG_PATH", "config.yaml")
17
-
18
- configs: dict[str, Any] = {}
19
- try:
20
- with open(config_path, "r", encoding="utf-8") as f:
21
- configs = yaml.safe_load(f)
22
-
23
- except Exception as e:
24
- raise ValueError(f"加载配置失败: {e}")
25
-
26
- return {
27
- k: SiteConfig(k, v["endpoint"], v["svc_account"], v["svc_secret"], v.get("endpoint_bytedts_spacex", None))
28
- for k, v in configs["sites"].items()
29
- if k in sites
30
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes