cgcsdk 0.7.1__py3-none-any.whl → 0.8.0__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 CHANGED
@@ -6,5 +6,5 @@ API_PORT=21919
6
6
  CONFIG_FILE_NAME = cfg.json
7
7
  TMP_DIR = .tmp
8
8
  RELEASE = 0
9
- MAJOR_VERSION = 7
10
- MINOR_VERSION = 1
9
+ MAJOR_VERSION = 8
10
+ MINOR_VERSION = 0
cgc/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.8.0
4
+
5
+ Release on Apr 14, 2023.
6
+
7
+ * cgc db - new commands for managing databases
8
+ * cgc compute - refactor commands for compute template management
9
+ * cgc resource - new command to control db and compute resources
10
+
3
11
  ## 0.7.1
4
12
 
5
13
  Released on Mar 23, 2023.
cgc/__init__.py CHANGED
@@ -7,3 +7,10 @@ from cgc.utils.version_control import get_version
7
7
  __version__ = get_version()
8
8
  __author__ = "Adrian Jastrzębski <a.jastrzebski@quantdevlabs.com>, Przemysław Kowalski <przemyslaw.kowalski@comtegra.pl>, Jakub Zboina <jakub.zboina@comtegra.pl>"
9
9
  __credits__ = "Quantum Dev Labs"
10
+
11
+
12
+ # from cgc.utils.asdasd import asdasdasd as asdasdasdasdasdMongo
13
+
14
+ # import cgc
15
+
16
+ # cgc.asdasdasdasdasdMongo()
cgc/cgc.py CHANGED
@@ -2,6 +2,8 @@ import click
2
2
  from cgc.commands.volume.volume_cmd import volume_group
3
3
  from cgc.commands.compute.compute_cmd import compute_group
4
4
  from cgc.commands.billing.billing_cmd import billing_group
5
+ from cgc.commands.db.db_cmd import db_group
6
+ from cgc.commands.resource.resource_cmd import resource_group
5
7
  from cgc.commands.auth.auth_cmd import (
6
8
  api_keys_group,
7
9
  auth_register,
@@ -23,6 +25,8 @@ cli.add_command(auth_register)
23
25
  cli.add_command(api_keys_group)
24
26
  cli.add_command(volume_group)
25
27
  cli.add_command(compute_group)
28
+ cli.add_command(db_group)
29
+ cli.add_command(resource_group)
26
30
  cli.add_command(billing_group)
27
31
  cli.add_command(cgc_rm)
28
32
  cli.add_command(cgc_status)
@@ -13,7 +13,6 @@ from cgc.utils.cryptography import rsa_crypto
13
13
  from cgc.utils.click_group import CustomCommand, CustomGroup
14
14
  from cgc.utils.requests_helper import call_api, EndpointTypes
15
15
  from cgc.utils.response_utils import retrieve_and_validate_response_send_metric
16
- from cgc.telemetry.basic import telemetry_permission_set
17
16
 
18
17
 
19
18
  @click.group("api-keys", cls=CustomGroup)
@@ -20,6 +20,6 @@ class NoVolumeStopEvents(BillingCommandException):
20
20
  super().__init__("No volume stop events to list.")
21
21
 
22
22
 
23
- class NoComputeStopEvents(BillingCommandException):
23
+ class NoResourceStopEvents(BillingCommandException):
24
24
  def __init__(self) -> None:
25
- super().__init__("No compute stop events to list.")
25
+ super().__init__("No resource stop events to list.")
@@ -4,7 +4,7 @@ from cgc.commands.billing.billing_utils import verify_input_datetime
4
4
  from cgc.commands.billing.billing_responses import (
5
5
  billing_status_response,
6
6
  billing_invoice_response,
7
- stop_events_compute_response,
7
+ stop_events_resource_response,
8
8
  stop_events_volume_response,
9
9
  )
10
10
  from cgc.utils.prepare_headers import get_api_url_and_prepare_headers
@@ -66,17 +66,17 @@ def stop_events_group():
66
66
  pass
67
67
 
68
68
 
69
- @stop_events_group.command("compute")
69
+ @stop_events_group.command("resource")
70
70
  @click.option("--date_from", "-f", "date_from", prompt="Date from (DD-MM-YYYY)")
71
71
  @click.option("--date_to", "-t", "date_to", prompt="Date to (DD-MM-YYYY)")
72
- def stop_events_compute(date_from, date_to):
72
+ def stop_events_resource(date_from, date_to):
73
73
  verify_input_datetime(date_from, date_to)
74
74
  api_url, headers = get_api_url_and_prepare_headers()
75
- url = f"{api_url}/v1/api/billing/list_compute_stop_events?time_from={date_from}&time_till={date_to}"
76
- metric = "billing.stop_events.compute"
75
+ url = f"{api_url}/v1/api/billing/list_resource_stop_events?time_from={date_from}&time_till={date_to}"
76
+ metric = "billing.stop_events.resource"
77
77
  __res = call_api(request=EndpointTypes.get, url=url, headers=headers)
78
78
  click.echo(
79
- stop_events_compute_response(
79
+ stop_events_resource_response(
80
80
  retrieve_and_validate_response_send_metric(__res, metric)
81
81
  )
82
82
  )
@@ -2,7 +2,7 @@ import calendar
2
2
  from cgc.commands.billing import (
3
3
  NoCostsFound,
4
4
  NoInvoiceFoundForSelectedMonth,
5
- NoComputeStopEvents,
5
+ NoResourceStopEvents,
6
6
  NoVolumeStopEvents,
7
7
  )
8
8
  from cgc.commands.billing.billing_utils import (
@@ -40,10 +40,10 @@ def billing_invoice_response(year: int, month: int, data: dict) -> str:
40
40
 
41
41
 
42
42
  @key_error_decorator_for_helpers
43
- def stop_events_compute_response(data: dict) -> str:
43
+ def stop_events_resource_response(data: dict) -> str:
44
44
  event_list = data["details"]["event_list"]
45
45
  if not event_list:
46
- raise NoComputeStopEvents()
46
+ raise NoResourceStopEvents()
47
47
  return get_table_compute_stop_events_message(event_list)
48
48
 
49
49
 
@@ -35,7 +35,7 @@ def _get_costs_list_for_user(costs_list: list):
35
35
  resources = cost["resources"]
36
36
  name = resources["name"]
37
37
  rent_type = cost["type"]
38
- if rent_type == "events_compute":
38
+ if rent_type == "events_resource":
39
39
  entity = resources["entity"]
40
40
  elif rent_type == "events_volume":
41
41
  entity = "volume"
cgc/commands/cgc_cmd.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import click
2
2
  from cgc.commands.cgc_cmd_responses import cgc_status_response
3
- from cgc.commands.compute.compute_cmd import compute_delete
3
+ from cgc.commands.resource.resource_cmd import resource_delete
4
4
  from cgc.utils.requests_helper import call_api, EndpointTypes
5
5
  from cgc.utils.click_group import CustomCommand
6
6
  from cgc.utils.prepare_headers import get_api_url_and_prepare_headers
@@ -14,15 +14,15 @@ def cgc_rm(name: str):
14
14
  """
15
15
  Delete an app in user namespace
16
16
  """
17
- compute_delete(name)
17
+ resource_delete(name)
18
18
 
19
19
 
20
20
  @click.command("status", cls=CustomCommand)
21
21
  def cgc_status():
22
22
  """Lists available and used resources"""
23
23
  api_url, headers = get_api_url_and_prepare_headers()
24
- url = f"{api_url}/v1/api/compute/status"
25
- metric = "compute.status"
24
+ url = f"{api_url}/v1/api/resource/status"
25
+ metric = "resource.status"
26
26
  __res = call_api(
27
27
  request=EndpointTypes.get,
28
28
  url=url,
@@ -21,12 +21,11 @@ def cgc_status_response(data: dict):
21
21
  "GPU",
22
22
  "-",
23
23
  "-",
24
- "-",
24
+ # "-",
25
25
  "Volume",
26
26
  "Storage",
27
27
  "-",
28
28
  "-",
29
- "-",
30
29
  ]
31
30
  types = [
32
31
  "",
@@ -37,9 +36,8 @@ def cgc_status_response(data: dict):
37
36
  # "V100",
38
37
  "Count",
39
38
  "",
40
- "cpu-nvme",
41
- "cpu-ssd",
42
- "gpu-nvme",
39
+ "nvme",
40
+ "ssd",
43
41
  ]
44
42
  resource_keys = [
45
43
  "limits.cpu",
@@ -50,9 +48,8 @@ def cgc_status_response(data: dict):
50
48
  # "comtegra.cloud/v100",
51
49
  "persistentvolumeclaims",
52
50
  "requests.storage",
53
- "compute-nvme-rwx.storageclass.storage.k8s.io/requests.storage",
54
- "compute-ssd-rwx.storageclass.storage.k8s.io/requests.storage",
55
- "gpu-nvme-rwx.storageclass.storage.k8s.io/requests.storage",
51
+ "nvme-rwx.storageclass.storage.k8s.io/requests.storage",
52
+ "ssd-rwx.storageclass.storage.k8s.io/requests.storage",
56
53
  ]
57
54
 
58
55
  resources_available_list = []
@@ -61,8 +58,8 @@ def cgc_status_response(data: dict):
61
58
  available = resources_available[key]
62
59
  limit = resources_limits[key]
63
60
  if "storage" in key or "memory" in key:
64
- available = f"{available} GiB"
65
- limit = f"{limit} GiB"
61
+ available = f"{available} Gb"
62
+ limit = f"{limit} Gb"
66
63
  else:
67
64
  available = int(available)
68
65
  limit = int(limit)
@@ -5,20 +5,13 @@ from cgc.commands.compute.compute_models import EntityList, GPUsList
5
5
  from cgc.commands.compute.compute_responses import (
6
6
  compute_create_filebrowser_response,
7
7
  compute_create_response,
8
- compute_delete_response,
9
- compute_restart_response,
10
- compute_list_response,
11
- template_list_response,
12
- template_get_start_path_response,
13
- )
14
- from cgc.commands.compute.compute_utills import (
15
- compute_create_payload,
16
- compute_delete_payload,
17
8
  )
9
+ from cgc.commands.compute.compute_utills import compute_create_payload
18
10
  from cgc.utils.prepare_headers import get_api_url_and_prepare_headers
19
11
  from cgc.utils.response_utils import retrieve_and_validate_response_send_metric
20
12
  from cgc.utils.click_group import CustomGroup, CustomCommand
21
13
  from cgc.utils.requests_helper import call_api, EndpointTypes
14
+ from cgc.commands.resource.resource_cmd import resource_delete
22
15
 
23
16
 
24
17
  @click.group(name="compute", cls=CustomGroup)
@@ -32,42 +25,6 @@ def compute_group(ctx, debug):
32
25
  ctx.obj["DEBUG"] = debug
33
26
 
34
27
 
35
- @click.group(name="template", cls=CustomGroup)
36
- def template_group():
37
- """
38
- Management of templates.
39
- """
40
-
41
-
42
- @template_group.command("list", cls=CustomCommand)
43
- def template_list():
44
- """Lists all available templates"""
45
- api_url, headers = get_api_url_and_prepare_headers()
46
- url = f"{api_url}/v1/api/compute/list_available_templates"
47
- metric = "compute.template.list"
48
- __res = call_api(request=EndpointTypes.get, url=url, headers=headers)
49
- click.echo(
50
- template_list_response(
51
- retrieve_and_validate_response_send_metric(__res, metric)
52
- )
53
- )
54
-
55
-
56
- @template_group.command("get_start_path", cls=CustomCommand)
57
- @click.argument("template", type=click.Choice(EntityList.get_list()))
58
- def template_get_start_path(template: str):
59
- """Displays start path of specified template"""
60
- api_url, headers = get_api_url_and_prepare_headers()
61
- url = f"{api_url}/v1/api/compute/get_template_start_path?template_name={template}"
62
- metric = "compute.template.get_start_path"
63
- __res = call_api(request=EndpointTypes.get, url=url, headers=headers)
64
- click.echo(
65
- template_get_start_path_response(
66
- retrieve_and_validate_response_send_metric(__res, metric)
67
- )
68
- )
69
-
70
-
71
28
  @click.group(name="filebrowser", cls=CustomGroup)
72
29
  def filebrowser_group():
73
30
  """
@@ -79,7 +36,7 @@ def filebrowser_group():
79
36
  def compute_filebrowser_create():
80
37
  """Create a filebrowser service"""
81
38
  api_url, headers = get_api_url_and_prepare_headers()
82
- url = f"{api_url}/v1/api/compute/filebrowser_create"
39
+ url = f"{api_url}/v1/api/resource/filebrowser_create"
83
40
  metric = "compute.create_filebrowser"
84
41
  __payload = {"puid": 0, "pgid": 0}
85
42
  __res = call_api(
@@ -98,7 +55,7 @@ def compute_filebrowser_create():
98
55
  @filebrowser_group.command("delete", cls=CustomCommand)
99
56
  def compute_filebrowser_delete():
100
57
  """Delete a filebrowser service"""
101
- compute_delete("filebrowser")
58
+ resource_delete("filebrowser")
102
59
 
103
60
 
104
61
  @compute_group.command("create", cls=CustomCommand)
@@ -169,7 +126,7 @@ def compute_create(
169
126
  :type name: str
170
127
  """
171
128
  api_url, headers = get_api_url_and_prepare_headers()
172
- url = f"{api_url}/v1/api/compute/create"
129
+ url = f"{api_url}/v1/api/resource/create"
173
130
  metric = "compute.create"
174
131
  __payload = compute_create_payload(
175
132
  name=name,
@@ -202,78 +159,7 @@ def compute_delete_cmd(name: str):
202
159
  :param name: name of app to delete
203
160
  :type name: str
204
161
  """
205
- compute_delete(name)
206
-
207
-
208
- def compute_delete(name: str):
209
- """
210
- Delete an app using backend endpoint.
211
- \f
212
- :param name: name of app to delete
213
- :type name: str
214
- """
215
- api_url, headers = get_api_url_and_prepare_headers()
216
- url = f"{api_url}/v1/api/compute/delete"
217
- metric = "compute.delete"
218
- __payload = compute_delete_payload(name=name)
219
- __res = call_api(
220
- request=EndpointTypes.delete,
221
- url=url,
222
- headers=headers,
223
- data=json.dumps(__payload),
224
- )
225
- click.echo(
226
- compute_delete_response(
227
- retrieve_and_validate_response_send_metric(__res, metric)
228
- )
229
- )
230
-
231
-
232
- @compute_group.command("list", cls=CustomCommand)
233
- @click.option(
234
- "-d", "--detailed", "detailed", type=click.BOOL, is_flag=True, default=False
235
- )
236
- @click.pass_context
237
- def compute_list(ctx, detailed):
238
- """
239
- List all apps for user namespace.
240
- """
241
- api_url, headers = get_api_url_and_prepare_headers()
242
- url = f"{api_url}/v1/api/compute/list"
243
- metric = "compute.list"
244
- __res = call_api(
245
- request=EndpointTypes.get,
246
- url=url,
247
- headers=headers,
248
- )
249
- table = compute_list_response(
250
- detailed,
251
- retrieve_and_validate_response_send_metric(__res, metric),
252
- )
253
-
254
- click.echo(table)
255
-
256
-
257
- @compute_group.command("restart", cls=CustomCommand)
258
- @click.argument("name", type=click.STRING)
259
- def compute_restart(name: str):
260
- """Restarts the specified app"""
261
- api_url, headers = get_api_url_and_prepare_headers()
262
- url = f"{api_url}/v1/api/compute/restart"
263
- metric = "compute.restart"
264
- __payload = {"name": name}
265
- __res = call_api(
266
- request=EndpointTypes.post,
267
- url=url,
268
- headers=headers,
269
- data=json.dumps(__payload),
270
- )
271
- click.echo(
272
- compute_restart_response(
273
- retrieve_and_validate_response_send_metric(__res, metric)
274
- )
275
- )
162
+ resource_delete(name)
276
163
 
277
164
 
278
165
  compute_group.add_command(filebrowser_group)
279
- compute_group.add_command(template_group)
@@ -1,7 +1,15 @@
1
1
  from enum import Enum
2
2
 
3
3
 
4
- class EntityList(Enum):
4
+ class CGCEntityList(Enum):
5
+ """Base class for other lists"""
6
+
7
+ @classmethod
8
+ def get_list(cls) -> list[str]:
9
+ return [el.value for el in cls]
10
+
11
+
12
+ class EntityList(CGCEntityList):
5
13
  """List of templates in cgc-server
6
14
 
7
15
  :param Enum: name of template
@@ -13,12 +21,20 @@ class EntityList(Enum):
13
21
  NVIDIA_PYTORCH = "nvidia-pytorch"
14
22
  NVIDIA_TRITON = "nvidia-triton"
15
23
 
16
- @classmethod
17
- def get_list(cls) -> list[str]:
18
- return [el.value for el in cls]
19
24
 
25
+ class DatabasesList(CGCEntityList):
26
+ """List of templates in cgc-server
27
+
28
+ :param Enum: name of template
29
+ :type Enum: str
30
+ """
31
+
32
+ MONGODB = "mongodb"
33
+ POSTGRESQL = "postgresql"
34
+ REDIS = "redis"
20
35
 
21
- class GPUsList(Enum):
36
+
37
+ class GPUsList(CGCEntityList):
22
38
  """List of templates in cgc-server
23
39
 
24
40
  :param Enum: name of template
@@ -28,7 +44,3 @@ class GPUsList(Enum):
28
44
  A100 = "A100"
29
45
  # V100 = "V100"
30
46
  A5000 = "A5000"
31
-
32
- @classmethod
33
- def get_list(cls) -> list[str]:
34
- return [el.value for el in cls]
@@ -89,13 +89,18 @@ def compute_create_response(data: dict) -> str:
89
89
  app_token = data["details"]["created_template"]["app_token"]
90
90
  except KeyError:
91
91
  app_token = None
92
- app_url = data["details"]["created_template"]["pod_url"]
93
92
 
94
93
  message = f"{entity} app {name} creation started!\n"
95
94
  if volumes:
96
95
  message += f" Volumes to mount: {volumes}\n"
97
96
  message += f"Container will be Ready after volumes can be see mounted.\n"
98
- message += f"Will be accessible at: {app_url}\nApp token: {app_token}\nTo monitor the startup status use command: cgc compute list"
97
+
98
+ app_url = data["details"]["created_template"]["pod_url"]
99
+ if app_url == "None":
100
+ message += f"Will be accessible at: {app_url}\n"
101
+ else:
102
+ message += "This app is not exposed via HTTPS\n"
103
+ message += f"App token: {app_token}\nTo monitor the startup status use command: cgc resource list"
99
104
 
100
105
  return message
101
106
 
@@ -126,3 +131,25 @@ def compute_restart_response(data: dict) -> str:
126
131
 
127
132
  name = data["details"]["template_name"]
128
133
  return f"App {name} has been successfully restarted."
134
+
135
+
136
+ @key_error_decorator_for_helpers
137
+ def compute_logs_response(data: dict) -> str:
138
+ """prepare logs to print
139
+
140
+ :param data: _description_
141
+ :type data: dict
142
+ :return: _description_
143
+ :rtype: str
144
+ """
145
+ # converting dict o list
146
+ logs_list = []
147
+ for event in data["details"]["pod_event_list"]:
148
+ row = []
149
+ for key, value in event.items():
150
+ row.append((key, value))
151
+ logs_list.append(row)
152
+ if len(logs_list) > 0:
153
+ return tabulate_a_response(logs_list)
154
+ else:
155
+ return "No events to list for this app"
@@ -76,7 +76,7 @@ def get_app_list(pod_list: list, detailed: bool) -> list:
76
76
 
77
77
 
78
78
  def compute_create_payload(
79
- name, entity, cpu, memory, volumes: list, gpu: int, gpu_type: str
79
+ name, entity, cpu, memory, volumes: list, gpu: int = 0, gpu_type: str = None
80
80
  ):
81
81
  """
82
82
  Create payload for app creation.
@@ -90,8 +90,11 @@ def compute_create_payload(
90
90
  "memory": memory,
91
91
  "gpu_type": gpu_type,
92
92
  }
93
- if len(volumes) != 0:
94
- payload["pv_volume"] = volumes
93
+ try:
94
+ if len(volumes) != 0:
95
+ payload["pv_volume"] = volumes
96
+ except TypeError:
97
+ pass
95
98
  return payload
96
99
 
97
100
 
@@ -0,0 +1,100 @@
1
+ import json
2
+ import click
3
+
4
+ from cgc.commands.compute.compute_models import DatabasesList
5
+ from cgc.commands.compute.compute_responses import compute_create_response
6
+ from cgc.commands.compute.compute_utills import compute_create_payload
7
+ from cgc.commands.resource.resource_cmd import resource_delete
8
+ from cgc.utils.prepare_headers import get_api_url_and_prepare_headers
9
+ from cgc.utils.response_utils import retrieve_and_validate_response_send_metric
10
+ from cgc.utils.click_group import CustomGroup, CustomCommand
11
+ from cgc.utils.requests_helper import call_api, EndpointTypes
12
+
13
+
14
+ @click.group(name="db", cls=CustomGroup)
15
+ def db_group():
16
+ """
17
+ Management of db resources.
18
+ """
19
+
20
+
21
+ @db_group.command("create", cls=CustomCommand)
22
+ @click.argument("entity", type=click.Choice(DatabasesList.get_list()))
23
+ @click.option("-n", "--name", "name", type=click.STRING, required=True)
24
+ @click.option(
25
+ "-c",
26
+ "--cpu",
27
+ "cpu",
28
+ type=click.INT,
29
+ default=1,
30
+ help="How much CPU cores app can use",
31
+ )
32
+ @click.option(
33
+ "-m",
34
+ "--memory",
35
+ "memory",
36
+ type=click.INT,
37
+ default=2,
38
+ help="How much Gi RAM app can use",
39
+ )
40
+ @click.option(
41
+ "-v",
42
+ "--volume",
43
+ "volumes",
44
+ multiple=False,
45
+ help="Volume name to be mounted with default mount path",
46
+ )
47
+ def db_create(
48
+ entity: str,
49
+ cpu: int,
50
+ memory: int,
51
+ volumes: list[str],
52
+ name: str,
53
+ ):
54
+ """
55
+ Create an app in user namespace.
56
+ \f
57
+ :param entity: name of entity to create
58
+ :type entity: str
59
+ :param cpu: number of cores to be used by app
60
+ :type cpu: int
61
+ :param memory: GB of memory to be used by app
62
+ :type memory: int
63
+ :param volumes: list of volumes to mount
64
+ :type volumes: list[str]
65
+ :param name: name of app
66
+ :type name: str
67
+ """
68
+ api_url, headers = get_api_url_and_prepare_headers()
69
+ url = f"{api_url}/v1/api/resource/create"
70
+ metric = "db.create"
71
+ __payload = compute_create_payload(
72
+ name=name,
73
+ entity=entity,
74
+ cpu=cpu,
75
+ memory=memory,
76
+ volumes=volumes,
77
+ )
78
+ __res = call_api(
79
+ request=EndpointTypes.post,
80
+ url=url,
81
+ headers=headers,
82
+ data=json.dumps(__payload),
83
+ )
84
+ click.echo(
85
+ compute_create_response(
86
+ retrieve_and_validate_response_send_metric(__res, metric)
87
+ )
88
+ )
89
+
90
+
91
+ @db_group.command("delete", cls=CustomCommand)
92
+ @click.argument("name", type=click.STRING)
93
+ def db_delete_cmd(name: str):
94
+ """
95
+ Delete an app from user namespace.
96
+ \f
97
+ :param name: name of app to delete
98
+ :type name: str
99
+ """
100
+ resource_delete(name)
@@ -5,7 +5,7 @@ from cgc.commands.auth.auth_utils import (
5
5
  from cgc.utils.click_group import CustomCommand, CustomGroup
6
6
 
7
7
 
8
- @click.group("debug", cls=CustomGroup)
8
+ @click.group("debug", cls=CustomGroup, hidden=True)
9
9
  def debug_group():
10
10
  """
11
11
  Debug commands for testing.
File without changes