cgcsdk 1.2.1__py3-none-any.whl → 1.2.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.
- cgc/.env +1 -1
- cgc/CHANGELOG.md +18 -0
- cgc/commands/auth/__init__.py +5 -0
- cgc/commands/auth/auth_cmd.py +2 -1
- cgc/commands/compute/billing/billing_cmd.py +11 -1
- cgc/commands/compute/billing/billing_utils.py +22 -5
- cgc/commands/compute/compute_cmd.py +23 -17
- cgc/commands/compute/compute_models.py +1 -0
- cgc/commands/compute/compute_utils.py +3 -2
- cgc/commands/db/db_cmd.py +14 -9
- cgc/commands/exceptions.py +4 -0
- cgc/sdk/resource.py +21 -17
- cgc/utils/config_utils.py +41 -24
- cgc/utils/consts/message_consts.py +1 -0
- cgc/utils/message_utils.py +5 -2
- cgc/utils/response_utils.py +4 -4
- {cgcsdk-1.2.1.dist-info → cgcsdk-1.2.3.dist-info}/METADATA +14 -2
- {cgcsdk-1.2.1.dist-info → cgcsdk-1.2.3.dist-info}/RECORD +22 -22
- {cgcsdk-1.2.1.dist-info → cgcsdk-1.2.3.dist-info}/WHEEL +1 -1
- {cgcsdk-1.2.1.dist-info → cgcsdk-1.2.3.dist-info}/entry_points.txt +0 -0
- {cgcsdk-1.2.1.dist-info → cgcsdk-1.2.3.dist-info/licenses}/LICENSE +0 -0
- {cgcsdk-1.2.1.dist-info → cgcsdk-1.2.3.dist-info}/top_level.txt +0 -0
cgc/.env
CHANGED
cgc/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 1.2.3
|
4
|
+
|
5
|
+
Release on Apr 07, 2025
|
6
|
+
|
7
|
+
* support for the `RTX6000` cards
|
8
|
+
|
9
|
+
## 1.2.2
|
10
|
+
|
11
|
+
Release on Apr 01, 2025
|
12
|
+
|
13
|
+
* updated handling of server configuration data
|
14
|
+
* update node_port logic for on-premises
|
15
|
+
* updated response message, when working with LLM api keys
|
16
|
+
* updated logic for non main CGC clusters
|
17
|
+
* updated aggregation of one-off events in billing status
|
18
|
+
* user config permissions updated to 600
|
19
|
+
* added CorruptedConfigFile exception
|
20
|
+
|
3
21
|
## 1.2.1
|
4
22
|
|
5
23
|
Release on Nov 26, 2024
|
cgc/commands/auth/__init__.py
CHANGED
@@ -13,3 +13,8 @@ class NoNamespaceInConfig(AuthCommandException):
|
|
13
13
|
class NoConfigFileFound(AuthCommandException):
|
14
14
|
def __init__(self) -> None:
|
15
15
|
super().__init__("Config does not exists.")
|
16
|
+
|
17
|
+
|
18
|
+
class CorruptedConfigFile(AuthCommandException):
|
19
|
+
def __init__(self) -> None:
|
20
|
+
super().__init__("Config file is corrupted. Please check the file format or contact support at support@comtegra.pl")
|
cgc/commands/auth/auth_cmd.py
CHANGED
@@ -156,7 +156,8 @@ def api_keys_create(
|
|
156
156
|
user_id, password, level, expires_in, overwrite, comment
|
157
157
|
)
|
158
158
|
click.echo(login_successful_response())
|
159
|
-
|
159
|
+
if level is None or level.lower() != "llm":
|
160
|
+
click.echo(f"API key: {api_key}")
|
160
161
|
click.echo(f"API secret: {secret}")
|
161
162
|
if comment:
|
162
163
|
click.echo(f"Comment: {comment}")
|
@@ -97,6 +97,7 @@ def stop_events_group():
|
|
97
97
|
"date_from",
|
98
98
|
prompt="Date from (DD-MM-YYYY)",
|
99
99
|
default=datetime.now().replace(day=1).strftime("%d-%m-%Y"),
|
100
|
+
help="Start date for filtering stop events",
|
100
101
|
)
|
101
102
|
@click.option(
|
102
103
|
"--date_to",
|
@@ -104,8 +105,12 @@ def stop_events_group():
|
|
104
105
|
"date_to",
|
105
106
|
prompt="Date to (DD-MM-YYYY)",
|
106
107
|
default=datetime.now().strftime("%d-%m-%Y"),
|
108
|
+
help="End date for filtering stop events",
|
107
109
|
)
|
108
110
|
def stop_events_resource(date_from, date_to):
|
111
|
+
"""
|
112
|
+
List resource stop events information for a given time period
|
113
|
+
"""
|
109
114
|
verify_input_datetime(date_from, date_to)
|
110
115
|
api_url, headers = get_api_url_and_prepare_headers()
|
111
116
|
url = f"{api_url}/v1/api/billing/list_resource_stop_events?time_from={date_from}&time_till={date_to}"
|
@@ -125,15 +130,20 @@ def stop_events_resource(date_from, date_to):
|
|
125
130
|
"date_from",
|
126
131
|
prompt="Date from (DD-MM-YYYY)",
|
127
132
|
default=datetime.now().replace(day=1).strftime("%d-%m-%Y"),
|
133
|
+
help="Start date for filtering stop events",
|
128
134
|
)
|
129
135
|
@click.option(
|
130
136
|
"--date_to",
|
131
137
|
"-t",
|
132
138
|
"date_to",
|
133
|
-
prompt="Date
|
139
|
+
prompt="Date to (DD-MM-YYYY)",
|
134
140
|
default=datetime.now().strftime("%d-%m-%Y"),
|
141
|
+
help="End date for filtering stop events",
|
135
142
|
)
|
136
143
|
def stop_events_volume(date_from, date_to):
|
144
|
+
"""
|
145
|
+
List volume stop events information for a given time period
|
146
|
+
"""
|
137
147
|
verify_input_datetime(date_from, date_to)
|
138
148
|
api_url, headers = get_api_url_and_prepare_headers()
|
139
149
|
url = f"{api_url}/v1/api/billing/list_storage_stop_events?time_from={date_from}&time_till={date_to}"
|
@@ -19,14 +19,15 @@ def verify_input_datetime(*args):
|
|
19
19
|
def _get_costs_list_for_user(costs_list: list):
|
20
20
|
"""Method to format data in costs list to be displayed in a table and calculate user cost
|
21
21
|
|
22
|
-
|
23
22
|
:param costs_list: list of costs for user
|
24
23
|
:type costs_list: list
|
25
24
|
:return: formatted list of costs and total cost for user
|
26
25
|
:rtype: user_costs_list_to_print: list, total_user_cost: float
|
27
26
|
"""
|
28
27
|
user_costs_list_to_print = []
|
28
|
+
oneoff_aggregated = {}
|
29
29
|
total_user_cost = 0
|
30
|
+
|
30
31
|
for cost in costs_list:
|
31
32
|
if cost["type"] == "events_resource":
|
32
33
|
resources = cost["resources"]
|
@@ -41,12 +42,28 @@ def _get_costs_list_for_user(costs_list: list):
|
|
41
42
|
f"{int(cost['rent_time_cost'])} s",
|
42
43
|
f"{float(cost['cost_total']):.2f} pln"])
|
43
44
|
elif cost["type"] == "events_oneoff":
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
product = cost["product"]
|
46
|
+
if product not in oneoff_aggregated:
|
47
|
+
oneoff_aggregated[product] = {
|
48
|
+
"quantity": 0,
|
49
|
+
"cost_total": 0
|
50
|
+
}
|
51
|
+
oneoff_aggregated[product]["quantity"] += cost["quantity"]
|
52
|
+
oneoff_aggregated[product]["cost_total"] += cost["cost_total"]
|
47
53
|
else:
|
48
54
|
user_costs_list_to_print.append(["ERROR", "", "", "", "", ""])
|
49
|
-
total_user_cost +=
|
55
|
+
total_user_cost += cost["cost_total"]
|
56
|
+
|
57
|
+
for product, data in oneoff_aggregated.items():
|
58
|
+
user_costs_list_to_print.append([
|
59
|
+
"oneoff",
|
60
|
+
product,
|
61
|
+
"-",
|
62
|
+
"-",
|
63
|
+
f"{data['quantity']:d}",
|
64
|
+
f"{data['cost_total']:.8f} pln"
|
65
|
+
])
|
66
|
+
|
50
67
|
if costs_list:
|
51
68
|
user_costs_list_to_print.sort(key=lambda d: f"{d[0]} {d[2]}")
|
52
69
|
return user_costs_list_to_print, total_user_cost
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import json
|
2
2
|
import sys
|
3
|
+
from cgc.commands.exceptions import NonOnPremisesException
|
4
|
+
from cgc.utils.message_utils import prepare_warning_message
|
3
5
|
import click
|
4
6
|
|
5
7
|
from cgc.commands.compute.compute_models import ComputesList, GPUsList
|
@@ -443,23 +445,27 @@ def compute_create(
|
|
443
445
|
elif startup_command:
|
444
446
|
cleaned_data = startup_command
|
445
447
|
metric = "compute.create"
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
448
|
+
try:
|
449
|
+
__payload = compute_create_payload(
|
450
|
+
name=name,
|
451
|
+
entity=entity,
|
452
|
+
cpu=cpu,
|
453
|
+
memory=memory,
|
454
|
+
gpu=gpu,
|
455
|
+
volumes=volumes,
|
456
|
+
volume_full_path=volume_full_path,
|
457
|
+
resource_data=resource_data,
|
458
|
+
config_maps_data=config_maps_data,
|
459
|
+
gpu_type=gpu_type,
|
460
|
+
shm_size=shm_size,
|
461
|
+
image_name=image_name,
|
462
|
+
startup_command=cleaned_data,
|
463
|
+
repository_secret=repository_secret,
|
464
|
+
node_port_enabled=node_port_enabled,
|
465
|
+
)
|
466
|
+
except NonOnPremisesException as err:
|
467
|
+
click.echo(prepare_warning_message(err))
|
468
|
+
return
|
463
469
|
# Extra keys allowed for payload:
|
464
470
|
# 1.
|
465
471
|
# template_specific_data: TemplateSpecificData
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from typing import Optional
|
2
|
+
from cgc.commands.exceptions import NonOnPremisesException
|
2
3
|
import cgc.utils.consts.env_consts as env_consts
|
3
4
|
from cgc.utils.get_headers_data import load_user_api_url
|
4
5
|
|
@@ -248,8 +249,8 @@ def compute_create_payload(
|
|
248
249
|
node_port_enabled
|
249
250
|
or "node_port_enabled" in resource_data_dict["resource_data"]
|
250
251
|
):
|
251
|
-
if env_consts.CGC_API_URL
|
252
|
-
raise
|
252
|
+
if env_consts.CGC_API_URL == load_user_api_url():
|
253
|
+
raise NonOnPremisesException(
|
253
254
|
"NodePort is supported in on-premises environments only."
|
254
255
|
)
|
255
256
|
resource_data_dict["resource_data"]["node_port_enabled"] = True
|
cgc/commands/db/db_cmd.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import json
|
2
|
+
from cgc.utils.message_utils import prepare_warning_message
|
2
3
|
import click
|
3
4
|
|
4
5
|
from cgc.commands.compute.compute_responses import compute_list_response
|
5
6
|
from cgc.commands.db.db_models import DatabasesList
|
6
7
|
from cgc.commands.compute.compute_responses import compute_create_response
|
7
8
|
from cgc.commands.compute.compute_utils import compute_create_payload
|
8
|
-
from cgc.commands.exceptions import DatabaseCreationException
|
9
|
+
from cgc.commands.exceptions import DatabaseCreationException, NonOnPremisesException
|
9
10
|
from cgc.commands.resource.resource_cmd import resource_delete
|
10
11
|
from cgc.utils.prepare_headers import get_api_url_and_prepare_headers
|
11
12
|
from cgc.utils.response_utils import retrieve_and_validate_response_send_metric
|
@@ -83,14 +84,18 @@ def db_create(
|
|
83
84
|
api_url, headers = get_api_url_and_prepare_headers()
|
84
85
|
url = f"{api_url}/v1/api/resource/create"
|
85
86
|
metric = "db.create"
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
87
|
+
try:
|
88
|
+
__payload = compute_create_payload(
|
89
|
+
name=name,
|
90
|
+
entity=entity,
|
91
|
+
cpu=cpu,
|
92
|
+
memory=memory,
|
93
|
+
volumes=volumes,
|
94
|
+
resource_data=resource_data,
|
95
|
+
)
|
96
|
+
except NonOnPremisesException as err:
|
97
|
+
click.echo(prepare_warning_message(err))
|
98
|
+
return
|
94
99
|
__res = call_api(
|
95
100
|
request=EndpointTypes.post,
|
96
101
|
url=url,
|
cgc/commands/exceptions.py
CHANGED
cgc/sdk/resource.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import json as _json
|
2
2
|
import cgc.sdk.exceptions as _exceptions
|
3
|
+
from cgc.commands.exceptions import NonOnPremisesException as _NonOnPremisesException
|
3
4
|
from cgc.utils.custom_exceptions import CUSTOM_EXCEPTIONS
|
4
5
|
import cgc.utils.prepare_headers as _prepare_headers
|
5
6
|
import cgc.commands.compute.compute_utils as _compute_utils
|
@@ -243,23 +244,26 @@ def compute_create_custom(
|
|
243
244
|
gpu_type = gpu_type.upper()
|
244
245
|
if gpu_type not in GPUsList.get_list():
|
245
246
|
raise _exceptions.SDKException(-3, f"Invalid GPU type: {gpu_type}")
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
247
|
+
try:
|
248
|
+
__payload = _compute_utils.compute_create_payload(
|
249
|
+
name=name,
|
250
|
+
entity="custom",
|
251
|
+
cpu=cpu,
|
252
|
+
memory=memory,
|
253
|
+
gpu=gpu,
|
254
|
+
gpu_type=gpu_type,
|
255
|
+
volumes=volumes,
|
256
|
+
volume_full_path=volume_full_path,
|
257
|
+
resource_data=resource_data,
|
258
|
+
config_maps_data=config_maps_data,
|
259
|
+
shm_size=shm_size,
|
260
|
+
image_name=image_name,
|
261
|
+
startup_command=startup_command,
|
262
|
+
repository_secret=repository_secret,
|
263
|
+
node_port_enabled=node_port_enabled,
|
264
|
+
)
|
265
|
+
except _NonOnPremisesException as err:
|
266
|
+
raise _exceptions.SDKException(400, err) from err
|
263
267
|
|
264
268
|
__res = _requests_helper.call_api(
|
265
269
|
request=_requests_helper.EndpointTypes.post,
|
cgc/utils/config_utils.py
CHANGED
@@ -4,7 +4,7 @@ import sys
|
|
4
4
|
from typing import Union
|
5
5
|
import click
|
6
6
|
|
7
|
-
from cgc.commands.auth import NoNamespaceInConfig, NoConfigFileFound
|
7
|
+
from cgc.commands.auth import NoNamespaceInConfig, NoConfigFileFound, CorruptedConfigFile
|
8
8
|
from cgc.utils.message_utils import prepare_error_message
|
9
9
|
from cgc.utils.consts.env_consts import CGC_API_URL, CGC_SECRET
|
10
10
|
|
@@ -51,7 +51,7 @@ def save_to_local_config_context(context_filename: str):
|
|
51
51
|
read_cfg = {}
|
52
52
|
user_config_file = os.path.join(config_path, "cgc.json")
|
53
53
|
if not os.path.isdir(config_path):
|
54
|
-
os.makedirs(config_path)
|
54
|
+
os.makedirs(config_path, mode=0o700)
|
55
55
|
try:
|
56
56
|
with open(user_config_file, "r", encoding="UTF-8") as f:
|
57
57
|
read_cfg = json.load(f)
|
@@ -60,9 +60,13 @@ def save_to_local_config_context(context_filename: str):
|
|
60
60
|
except json.decoder.JSONDecodeError:
|
61
61
|
pass
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
prev_umask = os.umask(0o077)
|
64
|
+
try:
|
65
|
+
with open(user_config_file, "w", encoding="UTF-8") as f:
|
66
|
+
final_cfg = {**read_cfg, "context_filename": context_filename}
|
67
|
+
json.dump(final_cfg, f)
|
68
|
+
finally:
|
69
|
+
os.umask(prev_umask)
|
66
70
|
|
67
71
|
|
68
72
|
def save_to_local_config(**kwargs):
|
@@ -76,7 +80,7 @@ def save_to_local_config(**kwargs):
|
|
76
80
|
read_cfg = {}
|
77
81
|
user_config_file = os.path.join(config_path, "cgc.json")
|
78
82
|
if not os.path.isdir(config_path):
|
79
|
-
os.makedirs(config_path)
|
83
|
+
os.makedirs(config_path, mode=0o700)
|
80
84
|
try:
|
81
85
|
with open(user_config_file, "r", encoding="UTF-8") as f:
|
82
86
|
read_cfg = json.load(f)
|
@@ -85,17 +89,22 @@ def save_to_local_config(**kwargs):
|
|
85
89
|
except json.decoder.JSONDecodeError:
|
86
90
|
pass
|
87
91
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
**
|
96
|
-
|
97
|
-
|
98
|
-
|
92
|
+
prev_umask = os.umask(0o077)
|
93
|
+
try:
|
94
|
+
with open(user_config_file, "w", encoding="UTF-8") as f:
|
95
|
+
cgc_api_url = read_from_cfg("cgc_api_url")
|
96
|
+
if "context_filename" in kwargs:
|
97
|
+
kwargs.pop("context_filename")
|
98
|
+
previous_server_values: dict = read_cfg.get(cgc_api_url, {})
|
99
|
+
new_server_values = {**previous_server_values, **kwargs}
|
100
|
+
previous_server_values = new_server_values
|
101
|
+
final_cfg = {
|
102
|
+
**read_cfg,
|
103
|
+
cgc_api_url: {**previous_server_values},
|
104
|
+
}
|
105
|
+
json.dump(final_cfg, f)
|
106
|
+
finally:
|
107
|
+
os.umask(prev_umask)
|
99
108
|
|
100
109
|
|
101
110
|
def save_to_config(**kwargs):
|
@@ -109,16 +118,20 @@ def save_to_config(**kwargs):
|
|
109
118
|
read_cfg = {}
|
110
119
|
user_config_file = os.path.join(config_path, get_config_file_name())
|
111
120
|
if not os.path.isdir(config_path):
|
112
|
-
os.makedirs(config_path)
|
121
|
+
os.makedirs(config_path, mode=0o700)
|
113
122
|
try:
|
114
123
|
with open(user_config_file, "r", encoding="UTF-8") as f:
|
115
124
|
read_cfg = json.load(f)
|
116
125
|
except FileNotFoundError:
|
117
126
|
pass
|
118
127
|
|
119
|
-
|
120
|
-
|
121
|
-
|
128
|
+
prev_umask = os.umask(0o077)
|
129
|
+
try:
|
130
|
+
with open(user_config_file, "w", encoding="UTF-8") as f:
|
131
|
+
final_cfg = {**read_cfg, **kwargs}
|
132
|
+
json.dump(final_cfg, f)
|
133
|
+
finally:
|
134
|
+
os.umask(prev_umask)
|
122
135
|
|
123
136
|
|
124
137
|
def is_config_file_present():
|
@@ -150,7 +163,10 @@ def read_from_local_cfg(key: str) -> Union[list, str]:
|
|
150
163
|
read_cfg: dict = json.load(f)
|
151
164
|
if key == "context_filename":
|
152
165
|
return read_cfg[key]
|
153
|
-
|
166
|
+
try:
|
167
|
+
cgc_api_url = read_from_cfg("cgc_api_url")
|
168
|
+
except (NoConfigFileFound, CorruptedConfigFile):
|
169
|
+
cgc_api_url = CGC_API_URL
|
154
170
|
if key is None:
|
155
171
|
return read_cfg[cgc_api_url]
|
156
172
|
return read_cfg[cgc_api_url][key]
|
@@ -205,8 +221,9 @@ def read_from_cfg(key: str, filename=None):
|
|
205
221
|
return CGC_SECRET
|
206
222
|
elif key == "cgc_api_url":
|
207
223
|
return CGC_API_URL
|
208
|
-
|
209
|
-
|
224
|
+
raise CorruptedConfigFile()
|
225
|
+
except json.decoder.JSONDecodeError:
|
226
|
+
raise CorruptedConfigFile()
|
210
227
|
|
211
228
|
|
212
229
|
def get_namespace() -> str:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
CONFIG_FILE_NOT_FOUND = (
|
2
2
|
"Config file not found. Please register with CGC or verify user context."
|
3
3
|
)
|
4
|
+
CONFIG_FILE_CORRUPTED = "Config file is corrupted. Please check the file format or contact support at support@comtegra.pl"
|
4
5
|
UNKNOWN_ERROR = "An unknown error occurred. Please try again or contact support at support@comtegra.pl."
|
5
6
|
TIMEOUT_ERROR = (
|
6
7
|
"Connection timed out. Try again or contact support at support@comtegra.pl"
|
cgc/utils/message_utils.py
CHANGED
@@ -5,8 +5,8 @@ from functools import wraps
|
|
5
5
|
|
6
6
|
from cgc.commands.exceptions import ResponseException
|
7
7
|
from cgc.telemetry.basic import increment_metric
|
8
|
-
from cgc.utils.consts.message_consts import UNKNOWN_ERROR, CONFIG_FILE_NOT_FOUND
|
9
|
-
from cgc.commands.auth import NoConfigFileFound
|
8
|
+
from cgc.utils.consts.message_consts import UNKNOWN_ERROR, CONFIG_FILE_NOT_FOUND, CONFIG_FILE_CORRUPTED
|
9
|
+
from cgc.commands.auth import NoConfigFileFound, CorruptedConfigFile
|
10
10
|
|
11
11
|
|
12
12
|
def prepare_error_message(message: str) -> str:
|
@@ -52,6 +52,9 @@ def key_error_decorator_for_helpers(func):
|
|
52
52
|
except NoConfigFileFound:
|
53
53
|
click.echo(prepare_warning_message(CONFIG_FILE_NOT_FOUND))
|
54
54
|
exit(1)
|
55
|
+
except CorruptedConfigFile:
|
56
|
+
click.echo(prepare_warning_message(CONFIG_FILE_CORRUPTED))
|
57
|
+
exit(1)
|
55
58
|
except (TypeError, KeyError, IndexError) as err:
|
56
59
|
print(args, "\n", kwargs)
|
57
60
|
increment_metric("client.parser", True)
|
cgc/utils/response_utils.py
CHANGED
@@ -61,8 +61,8 @@ def retrieve_and_validate_response_send_metric_for_sdk(
|
|
61
61
|
else:
|
62
62
|
try:
|
63
63
|
response_json = response.json()
|
64
|
-
if "
|
65
|
-
raise SDKException(response.status_code, response_json["
|
64
|
+
if "details" in response_json:
|
65
|
+
raise SDKException(response.status_code, response_json["details"])
|
66
66
|
else:
|
67
67
|
raise SDKException(
|
68
68
|
response.status_code,
|
@@ -118,8 +118,8 @@ def retrieve_and_validate_response_send_metric(
|
|
118
118
|
else:
|
119
119
|
try:
|
120
120
|
response_json = response.json()
|
121
|
-
if "
|
122
|
-
click.echo(prepare_error_message(response_json["
|
121
|
+
if "details" in response_json:
|
122
|
+
click.echo(prepare_error_message(response_json["details"]))
|
123
123
|
else:
|
124
124
|
click.echo(
|
125
125
|
prepare_error_message(
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: cgcsdk
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.3
|
4
4
|
Summary: CGC Core REST API client
|
5
5
|
Home-page: https://cgc.comtegra.cloud/
|
6
6
|
Author: Comtegra AI Team
|
@@ -29,6 +29,18 @@ Requires-Dist: requests
|
|
29
29
|
Requires-Dist: setuptools
|
30
30
|
Requires-Dist: colorama
|
31
31
|
Requires-Dist: psycopg2-binary
|
32
|
+
Dynamic: author
|
33
|
+
Dynamic: author-email
|
34
|
+
Dynamic: classifier
|
35
|
+
Dynamic: description
|
36
|
+
Dynamic: description-content-type
|
37
|
+
Dynamic: home-page
|
38
|
+
Dynamic: keywords
|
39
|
+
Dynamic: license
|
40
|
+
Dynamic: license-file
|
41
|
+
Dynamic: project-url
|
42
|
+
Dynamic: requires-dist
|
43
|
+
Dynamic: summary
|
32
44
|
|
33
45
|
# Comtegra GPU Cloud CLI Client
|
34
46
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
cgc/.env,sha256=
|
2
|
-
cgc/CHANGELOG.md,sha256=
|
1
|
+
cgc/.env,sha256=DGQJ-5rSh4hgtff1ZLzk32jcYrQJ5ZLqAuiiWqIUayI,209
|
2
|
+
cgc/CHANGELOG.md,sha256=zgTowQ62AVhOBtojHYfEPWzw1JtfdIULgo_Vbl2AG14,11248
|
3
3
|
cgc/__init__.py,sha256=d03Xv8Pw4ktNyUHfmicP6XfxYPXnVYLaCZPyUlg_RNQ,326
|
4
4
|
cgc/cgc.py,sha256=3I_Ef0ggX9caaJKJkhfGYSe8XwkHzSWxwGAClMHDnUs,1663
|
5
5
|
cgc/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -8,23 +8,23 @@ cgc/commands/cgc_cmd.py,sha256=xuRoMtO7VG0sZbOFrEGxPWRg94SBrgyRJDQif4el7UM,5031
|
|
8
8
|
cgc/commands/cgc_cmd_responses.py,sha256=k8_rTAb9Ambnupg3NqCa7Te375D2YdeSVyhqz8xJg-Y,3647
|
9
9
|
cgc/commands/cgc_helpers.py,sha256=-RduMrEDknGx-bxLRUX413JY9nuqWxBIGcwbwWrnDb4,1516
|
10
10
|
cgc/commands/cgc_models.py,sha256=ThYrflL6gfiu3u3cWCbiisY7vfkKbo9JGqd5Jqr2jXc,352
|
11
|
-
cgc/commands/exceptions.py,sha256=
|
12
|
-
cgc/commands/auth/__init__.py,sha256=
|
13
|
-
cgc/commands/auth/auth_cmd.py,sha256=
|
11
|
+
cgc/commands/exceptions.py,sha256=4qbjILcfqwAy9ynCyTSdDgLQ04M-GAYHxCmI61165TU,215
|
12
|
+
cgc/commands/auth/__init__.py,sha256=HRr3dYrNgM8V_DKx-PuLljkaKFoKtaSsJZre1R2ziDg,605
|
13
|
+
cgc/commands/auth/auth_cmd.py,sha256=FmFnqGR97BpbTxyUrzfI2ehLIxIMCK_SdswMp60AhMc,5134
|
14
14
|
cgc/commands/auth/auth_logic.py,sha256=2XSVbPdxcHbWSQKUHgwz8JPw11_hiyDJFFTkYOAjIC4,2751
|
15
15
|
cgc/commands/auth/auth_responses.py,sha256=OlhZnE5yvS1EPmkVfOeCg7wBq5ayW7o_fAzN0OCAfgY,2109
|
16
16
|
cgc/commands/auth/auth_utils.py,sha256=3RSBAR_V5DANhJ_R0cN4poP2uCNdx2tU1VXxP17yXig,3605
|
17
17
|
cgc/commands/compute/__init__.py,sha256=lCdLfZ0ECSHtXEUSwq5YRHH85yXHchSsz8ZJvmClPtI,239
|
18
|
-
cgc/commands/compute/compute_cmd.py,sha256=
|
19
|
-
cgc/commands/compute/compute_models.py,sha256=
|
18
|
+
cgc/commands/compute/compute_cmd.py,sha256=1i4B_tXjSBtRNDnimgilz4a6BacZTHjFnMsf9EUodOU,16433
|
19
|
+
cgc/commands/compute/compute_models.py,sha256=5do3kSrzoZSDX1ElSZMmmW3AI9A1oeOGtrjQYePf4O0,884
|
20
20
|
cgc/commands/compute/compute_responses.py,sha256=X1ExOKDIxSFZbBRbWyfWSCeRAe3_cFGa3jOgq6CfjHw,6439
|
21
|
-
cgc/commands/compute/compute_utils.py,sha256=
|
21
|
+
cgc/commands/compute/compute_utils.py,sha256=wtSgzaoqvvwfR2dHvt8Eup0LH8Fm8pec4Hf52rU_TvI,9734
|
22
22
|
cgc/commands/compute/billing/__init__.py,sha256=ccjz-AzBCROjuR11qZRM4_62slI9ErmLi27xPUoRPHM,752
|
23
|
-
cgc/commands/compute/billing/billing_cmd.py,sha256=
|
23
|
+
cgc/commands/compute/billing/billing_cmd.py,sha256=cUOPQyf5d-vfUVMoetdBxoJx1dqxeQfyke5v-QP88wM,4508
|
24
24
|
cgc/commands/compute/billing/billing_responses.py,sha256=5vQSR_d41uizengzfXlHXL7XivO_73PpWdKmoUgqYNw,1965
|
25
|
-
cgc/commands/compute/billing/billing_utils.py,sha256=
|
25
|
+
cgc/commands/compute/billing/billing_utils.py,sha256=wIiDm7n4bOuKLO4-kLy0AnpPk9G_T14Y5DiFcXOtNrI,5553
|
26
26
|
cgc/commands/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
-
cgc/commands/db/db_cmd.py,sha256=
|
27
|
+
cgc/commands/db/db_cmd.py,sha256=iXwJzWu4xiaUIfyKSixpnK7-GtoplvfbUN8HHly1YAY,3981
|
28
28
|
cgc/commands/db/db_models.py,sha256=zpMcrDBanLx7YQJ_-PWrQCbh3B-C0qWn1Pt5SnDwsh0,1351
|
29
29
|
cgc/commands/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
30
|
cgc/commands/debug/debug_cmd.py,sha256=kuAuh5YOqzGFjoiYZwfM9FJ1z5OeSpC0JAIUEzS83lM,412
|
@@ -54,7 +54,7 @@ cgc/sdk/__init__.py,sha256=m8uAD2e_ADbHC4_kaOpLrUk_bHy7wC56rPjhcttclCs,177
|
|
54
54
|
cgc/sdk/exceptions.py,sha256=99XIzDO6LYKjex715troH-MkGUN7hi2Bit4KHfSHDis,214
|
55
55
|
cgc/sdk/job.py,sha256=q9Vsarc3rKzurM4AOmbQDsQUVdyRqx0UzJVe_uO8xCU,5318
|
56
56
|
cgc/sdk/postgresql.py,sha256=ziXaMMwjSF3k1OAID3F9npqWVxreQaoZ8wn7X8x1FZw,1637
|
57
|
-
cgc/sdk/resource.py,sha256=
|
57
|
+
cgc/sdk/resource.py,sha256=dEUdXIWGGJC4VmfzxAaxK_NPE-YUmUZs1mOhIwlKeVk,13801
|
58
58
|
cgc/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
59
|
cgc/telemetry/basic.py,sha256=h0f2yAanaflkEnetLjQvs_IR43KL0JmhJ30yrl6tOas,3174
|
60
60
|
cgc/tests/__init__.py,sha256=8aI3MVpkzaj0_UX02kZCtY5vmGO0rnq0mw2H04-OHf8,102743
|
@@ -69,25 +69,25 @@ cgc/tests/desired_responses/test_tabulate_response.txt,sha256=beNyCTS9fwrHn4ueEO
|
|
69
69
|
cgc/tests/desired_responses/test_volume_list.txt,sha256=vYB1p50BBHD801q7LUdDc_aca4ezQ8CFLWw7I-b4Uao,309
|
70
70
|
cgc/utils/__init__.py,sha256=JOvbqyGdFtswXE1TntOqM7XuIg5-t042WzAzvmX7Xtk,3661
|
71
71
|
cgc/utils/click_group.py,sha256=Scfw8eMIyt2dE1ezUq2JuiI-E_LklqXQXJEr7L-EG6A,633
|
72
|
-
cgc/utils/config_utils.py,sha256=
|
72
|
+
cgc/utils/config_utils.py,sha256=rbiA2ZNP2SslJ7zA-my7SB0ZLILBMxGjnzP1JhhGc2g,7525
|
73
73
|
cgc/utils/custom_exceptions.py,sha256=qvHdzaunZswZgN96iOHZIfLjehlJ79mcjqoMoW-tqEM,2628
|
74
74
|
cgc/utils/get_headers_data.py,sha256=JdEg5vrAHcWfsSJ7poYk3sNIY10OxX7YGVcmua-37lY,413
|
75
|
-
cgc/utils/message_utils.py,sha256=
|
75
|
+
cgc/utils/message_utils.py,sha256=Lg9G86MRKhQyl1Ito38clGBK-REfgp5fT5aeMqSfhW4,1961
|
76
76
|
cgc/utils/prepare_headers.py,sha256=Hi3WNqtqydW56tNTLZmpfMTpu4aKCoDrLx4OcCGH9_U,2656
|
77
77
|
cgc/utils/requests_helper.py,sha256=Z89dTOTbSSi1xmtNPmAdJpduR9-DC12WEQsHYeuM9a0,2046
|
78
|
-
cgc/utils/response_utils.py,sha256=
|
78
|
+
cgc/utils/response_utils.py,sha256=C0we250lDVxpadtMlx7vUQj0u_gff0zieuVqeuqS2x8,7378
|
79
79
|
cgc/utils/update.py,sha256=AsQwhcBqsjgNPKn6AN6ojt0Ew5otvJXyshys6bjr7DQ,413
|
80
80
|
cgc/utils/version_control.py,sha256=rnHeo8_y-8HJfEKLqpiMM26QR8b-CAl3zfgcv0a3y8I,4163
|
81
81
|
cgc/utils/consts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
82
82
|
cgc/utils/consts/env_consts.py,sha256=_yHjhXDBwYfLfUWfHOPlhGdzC0j9VFlkjKuSrvblBsU,1154
|
83
|
-
cgc/utils/consts/message_consts.py,sha256=
|
83
|
+
cgc/utils/consts/message_consts.py,sha256=KMajQ5yGxQ45ZPTWVLQj9ajy1KbMeCkHvSW-871A1rs,1355
|
84
84
|
cgc/utils/cryptography/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
85
85
|
cgc/utils/cryptography/aes_crypto.py,sha256=S0rKg38oy7rM5lTrP6DDpjLA-XRxuZggAXyxMFHtyzY,3333
|
86
86
|
cgc/utils/cryptography/encryption_module.py,sha256=rbblBBorHYPGl-iKblyZX3_NuPEvUTpnH1l_RgNGCbA,1958
|
87
87
|
cgc/utils/cryptography/rsa_crypto.py,sha256=h3jU5qPpj9uVjP1rTqZJTdYB5yjhD9HZpr_nD439h9Q,4180
|
88
|
-
cgcsdk-1.2.
|
89
|
-
cgcsdk-1.2.
|
90
|
-
cgcsdk-1.2.
|
91
|
-
cgcsdk-1.2.
|
92
|
-
cgcsdk-1.2.
|
93
|
-
cgcsdk-1.2.
|
88
|
+
cgcsdk-1.2.3.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
89
|
+
cgcsdk-1.2.3.dist-info/METADATA,sha256=404GwJu0VdpBlAVE29KonRWOCLR3i9JZ4oTS6pSDiQY,3247
|
90
|
+
cgcsdk-1.2.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
91
|
+
cgcsdk-1.2.3.dist-info/entry_points.txt,sha256=bdfIHeJ6Y-BBr5yupCVoK7SUrJj1yNdew8OtIOg_3No,36
|
92
|
+
cgcsdk-1.2.3.dist-info/top_level.txt,sha256=nqW9tqcIcCXFigQT69AuOk7XHKc4pCuv4HGJQGXb6iA,12
|
93
|
+
cgcsdk-1.2.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|