dts-dance 0.2.5__tar.gz → 0.2.6__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.
- {dts_dance-0.2.5 → dts_dance-0.2.6}/PKG-INFO +2 -2
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/bytecloud.py +8 -3
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/ddutil.py +13 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/dflow.py +15 -20
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/dsyncer.py +4 -4
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/spacex.py +8 -8
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/tcc_inner.py +2 -2
- {dts_dance-0.2.5 → dts_dance-0.2.6}/pyproject.toml +2 -2
- {dts_dance-0.2.5 → dts_dance-0.2.6}/tests/test_dflow.py +8 -15
- {dts_dance-0.2.5 → dts_dance-0.2.6}/uv.lock +7 -7
- {dts_dance-0.2.5 → dts_dance-0.2.6}/.gitignore +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/.python-version +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/CLAUDE.md +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/DEV.md +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/README.md +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/config.yaml +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/__init__.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/feishu_base.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/feishu_table.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/metrics_fe.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/s3.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/dtsdance/tcc_open.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/tests/config.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/tests/test_spacex.py +0 -0
- {dts_dance-0.2.5 → dts_dance-0.2.6}/tests/test_tcc.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dts-dance
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: dts dance lib
|
|
5
5
|
Keywords: observation,tools
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
|
-
Requires-Dist: boto3>=1.42.
|
|
7
|
+
Requires-Dist: boto3>=1.42.35
|
|
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-toolbelt==1.0.0
|
|
@@ -145,18 +145,23 @@ class ByteCloudClient:
|
|
|
145
145
|
site_config = self.get_site_config(site)
|
|
146
146
|
return self._acquire_jwt_token(site_config.endpoint, site_config.svc_secret)
|
|
147
147
|
|
|
148
|
-
def build_request_headers(self, site: str) -> dict[str, str]:
|
|
148
|
+
def build_request_headers(self, site: str, vregion: str | None = None) -> dict[str, str]:
|
|
149
149
|
"""
|
|
150
150
|
构建请求头
|
|
151
151
|
|
|
152
152
|
Args:
|
|
153
153
|
site: 站点名称
|
|
154
|
-
|
|
154
|
+
vregion: 默认为 None
|
|
155
155
|
Returns:
|
|
156
156
|
dict[str, str]: 请求头字典
|
|
157
157
|
"""
|
|
158
158
|
jwt_token = self.get_jwt_token(site)
|
|
159
|
-
|
|
159
|
+
headers = {"Content-Type": "application/json", "x-jwt-token": jwt_token}
|
|
160
|
+
if vregion:
|
|
161
|
+
headers["x-bcgw-vregion"] = vregion
|
|
162
|
+
headers["get-svc"] = "1" # response header 中显示实际请求的机房
|
|
163
|
+
|
|
164
|
+
return headers
|
|
160
165
|
|
|
161
166
|
def get_site_config(self, site: str) -> SiteConfig:
|
|
162
167
|
"""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Any, Optional
|
|
2
2
|
from loguru import logger
|
|
3
3
|
import requests
|
|
4
|
+
import json
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def make_request(method: str, url: str, headers: dict[str, str], payload: Optional[dict] = None) -> dict[str, Any]:
|
|
@@ -37,3 +38,15 @@ def make_request(method: str, url: str, headers: dict[str, str], payload: Option
|
|
|
37
38
|
error_msg += f", response.text: {response.text}"
|
|
38
39
|
logger.warning(error_msg)
|
|
39
40
|
raise
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def output_curl(url: str, headers: dict[str, str], payload: dict) -> str:
|
|
44
|
+
"""
|
|
45
|
+
生成等效的 curl 命令字符串
|
|
46
|
+
"""
|
|
47
|
+
curl_headers = " \\\n ".join([f"-H '{k}: {v}'" for k, v in headers.items()])
|
|
48
|
+
curl_payload = json.dumps(payload, ensure_ascii=False)
|
|
49
|
+
curl_cmd = f"""curl -X POST '{url}' \\
|
|
50
|
+
{curl_headers} \\
|
|
51
|
+
-d '{curl_payload}'"""
|
|
52
|
+
return curl_cmd
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import collections
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
from loguru import logger
|
|
4
4
|
|
|
5
|
-
from dtsdance.ddutil import make_request
|
|
5
|
+
from dtsdance.ddutil import make_request, output_curl
|
|
6
6
|
from .bytecloud import ByteCloudClient
|
|
7
7
|
|
|
8
8
|
|
|
@@ -19,12 +19,6 @@ class DFlowClient:
|
|
|
19
19
|
def __init__(self, bytecloud_client: ByteCloudClient) -> None:
|
|
20
20
|
self.bytecloud_client = bytecloud_client
|
|
21
21
|
|
|
22
|
-
def build_request_headers(self, site: str, vregion: str | None) -> dict[str, str]:
|
|
23
|
-
headers = self.bytecloud_client.build_request_headers(site)
|
|
24
|
-
if vregion:
|
|
25
|
-
headers["x-bcgw-vregion"] = vregion
|
|
26
|
-
return headers
|
|
27
|
-
|
|
28
22
|
def get_task_info(self, site: str, task_id: str, vregion: str | None = None) -> dict[str, Any]:
|
|
29
23
|
"""
|
|
30
24
|
获取 DFlow 任务信息
|
|
@@ -43,7 +37,7 @@ class DFlowClient:
|
|
|
43
37
|
# 构建请求数据
|
|
44
38
|
payload = {"id": int(task_id)}
|
|
45
39
|
|
|
46
|
-
response_data = make_request("POST", url, self.build_request_headers(site, vregion), payload)
|
|
40
|
+
response_data = make_request("POST", url, self.bytecloud_client.build_request_headers(site, vregion), payload)
|
|
47
41
|
|
|
48
42
|
message = response_data.get("message")
|
|
49
43
|
# logger.debug(f"get_task_info {site} {task_id}, message: {message}")
|
|
@@ -52,8 +46,7 @@ class DFlowClient:
|
|
|
52
46
|
raise TaskNotFound(f"获取 DFlow 任务信息失败,站点: {site}, 任务 ID: {task_id} 不存在")
|
|
53
47
|
|
|
54
48
|
try:
|
|
55
|
-
|
|
56
|
-
task = cast(dict, data.get("task", {}))
|
|
49
|
+
task = response_data.get("data", {}).get("task", {})
|
|
57
50
|
# 提取核心信息
|
|
58
51
|
filtered_data = {
|
|
59
52
|
"task_id": task.get("id", ""),
|
|
@@ -85,7 +78,7 @@ class DFlowClient:
|
|
|
85
78
|
# 构建请求数据
|
|
86
79
|
payload = {"dflow_id": int(dflow_id)}
|
|
87
80
|
|
|
88
|
-
response_data = make_request("POST", url, self.build_request_headers(site, vregion), payload)
|
|
81
|
+
response_data = make_request("POST", url, self.bytecloud_client.build_request_headers(site, vregion), payload)
|
|
89
82
|
|
|
90
83
|
message = response_data.get("message", "")
|
|
91
84
|
# logger.debug(f"get_dflow_info {site} {dflow_id}, message: {message}")
|
|
@@ -94,8 +87,7 @@ class DFlowClient:
|
|
|
94
87
|
raise DFlowNotFound(f"获取 DFlow 进程信息失败,站点: {site}, 进程 ID: {dflow_id} 不存在")
|
|
95
88
|
|
|
96
89
|
try:
|
|
97
|
-
|
|
98
|
-
dflow = cast(dict, data.get("dflow", {}))
|
|
90
|
+
dflow = response_data.get("data", {}).get("dflow", {})
|
|
99
91
|
# 提取核心信息
|
|
100
92
|
filtered_data = {
|
|
101
93
|
"dflow_id": dflow.get("id", ""),
|
|
@@ -143,21 +135,21 @@ class DFlowClient:
|
|
|
143
135
|
# 构建请求数据
|
|
144
136
|
payload = {"ctrl_env": ctrl_env}
|
|
145
137
|
|
|
146
|
-
response_data = make_request("POST", url, self.build_request_headers(site, None), payload)
|
|
138
|
+
response_data = make_request("POST", url, self.bytecloud_client.build_request_headers(site, None), payload)
|
|
147
139
|
|
|
148
140
|
message = response_data.get("message")
|
|
149
141
|
logger.info(f"int_resources {site} {ctrl_env}, message: {message}")
|
|
150
142
|
|
|
151
143
|
return message == "ok"
|
|
152
144
|
|
|
153
|
-
def list_resources(self, site: str, ctrl_env: str) -> list[str]:
|
|
145
|
+
def list_resources(self, site: str, ctrl_env: str, vregion: str | None = None) -> list[str]:
|
|
154
146
|
"""
|
|
155
147
|
列举 CTRL 环境资源列表,连同 agent 列表
|
|
156
148
|
|
|
157
149
|
Args:
|
|
158
150
|
site: 站点名称
|
|
159
151
|
ctrl_env: 控制环境
|
|
160
|
-
|
|
152
|
+
vregion: 虚拟区域
|
|
161
153
|
Returns:
|
|
162
154
|
list[str]: CTRL 环境资源列表
|
|
163
155
|
"""
|
|
@@ -166,10 +158,13 @@ class DFlowClient:
|
|
|
166
158
|
url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeResources"
|
|
167
159
|
|
|
168
160
|
# 构建请求数据
|
|
161
|
+
headers = self.bytecloud_client.build_request_headers(site, vregion)
|
|
169
162
|
payload = {"offset": 0, "limit": 10, "ctrl_env": ctrl_env}
|
|
163
|
+
response_data = make_request("POST", url, headers, payload)
|
|
170
164
|
|
|
171
|
-
|
|
172
|
-
|
|
165
|
+
# curl_cmd = output_curl(url, headers, payload)
|
|
166
|
+
# print(f"Equivalent curl:\n{curl_cmd}")
|
|
167
|
+
|
|
173
168
|
try:
|
|
174
169
|
data = response_data.get("data", {})
|
|
175
170
|
items = data.get("items", [])
|
|
@@ -181,7 +176,7 @@ class DFlowClient:
|
|
|
181
176
|
"""获取所有可用的控制环境列表,返回以domain为键,ctrl_env列表为值的字典"""
|
|
182
177
|
site_info = self.bytecloud_client.get_site_config(site)
|
|
183
178
|
url = f"{site_info.endpoint}/api/v1/bytedts/api/bytedts/v3/DescribeRegions"
|
|
184
|
-
resp_json = make_request("POST", url, self.build_request_headers(site, None), {})
|
|
179
|
+
resp_json = make_request("POST", url, self.bytecloud_client.build_request_headers(site, None), {})
|
|
185
180
|
if resp_json["code"] != 0:
|
|
186
181
|
raise Exception(resp_json["message"])
|
|
187
182
|
|
|
@@ -21,7 +21,7 @@ class DSyncerClient:
|
|
|
21
21
|
self.envs = envs
|
|
22
22
|
self.bytecloud_client = bytecloud_client
|
|
23
23
|
|
|
24
|
-
def _build_headers(self,
|
|
24
|
+
def _build_headers(self, site: str, secret_api: bool = False) -> dict[str, str]:
|
|
25
25
|
"""
|
|
26
26
|
构建请求头
|
|
27
27
|
|
|
@@ -32,11 +32,11 @@ class DSyncerClient:
|
|
|
32
32
|
Returns:
|
|
33
33
|
dict[str, str]: 请求头字典
|
|
34
34
|
"""
|
|
35
|
-
jwt_token = self.bytecloud_client.get_jwt_token(
|
|
36
|
-
headers = {"X-Jwt-Token": jwt_token
|
|
35
|
+
jwt_token = self.bytecloud_client.get_jwt_token(site)
|
|
36
|
+
headers = {"X-Jwt-Token": jwt_token}
|
|
37
37
|
|
|
38
38
|
if secret_api:
|
|
39
|
-
token = self.envs[
|
|
39
|
+
token = self.envs[site].token
|
|
40
40
|
headers["Authorization"] = f"Token {token}"
|
|
41
41
|
|
|
42
42
|
return headers
|
|
@@ -40,11 +40,11 @@ class SpaceXClient:
|
|
|
40
40
|
logger.warning(f"do quest queryServerMeta exception: {e}")
|
|
41
41
|
raise
|
|
42
42
|
|
|
43
|
-
def register_resource(self, site: str,
|
|
43
|
+
def register_resource(self, site: str, payload: dict[str, Any]) -> bool:
|
|
44
44
|
site_info = self.bytecloud_client.get_site_config(site)
|
|
45
45
|
url = f"{site_info.endpoint_bytedts_spacex}/resource/v1/registerResource"
|
|
46
46
|
try:
|
|
47
|
-
response = requests.post(url, json=
|
|
47
|
+
response = requests.post(url, json=payload, headers=self.bytecloud_client.build_request_headers(site))
|
|
48
48
|
# print(f"response status code: {response.status_code}, response text: {response.text}")
|
|
49
49
|
|
|
50
50
|
response.raise_for_status()
|
|
@@ -56,11 +56,11 @@ class SpaceXClient:
|
|
|
56
56
|
logger.warning(f"do quest registerResource exception: {e}")
|
|
57
57
|
raise
|
|
58
58
|
|
|
59
|
-
def list_resources(self, site: str,
|
|
59
|
+
def list_resources(self, site: str, payload: dict[str, Any]) -> list[str]:
|
|
60
60
|
site_info = self.bytecloud_client.get_site_config(site)
|
|
61
61
|
url = f"{site_info.endpoint_bytedts_spacex}/resource/v1/listResource"
|
|
62
62
|
try:
|
|
63
|
-
response = requests.post(url, json=
|
|
63
|
+
response = requests.post(url, json=payload, headers=self.bytecloud_client.build_request_headers(site))
|
|
64
64
|
# print(f"response status code: {response.status_code}, response text: {response.text}")
|
|
65
65
|
|
|
66
66
|
response.raise_for_status()
|
|
@@ -78,7 +78,7 @@ class SpaceXClient:
|
|
|
78
78
|
def register_gateway(self, site: str, gateway_info: GatewayInfo) -> bool:
|
|
79
79
|
site_info = self.bytecloud_client.get_site_config(site)
|
|
80
80
|
url = f"{site_info.endpoint_bytedts_spacex}/bytedts/v1/registryGateway"
|
|
81
|
-
|
|
81
|
+
payload = {
|
|
82
82
|
"region": gateway_info.mgr_name,
|
|
83
83
|
"server_region": gateway_info.mgr_name,
|
|
84
84
|
"cluster_region": gateway_info.ctrl_name,
|
|
@@ -97,7 +97,7 @@ class SpaceXClient:
|
|
|
97
97
|
"unified_tao_service": 1,
|
|
98
98
|
}
|
|
99
99
|
try:
|
|
100
|
-
response = requests.post(url, json=
|
|
100
|
+
response = requests.post(url, json=payload, headers=self.bytecloud_client.build_request_headers(site))
|
|
101
101
|
response.raise_for_status()
|
|
102
102
|
|
|
103
103
|
result = response.json()
|
|
@@ -107,11 +107,11 @@ class SpaceXClient:
|
|
|
107
107
|
logger.warning(f"do quest registryGateway exception: {e}")
|
|
108
108
|
raise
|
|
109
109
|
|
|
110
|
-
def gateway_operation(self, site: str, operation: str,
|
|
110
|
+
def gateway_operation(self, site: str, operation: str, payload: dict[str, Any]) -> dict[str, Any]:
|
|
111
111
|
site_info = self.bytecloud_client.get_site_config(site)
|
|
112
112
|
url = f"{site_info.endpoint_bytedts_spacex}/bytedts/v1/{operation}"
|
|
113
113
|
try:
|
|
114
|
-
response = requests.post(url, json=
|
|
114
|
+
response = requests.post(url, json=payload, headers=self.bytecloud_client.build_request_headers(site))
|
|
115
115
|
# print(f"response status code: {response.status_code}, response text: {response.text}")
|
|
116
116
|
|
|
117
117
|
response.raise_for_status()
|
|
@@ -27,7 +27,7 @@ class TCCInnerClient:
|
|
|
27
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
|
+
payload = {
|
|
31
31
|
"ns_name": ns_name,
|
|
32
32
|
"region": region,
|
|
33
33
|
"dir_path": dir,
|
|
@@ -40,7 +40,7 @@ class TCCInnerClient:
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
try:
|
|
43
|
-
response = requests.post(url, headers=self.bytecloud_client.build_request_headers(site), json=
|
|
43
|
+
response = requests.post(url, headers=self.bytecloud_client.build_request_headers(site), json=payload, timeout=30)
|
|
44
44
|
response.raise_for_status()
|
|
45
45
|
result = response.json()
|
|
46
46
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dts-dance"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.6"
|
|
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.
|
|
15
|
+
"boto3>=1.42.35",
|
|
16
16
|
"pyyaml>=6.0.3,<7.0.0",
|
|
17
17
|
"requests_toolbelt==1.0.0",
|
|
18
18
|
]
|
|
@@ -10,23 +10,16 @@ bytecloud_client = ByteCloudClient(site_configs)
|
|
|
10
10
|
dflow_client = DFlowClient(bytecloud_client)
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
# pytest tests/test_dflow.py::
|
|
14
|
-
def
|
|
15
|
-
info = dflow_client.get_task_info("cn", "106037095986690")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# pytest tests/test_dflow.py::test_get_task_info2 -s
|
|
20
|
-
def test_get_task_info2():
|
|
21
|
-
info = dflow_client.get_task_info("cn", "99868429582521")
|
|
22
|
-
print(f"DFlow Info: {info}")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# pytest tests/test_dflow.py::test_get_dflow_info -s
|
|
26
|
-
def test_get_dflow_info():
|
|
27
|
-
info = dflow_client.get_dflow_info("cn", "106029334786818")
|
|
13
|
+
# pytest tests/test_dflow.py::test_get_task_info -s
|
|
14
|
+
def test_get_task_info():
|
|
15
|
+
# info = dflow_client.get_task_info("cn", "106037095986690")
|
|
16
|
+
info = dflow_client.get_task_info("cn", "10457709471247")
|
|
28
17
|
print(f"DFlow Info: {info}")
|
|
29
18
|
|
|
19
|
+
# pytest tests/test_dflow.py::test_list_resources -s
|
|
20
|
+
def test_list_resources():
|
|
21
|
+
resources = dflow_client.list_resources("cn", "cn_east", vregion = "China-East")
|
|
22
|
+
print(f"list_resources: {json.dumps(resources, indent=2)}")
|
|
30
23
|
|
|
31
24
|
# pytest tests/test_dflow.py::test_get_all_ctrl_envs -s
|
|
32
25
|
def test_get_all_ctrl_envs():
|
|
@@ -4,30 +4,30 @@ requires-python = ">=3.12"
|
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "boto3"
|
|
7
|
-
version = "1.42.
|
|
7
|
+
version = "1.42.36"
|
|
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/
|
|
14
|
+
sdist = { url = "https://files.pythonhosted.org/packages/54/06/50ff808cf4f40efada8edc20f9d563ab287864423c874dfb94f755a60c52/boto3-1.42.36.tar.gz", hash = "sha256:a4eb51105c8c5d7b2bc2a9e2316e69baf69a55611275b9f189c0cf59f1aae171", size = 112839, upload-time = "2026-01-27T20:38:26.992Z" }
|
|
15
15
|
wheels = [
|
|
16
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
16
|
+
{ url = "https://files.pythonhosted.org/packages/8d/d1/35d12f04a7792e2f5e9ddff3c7b60493a32027761380dee7f24ee8ae80cc/boto3-1.42.36-py3-none-any.whl", hash = "sha256:e0ff6f2747bfdec63405b35ea185a7aea35239c3f4fe99e4d29368a6de9c4a84", size = 140604, upload-time = "2026-01-27T20:38:25.349Z" },
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
[[package]]
|
|
20
20
|
name = "botocore"
|
|
21
|
-
version = "1.42.
|
|
21
|
+
version = "1.42.36"
|
|
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/
|
|
28
|
+
sdist = { url = "https://files.pythonhosted.org/packages/66/4e/b24089cf7a77d38886ac4fbae300a3c4c6d68c1b9ccb66af03cb07b6c35c/botocore-1.42.36.tar.gz", hash = "sha256:2ebd89cc75927944e2cee51b7adce749f38e0cb269a758a6464a27f8bcca65fb", size = 14909073, upload-time = "2026-01-27T20:38:16.621Z" }
|
|
29
29
|
wheels = [
|
|
30
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
30
|
+
{ url = "https://files.pythonhosted.org/packages/e6/e8/f14d25bd768187424b385bc6a44e2ed5e96964e461ba019add03e48713c7/botocore-1.42.36-py3-none-any.whl", hash = "sha256:2cfae4c482e5e87bd835ab4289b711490c161ba57e852c06b65a03e7c25e08eb", size = 14583066, upload-time = "2026-01-27T20:38:14.02Z" },
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[[package]]
|
|
@@ -119,7 +119,7 @@ dependencies = [
|
|
|
119
119
|
|
|
120
120
|
[package.metadata]
|
|
121
121
|
requires-dist = [
|
|
122
|
-
{ name = "boto3", specifier = ">=1.42.
|
|
122
|
+
{ name = "boto3", specifier = ">=1.42.35" },
|
|
123
123
|
{ name = "loguru", specifier = ">=0.7.3,<0.8.0" },
|
|
124
124
|
{ name = "pyyaml", specifier = ">=6.0.3,<7.0.0" },
|
|
125
125
|
{ name = "requests", specifier = ">=2.32.5,<3.0.0" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|