cgcsdk 1.0.6__py3-none-any.whl → 1.0.9__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.
Files changed (45) hide show
  1. cgc/.env +1 -1
  2. cgc/CHANGELOG.md +30 -0
  3. cgc/cgc.py +7 -1
  4. cgc/commands/auth/__init__.py +2 -2
  5. cgc/commands/auth/auth_cmd.py +14 -2
  6. cgc/commands/auth/auth_responses.py +9 -2
  7. cgc/commands/auth/auth_utils.py +6 -5
  8. cgc/commands/cgc_cmd.py +28 -3
  9. cgc/commands/cgc_cmd_responses.py +8 -0
  10. cgc/commands/cgc_models.py +9 -0
  11. cgc/commands/compute/compute_models.py +3 -23
  12. cgc/commands/compute/compute_utills.py +16 -6
  13. cgc/commands/db/db_cmd.py +7 -1
  14. cgc/commands/db/db_models.py +37 -0
  15. cgc/commands/exceptions.py +8 -0
  16. cgc/commands/jobs/__init__.py +10 -0
  17. cgc/commands/jobs/job_utils.py +180 -0
  18. cgc/commands/jobs/jobs_cmd.py +238 -0
  19. cgc/commands/jobs/jobs_responses.py +52 -0
  20. cgc/commands/keys/__init__.py +5 -0
  21. cgc/commands/keys/keys_cmd.py +176 -0
  22. cgc/commands/keys/keys_models.py +16 -0
  23. cgc/commands/keys/keys_responses.py +47 -0
  24. cgc/commands/keys/keys_utils.py +79 -0
  25. cgc/commands/resource/resource_cmd.py +2 -1
  26. cgc/sdk/__init__.py +1 -2
  27. cgc/sdk/job.py +147 -0
  28. cgc/sdk/resource.py +1 -0
  29. cgc/utils/__init__.py +8 -0
  30. cgc/utils/config_utils.py +5 -1
  31. cgc/utils/consts/env_consts.py +1 -1
  32. cgc/utils/custom_exceptions.py +8 -1
  33. cgc/utils/message_utils.py +1 -1
  34. cgc/utils/prepare_headers.py +22 -13
  35. cgc/utils/requests_helper.py +1 -3
  36. cgcsdk-1.0.9.dist-info/METADATA +66 -0
  37. {cgcsdk-1.0.6.dist-info → cgcsdk-1.0.9.dist-info}/RECORD +41 -32
  38. cgc/sdk/handlers.py +0 -24
  39. cgc/sdk/mongodb.py +0 -204
  40. cgc/sdk/redis.py +0 -91
  41. cgcsdk-1.0.6.dist-info/METADATA +0 -39
  42. {cgcsdk-1.0.6.dist-info → cgcsdk-1.0.9.dist-info}/LICENSE +0 -0
  43. {cgcsdk-1.0.6.dist-info → cgcsdk-1.0.9.dist-info}/WHEEL +0 -0
  44. {cgcsdk-1.0.6.dist-info → cgcsdk-1.0.9.dist-info}/entry_points.txt +0 -0
  45. {cgcsdk-1.0.6.dist-info → cgcsdk-1.0.9.dist-info}/top_level.txt +0 -0
cgc/sdk/job.py ADDED
@@ -0,0 +1,147 @@
1
+ import json as _json
2
+ from typing import Optional
3
+ import cgc.sdk.exceptions as _exceptions
4
+ from cgc.utils.custom_exceptions import CUSTOM_EXCEPTIONS
5
+ import cgc.utils.prepare_headers as _prepare_headers
6
+ import cgc.commands.jobs.job_utils as _job_utils
7
+ import cgc.utils.requests_helper as _requests_helper
8
+ import cgc.utils.response_utils as _response_utils
9
+ from cgc.commands.compute.compute_models import GPUsList
10
+
11
+
12
+ def job_create(
13
+ name: str,
14
+ image_name: str,
15
+ cpu: int = 1,
16
+ memory: int = 2,
17
+ shm_size: int = 0,
18
+ gpu: int = 0,
19
+ gpu_type: str = "A5000",
20
+ volumes: list = [],
21
+ volume_full_path: str = "",
22
+ startup_command: str = "",
23
+ repository_secret: str = "",
24
+ resource_data: list = [],
25
+ config_maps_data: list = [],
26
+ ttl_seconds_after_finished: Optional[int] = None,
27
+ ):
28
+ """
29
+ Create a custom compute resource.
30
+
31
+ :param name: The name of the compute resource.
32
+ :type name: str
33
+ :param image_name: The name of the image to use for the compute resource.
34
+ :type image_name: str,
35
+ :param cpu: The number of CPUs for the compute resource, defaults to 1.
36
+ :type cpu: int, optional
37
+ :param memory: The amount of memory (in GB) for the compute resource, defaults to 2.
38
+ :type memory: int, optional
39
+ :param shm_size: The size of the shared memory (in GB) for the compute resource, defaults to 0.
40
+ :type shm_size: int, optional
41
+ :param gpu: The number of GPUs for the compute resource, defaults to 0.
42
+ :type gpu: int, optional
43
+ :param gpu_type: The type of GPU for the compute resource, defaults to "A5000".
44
+ :type gpu_type: str, optional
45
+ :param volumes: The list of volumes to attach to the compute resource, defaults to [].
46
+ :type volumes: list, optional
47
+ :param volume_full_path: The full path of the volume, defaults to "".
48
+ :type volume_full_path: str, optional
49
+ :param startup_command: The startup command for the compute resource, defaults to "".
50
+ :type startup_command: str, optional
51
+ :param repository_secret: The secret for accessing the repository, defaults to "".
52
+ :type repository_secret: str, optional
53
+ :param resource_data: The additional resource data, defaults to [].
54
+ :type resource_data: list, optional
55
+ :param config_maps_data: The additional config maps data, defaults to [].
56
+ :type config_maps_data: list, optional
57
+ :param ttl_seconds_after_finished: The time to live in seconds after the app is finished, defaults to None.
58
+ :type ttl_seconds_after_finished: int, optional
59
+ :raises _SDKException: If the image name is not provided.
60
+ :raises _SDKException: If an invalid GPU type is specified.
61
+ :return: The response from the API call.
62
+ :rtype: _type_
63
+ """
64
+ if not image_name:
65
+ raise _exceptions.SDKException(-2, "Image name is required")
66
+ api_url, headers = _prepare_headers.get_api_url_and_prepare_headers()
67
+ url = f"{api_url}/v1/api/job/create"
68
+ metric = "job.create"
69
+ gpu_type = gpu_type.upper()
70
+ if gpu_type not in GPUsList.get_list():
71
+ raise _exceptions.SDKException(-3, f"Invalid GPU type: {gpu_type}")
72
+ __payload = _job_utils.job_create_payload(
73
+ name=name,
74
+ cpu=cpu,
75
+ memory=memory,
76
+ gpu=gpu,
77
+ gpu_type=gpu_type,
78
+ volumes=volumes,
79
+ volume_full_path=volume_full_path,
80
+ resource_data=resource_data,
81
+ config_maps_data=config_maps_data,
82
+ shm_size=shm_size,
83
+ image_name=image_name,
84
+ startup_command=startup_command,
85
+ repository_secret=repository_secret,
86
+ ttl_seconds_after_finished=ttl_seconds_after_finished,
87
+ )
88
+
89
+ __res = _requests_helper.call_api(
90
+ request=_requests_helper.EndpointTypes.post,
91
+ url=url,
92
+ headers=headers,
93
+ data=_json.dumps(__payload).encode("utf-8"),
94
+ )
95
+
96
+ return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(
97
+ __res, metric
98
+ )
99
+
100
+
101
+ def job_list():
102
+ """
103
+ List jobs using backend endpoint.
104
+
105
+ :return: response from the API call
106
+ :rtype: dict
107
+ """
108
+ api_url, headers = _prepare_headers.get_api_url_and_prepare_headers()
109
+ url = f"{api_url}/v1/api/job/list"
110
+ metric = "job.list"
111
+ __res = _requests_helper.call_api(
112
+ request=_requests_helper.EndpointTypes.get,
113
+ url=url,
114
+ headers=headers,
115
+ )
116
+
117
+ return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(
118
+ __res, metric
119
+ )
120
+ # job_pod_list = _response.get("details", {}).get("job_pod_list", [])
121
+ # job_list = _response.get("details", {}).get("job_list", [])
122
+ # return _job_utils.get_job_list(job_list)
123
+
124
+
125
+ def job_delete(name: str):
126
+ """
127
+ Delete job using backend endpoint.
128
+
129
+ :param name: name of job to delete
130
+ :type name: str
131
+ :return: response from the API call
132
+ :rtype: dict
133
+ """
134
+ api_url, headers = _prepare_headers.get_api_url_and_prepare_headers()
135
+ url = f"{api_url}/v1/api/job/delete"
136
+ metric = "job.delete"
137
+ __payload = _job_utils.job_delete_payload(name=name)
138
+ __res = _requests_helper.call_api(
139
+ request=_requests_helper.EndpointTypes.delete,
140
+ url=url,
141
+ headers=headers,
142
+ data=_json.dumps(__payload).encode("utf-8"),
143
+ )
144
+
145
+ return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(
146
+ __res, metric
147
+ )
cgc/sdk/resource.py CHANGED
@@ -114,6 +114,7 @@ def compute_list():
114
114
  class ResourceTypes(_Enum):
115
115
  compute = "compute"
116
116
  db = "db"
117
+ job = "job"
117
118
 
118
119
 
119
120
  def _resource_status_ready(name: str, response: dict):
cgc/utils/__init__.py CHANGED
@@ -20,6 +20,14 @@ def require_confirm_loop(message: str):
20
20
  exit(0)
21
21
 
22
22
 
23
+ def require_answer_loop(message: str, default: str):
24
+ while True:
25
+ answer = input(f"{message}: [{default}]").lower()
26
+ if answer == "":
27
+ return default
28
+ return answer
29
+
30
+
23
31
  def quick_sort(collection: list) -> list:
24
32
  """A pure Python implementation of quick sort algorithm
25
33
 
cgc/utils/config_utils.py CHANGED
@@ -5,7 +5,7 @@ import click
5
5
 
6
6
  from cgc.commands.auth import NoNamespaceInConfig, NoConfigFileFound
7
7
  from cgc.utils.message_utils import prepare_error_message
8
- from cgc.utils.consts.env_consts import get_config_file_name
8
+ from cgc.utils.consts.env_consts import CGC_API_URL, CGC_SECRET, get_config_file_name
9
9
 
10
10
 
11
11
  def get_config_path():
@@ -78,6 +78,10 @@ def read_from_cfg(key: str, filename=None):
78
78
  except KeyError:
79
79
  if key == "namespace":
80
80
  raise NoNamespaceInConfig()
81
+ elif key == "cgc_secret":
82
+ return CGC_SECRET
83
+ elif key == "cgc_api_url":
84
+ return CGC_API_URL
81
85
  print("Config file is corrupted. Please contact support at support@comtegra.pl")
82
86
  sys.exit()
83
87
 
@@ -33,7 +33,7 @@ else:
33
33
  raise Exception("not defined API_SECURE_CONNECTION. set yes/no")
34
34
 
35
35
  API_PORT = os.getenv("API_PORT")
36
- API_URL = f"{__prefix}://{API_HOST}:{API_PORT}"
36
+ CGC_API_URL = f"{__prefix}://{API_HOST}:{API_PORT}"
37
37
  TMP_DIR = os.getenv("TMP_DIR")
38
38
  RELEASE = int(os.getenv("RELEASE"))
39
39
  MAJOR_VERSION = int(os.getenv("MAJOR_VERSION"))
@@ -4,6 +4,7 @@
4
4
  CUSTOM_EXCEPTIONS = {
5
5
  500: {
6
6
  "UNDEFINED": "undefined exception",
7
+ "USER_KEY_CREATE_ERROR": "Error while creating key",
7
8
  },
8
9
  413: {
9
10
  "PVC_CREATE_STORAGE_LIMIT_EXCEEDED": "This request exceeds your storage limits",
@@ -15,7 +16,9 @@ CUSTOM_EXCEPTIONS = {
15
16
  "PVC_NAME_ALREADY_EXISTS": "Volume with this name already exists.",
16
17
  "PVC_DELETE_EXCEPTION": "Can't delete mounted volume, try with force",
17
18
  "RESOURCE_PORTS_ALREADY_EXISTS": "Port with this name already exists.",
18
- "RESOURCE_TEMPLATE_NAME_ALREADY_EXISTS": "Template with this name already exists.",
19
+ "RESOURCE_TEMPLATE_NAME_ALREADY_EXISTS": "Resource with this name already exists.",
20
+ "JOB_CREATE_ALREADY_EXISTS": "Job with this name already exists.",
21
+ "USER_KEY_ALREADY_EXISTS": "Key with these data already exists.",
19
22
  },
20
23
  404: {
21
24
  "PVC_CREATE_NO_SC": "Selected disk type and access mode unavailable",
@@ -30,11 +33,15 @@ CUSTOM_EXCEPTIONS = {
30
33
  "COMPUTE_CREATE_TEMPLATE_NOT_FOUND": "There is no template with this name.",
31
34
  "COMPUTE_TEMPLATE_NAME_NOT_FOUND": "No app with this name.",
32
35
  "COMPUTE_RESOURCE_QUOTA_NOT_FOUND": "You do not have enforced limits on your namespace.",
36
+ "JOB_NOT_FOUND": "Job with this name not found.",
37
+ "RESOURCE_NOT_FOUND": "Resource with this name not found.",
38
+ "USER_KEY_NOT_FOUND": "Key with this id not found.",
33
39
  },
34
40
  400: {
35
41
  "WRONG_DATE_FORMAT": "Wrong date format.",
36
42
  "ENTITY_NOT_ALLOWED": "You can't create this entity.",
37
43
  "PVC_MOUNT_ALREADY_MOUNTED": "This volume is already mounted.",
38
44
  "TEMPLATE_NAME_SYSTEM_RESERVED": "You can't create app with this name.",
45
+ "JOB_LACKS_REQUIRED_PARAMETER": "Job requires container image parameter.",
39
46
  },
40
47
  }
@@ -58,7 +58,7 @@ def key_error_decorator_for_helpers(func):
58
58
  if "debug" in kwargs:
59
59
  raise err
60
60
  return prepare_error_message(UNKNOWN_ERROR)
61
- except ResponseException as err:
61
+ except (ResponseException, click.ClickException) as err:
62
62
  return prepare_warning_message(err)
63
63
 
64
64
  return wrapper
@@ -1,5 +1,4 @@
1
1
  from cgc.utils.config_utils import read_from_cfg
2
- from cgc.utils.consts.env_consts import API_URL, CGC_SECRET
3
2
  from cgc.commands.auth import auth_utils
4
3
  from cgc.utils.message_utils import key_error_decorator_for_helpers
5
4
 
@@ -13,41 +12,51 @@ def load_user_api_keys():
13
12
  return read_from_cfg("api_key"), read_from_cfg("api_secret")
14
13
 
15
14
 
15
+ def load_user_cgc_secret():
16
+ return read_from_cfg("cgc_secret")
17
+
18
+
19
+ def load_user_api_url():
20
+ return read_from_cfg("cgc_api_url")
21
+
22
+
16
23
  @key_error_decorator_for_helpers
17
24
  def get_api_url_and_prepare_headers():
18
- """Loads API_URL and user api keys into single function. Mend to be used as single point of truth for all endpoints except register - due to different Content-Type header
25
+ """Loads CGC_API_URL and user api keys into single function. Mend to be used as single point of truth for all endpoints except register - due to different Content-Type header
19
26
 
20
- :return: API_URL and headers
27
+ :return: CGC_API_URL and headers
21
28
  :rtype: string and dict
22
29
  """
23
30
  api_key, api_secret = load_user_api_keys()
24
31
  headers = {
25
- "Content-Type": "application/json; charset=UTF-8",
26
32
  "accept": "application/json",
33
+ "Content-Type": "application/json; charset=UTF-8",
34
+ "comtegra-cgc": load_user_cgc_secret(),
27
35
  "api-key": api_key,
28
36
  "api-secret": api_secret,
29
- "comtegra-cgc": CGC_SECRET,
30
37
  }
31
- return API_URL, headers
38
+ return load_user_api_url(), headers
32
39
 
33
40
 
34
- def get_url_and_prepare_headers_register(user_id: str, access_key: str):
41
+ def get_url_and_prepare_headers_register(
42
+ user_id: str, access_key: str, url: str = None, secret: str = None
43
+ ):
35
44
  """Creates and returns url and headers for register request.
36
45
 
37
46
  :return: url, headers
38
47
  :rtype: string and dict
39
48
  """
40
- url = f"{API_URL}/v1/api/user/register?user_id={user_id}&access_key={access_key}"
49
+ url = f"{load_user_api_url() if url is None else url}/v1/api/user/register?user_id={user_id}&access_key={access_key}"
41
50
  headers = {
42
51
  "accept": "application/json",
43
- "comtegra-cgc": CGC_SECRET,
44
52
  "Content-Type": "octet-stream",
53
+ "comtegra-cgc": load_user_cgc_secret() if secret is None else secret,
45
54
  }
46
55
  return url, headers
47
56
 
48
57
 
49
58
  def get_url_and_headers_jwt_token():
50
- url = f"{API_URL}/v1/api/user/create/token"
59
+ url = f"{load_user_api_url()}/v1/api/user/create/token"
51
60
  headers = {
52
61
  "accept": "application/json",
53
62
  "Content-Type": "application/x-www-form-urlencoded",
@@ -64,8 +73,8 @@ def prepare_headers_api_key(user_id: str = None, password: str = None):
64
73
  """
65
74
  headers = {
66
75
  "accept": "application/json",
67
- "comtegra-cgc": CGC_SECRET,
68
76
  "Authorization": f"Bearer {auth_utils.get_jwt(user_id, password)}",
77
+ "comtegra-cgc": load_user_cgc_secret(),
69
78
  }
70
79
  return headers
71
80
 
@@ -76,10 +85,10 @@ def get_api_url_and_prepare_headers_version_control():
76
85
  :return: url and headers in a for of dictionary
77
86
  :rtype: string, dict
78
87
  """
79
- url = f"{API_URL}/v1/api/info/version"
88
+ url = f"{load_user_api_url()}/v1/api/info/version"
80
89
  headers = {
81
90
  "accept": "application/json",
82
- "comtegra-cgc": CGC_SECRET,
83
91
  "Content-Type": "application/json",
92
+ "comtegra-cgc": load_user_cgc_secret(),
84
93
  }
85
94
  return url, headers
@@ -1,7 +1,6 @@
1
1
  import requests
2
2
  import urllib3
3
3
  import urllib3.exceptions
4
- import ssl
5
4
  import click
6
5
  import sys
7
6
 
@@ -19,7 +18,6 @@ from cgc.utils.consts.message_consts import (
19
18
 
20
19
  urllib3.disable_warnings(urllib3.exceptions.SecurityWarning)
21
20
 
22
-
23
21
  class EndpointTypes(Enum):
24
22
  get = requests.get
25
23
  post = requests.post
@@ -27,7 +25,7 @@ class EndpointTypes(Enum):
27
25
 
28
26
 
29
27
  def _process_endpoint_kwargs(**kwargs):
30
- if not "timeout" in kwargs.keys():
28
+ if "timeout" not in kwargs.keys():
31
29
  kwargs["timeout"] = 30
32
30
  return kwargs
33
31
 
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.1
2
+ Name: cgcsdk
3
+ Version: 1.0.9
4
+ Summary: Comtegra GPU Cloud REST API client
5
+ Author: Comtegra AI Team
6
+ Author-email: ai@comtegra.pl
7
+ License: BSD 2-clause
8
+ Project-URL: Documentation, https://example.com/documentation/
9
+ Project-URL: GitHub, https://github.com/foobar/foobar/
10
+ Project-URL: Changelog, https://github.com/foobar/foobar/blob/master/CHANGELOG.md
11
+ Keywords: cloud,sdk,orchestrator,kubernetes,jupyter-notebook
12
+ Classifier: Development Status :: 1 - Planning
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: BSD License
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.4
18
+ Classifier: Programming Language :: Python :: 3.5
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: click
25
+ Requires-Dist: python-dotenv
26
+ Requires-Dist: tabulate
27
+ Requires-Dist: pycryptodomex
28
+ Requires-Dist: paramiko >=2.11
29
+ Requires-Dist: statsd
30
+ Requires-Dist: requests
31
+ Requires-Dist: setuptools
32
+ Requires-Dist: colorama
33
+ Requires-Dist: psycopg2-binary
34
+
35
+ # Comtegra GPU Cloud CLI Client
36
+
37
+ ## Basic info
38
+
39
+ CGC Clinet is complete solution to create and manage your compute resources through CLI interface and python code. It incorporates CLI and SDK in one package.
40
+
41
+ CGC CLI is a command line interface for Comtegra GPU Cloud. CGC CLI enables management of your Comtegra GPU Cloud resources. Current version of the app provides support for compute, storage and network resurces to be created, listed and deleted. Every compute resource is given to you as an URL, which is accessible from open Internet.
42
+
43
+ To enable better access to your storage resources, every account has the ability to spawn free of charge filebrowser which is local implementation of dropbox. Remember to mount newely created volumes to it.
44
+
45
+ For now, we provide the ability to spawn compute resources like:
46
+
47
+ 1. [Jupyter notebook](https://jupyter.org/) with tensorflow or pytorch installed as default
48
+ 2. [Triton inferencing server](https://docs.nvidia.com/deeplearning/triton-inference-server/) for large scale inferencing
49
+ 3. [Label studio](https://labelstud.io/) for easy management of your data annotation tasks with variety of modes
50
+ 4. [Rapids](https://rapids.ai/) suite of accelerated libraries for data processing
51
+
52
+ Notebooks are equiped with all CUDA libraries and GPU drivers which enables the usage of GPU for accelerated computations.
53
+ Apart from compute resources, we provide the database engines accessible from within your namespace:
54
+
55
+ 1. [PostgreSQL](https://www.postgresql.org/)
56
+ 2. [Weaviate](https://weaviate.io/)
57
+
58
+ More are coming!
59
+ Please follow instructions to get started.
60
+
61
+ ## More info
62
+
63
+ If you'd like to know more visit:
64
+
65
+ - [Comtegra GPU Website](https://cgc.comtegra.cloud)
66
+ - [Docs](https://docs.cgc.comtegra.cloud)
@@ -1,45 +1,54 @@
1
- cgc/.env,sha256=pohuoU74JqAFXwFouEY7no0qxtty7IWxCL_zC0XOBpM,209
2
- cgc/CHANGELOG.md,sha256=12AtIOmxUo_M7f8va6oecLrC12jm68GvjM9fgTMFFcs,7487
1
+ cgc/.env,sha256=9SFROL8yLunt_B6HnKsZXY7RQ8-njO1_mScMhSQJ5Rs,209
2
+ cgc/CHANGELOG.md,sha256=Ndoiy_uhnTCvgJcTdTa_kFV06stYTVAT3tUHdMZbocI,8255
3
3
  cgc/__init__.py,sha256=d03Xv8Pw4ktNyUHfmicP6XfxYPXnVYLaCZPyUlg_RNQ,326
4
- cgc/cgc.py,sha256=kPLg3h-3kjlMBiwZGOM7yvXJ7pzkVglAbWWQ7KX8jeY,1377
4
+ cgc/cgc.py,sha256=bW2Q2vcWfCBBkQ2nopXVCjW5GAbv6DGzTG-ZEn_VsLo,1571
5
5
  cgc/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  cgc/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- cgc/commands/cgc_cmd.py,sha256=gy7ePOBcF3pNL-np6xHGs6BSdnlPqLnYK6O7Tr82Evg,4326
8
- cgc/commands/cgc_cmd_responses.py,sha256=ToPjvGf3zUbFLhLwv-BV8ZAvAHg1xS99iprM928MnOY,2026
7
+ cgc/commands/cgc_cmd.py,sha256=QwqjZl9FmAMOvuUQMJm-wOV88OxbdwK5UIS0zkg-mAo,4956
8
+ cgc/commands/cgc_cmd_responses.py,sha256=wO9Hf5_4jaw1ZRhQvh9Za0S_vhc22t-0_CoEGz5ndNE,2245
9
9
  cgc/commands/cgc_helpers.py,sha256=ngArFjVw-8P_2g7J8k3b9xgDxfJw7JeaOtkhTySMSGU,1174
10
- cgc/commands/exceptions.py,sha256=l3Sms3D2fxSpLQQQEYeLWxO3to82myTQ0VFgFYdQdLU,45
11
- cgc/commands/auth/__init__.py,sha256=K8HkHHotMnK7SQRAst5rx_wprHEphPo_w2KToEymjAY,399
12
- cgc/commands/auth/auth_cmd.py,sha256=jfijV-C0uOnpj5LcOgsW7Sn5JiemZ-nuQRQUEjEvaEk,3856
13
- cgc/commands/auth/auth_responses.py,sha256=kf5Btt7-9oKH8AGL7_zcjDL4sXWmqmt3pV37S1GeqBQ,1839
14
- cgc/commands/auth/auth_utils.py,sha256=R-iwoZbMWTpPJ3O7tp3cU6l-csl-ULWoazE7t3L5hmU,5359
10
+ cgc/commands/cgc_models.py,sha256=T4eCMO5AO2kZpIRqpZ7ZfgO9gxCo_MLlY33msCzrLvA,182
11
+ cgc/commands/exceptions.py,sha256=kVCWEdcqmkLO5QVIINdEXQw29_glyX2C11ZMFgT7b8E,155
12
+ cgc/commands/auth/__init__.py,sha256=JnqNezSEUEVVPQIymya4llXr8LIug2vymQSAGBr4Ovg,397
13
+ cgc/commands/auth/auth_cmd.py,sha256=FiRM16RGtP1zoJ9InbFAa-3W-EkJQbzBDxF0AmZa1JA,4196
14
+ cgc/commands/auth/auth_responses.py,sha256=oZ1aC7tyrT43imF2iMaL0u1jTJzuGLEmCN8RBeMxpf4,1959
15
+ cgc/commands/auth/auth_utils.py,sha256=-diCsKuF5UcQZoq962RuLktrG6sRmipJrDkm9Sf3wbg,5507
15
16
  cgc/commands/billing/__init__.py,sha256=0arQm0R3Ouw7tXPooJsvWd_pGeHhzaVwQCbWMKQPT9A,753
16
17
  cgc/commands/billing/billing_cmd.py,sha256=T1E5WW5Z-RlzddaotimTuvLvIbGihNpStIBETnlUznM,4140
17
18
  cgc/commands/billing/billing_responses.py,sha256=HAD5N-Odx3Jz1OmhO4v66rHoXpTYIOGlXDsrs0da9dk,1949
18
19
  cgc/commands/billing/billing_utils.py,sha256=zXLbBBcWeOgur-r0OKiIjaKeaxMNxASXWzCTeTsyC6o,4711
19
20
  cgc/commands/compute/__init__.py,sha256=lCdLfZ0ECSHtXEUSwq5YRHH85yXHchSsz8ZJvmClPtI,239
20
21
  cgc/commands/compute/compute_cmd.py,sha256=jgO61ULXIAuRn1LcFn0VU0X2-oLvBQB-0_OYMzXau0w,15490
21
- cgc/commands/compute/compute_models.py,sha256=DzktT7nR6eG3po6iIayQjnczmnZruAl00Q9o3okqdng,1139
22
+ cgc/commands/compute/compute_models.py,sha256=yse6mCEhhE2RdWIO7EHx4r5Y-350gWWy4UWFsdltNNg,778
22
23
  cgc/commands/compute/compute_responses.py,sha256=eOmcllyOqPYqN0kSUzSpuC2S1rFmkkawgc_F-0-LSIQ,5807
23
- cgc/commands/compute/compute_utills.py,sha256=oANUoJRt0L2VDKoMsAhEkE5lfigjRrX9fJjhWpG1Mc4,8615
24
+ cgc/commands/compute/compute_utills.py,sha256=XXnd_EuF9vCmW14r0ThlN98ScKSx3KAeqFbWy2g2mlk,8812
24
25
  cgc/commands/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- cgc/commands/db/db_cmd.py,sha256=r0iwQ9oIQLcozshVyaHBxQMijYLrcfKvm0bXr9jGhek,3309
26
+ cgc/commands/db/db_cmd.py,sha256=iA7YAgyosydMsRagus1nxbMTPhFlr1olUaWPVjV2BsA,3513
27
+ cgc/commands/db/db_models.py,sha256=oJUAF23nb_r8fSyhLHMJrRbRzLY_vpJQu6Vy4WRa0cg,1036
26
28
  cgc/commands/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
29
  cgc/commands/debug/debug_cmd.py,sha256=kuAuh5YOqzGFjoiYZwfM9FJ1z5OeSpC0JAIUEzS83lM,412
30
+ cgc/commands/jobs/__init__.py,sha256=E-438wgIzlnGmXs5jgmWAhJ1KNV6UXF2gz8SXu3UxA0,231
31
+ cgc/commands/jobs/job_utils.py,sha256=Pu8SvVrmxee_dfkc4eFHWe5AeV31RyiUwiuuSFYA8fo,6195
32
+ cgc/commands/jobs/jobs_cmd.py,sha256=Q-orK6B9Zk1zAf8sOM6QqF9Eeu092P-UEg4GRA-zX-s,6555
33
+ cgc/commands/jobs/jobs_responses.py,sha256=QXFXA4zwQOo5Gvq5rEc7J_cxxsYqkdU19X9MCcZetUM,1771
34
+ cgc/commands/keys/__init__.py,sha256=rznd63OZhZvKHbdnXAsIBV_OWTnzHtFGfqzgNM4zCXk,112
35
+ cgc/commands/keys/keys_cmd.py,sha256=RQtDlvy31WNp7MgqrAfB1ydUya12wnr2eq1BOt2ZLz4,4437
36
+ cgc/commands/keys/keys_models.py,sha256=IYojnAu3aTGJ7qHIYvZy-0YFzXRmueZNplS4RqdfJfw,378
37
+ cgc/commands/keys/keys_responses.py,sha256=ENHRpUWEGX1r9mpMIwcVnYy6ikO0F1e-68834JHL9LE,1474
38
+ cgc/commands/keys/keys_utils.py,sha256=GiQcBoQdI6Zy_fvU9AVvBbUfaQx7g26s8NRbonmG474,2285
28
39
  cgc/commands/resource/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- cgc/commands/resource/resource_cmd.py,sha256=ALROaJPRK5BB8R_oEC7JzOl3J8umMmhC_HJuwGFaw_M,4053
40
+ cgc/commands/resource/resource_cmd.py,sha256=6iVkl77ZHpgky5a1Qjof6sBKLMOnUzyqSbOiJ5BmhBQ,4090
30
41
  cgc/commands/resource/resource_responses.py,sha256=sES7mAi_Cv5B6Z3I_6eUOqVwOr2HgMO45cz8MiNZetQ,197
31
42
  cgc/commands/volume/__init__.py,sha256=Ou3kyb72aaXkrVCfQCVdniA65R2xHsRFgebooG1gflA,384
32
43
  cgc/commands/volume/data_model.py,sha256=meprXdaXLo3mMTZta1ks1-BJ7G0rO16qi_ycH-sXJpY,1295
33
44
  cgc/commands/volume/volume_cmd.py,sha256=5bd0vq5--Y7IfniO33tGBYH0Z67Le2s_AMTiwJcPBA4,7673
34
45
  cgc/commands/volume/volume_responses.py,sha256=WefUohXxXZ9Znfc6P2XjoAM2RlA19hMKcVaW-xG9HWs,3199
35
46
  cgc/commands/volume/volume_utils.py,sha256=n6s0FgpsYyxFMp_JdMRCzRi5Ar3_Svg9JDvWSdX4lhk,1919
36
- cgc/sdk/__init__.py,sha256=2KWwBgq1wxwrB1uTYfN4TvKoNAWiy5qugb1L7YPspfo,271
47
+ cgc/sdk/__init__.py,sha256=m8uAD2e_ADbHC4_kaOpLrUk_bHy7wC56rPjhcttclCs,177
37
48
  cgc/sdk/exceptions.py,sha256=99XIzDO6LYKjex715troH-MkGUN7hi2Bit4KHfSHDis,214
38
- cgc/sdk/handlers.py,sha256=ECCHNe1pErsXFlmwHewsWRvYqzAZ5j5TrSqwernpLJk,868
39
- cgc/sdk/mongodb.py,sha256=TJ2XU7nilNRXLOIpQQPrRiVxHN2TaVM5QOSuMRtNDVs,7221
49
+ cgc/sdk/job.py,sha256=q9Vsarc3rKzurM4AOmbQDsQUVdyRqx0UzJVe_uO8xCU,5318
40
50
  cgc/sdk/postgresql.py,sha256=ziXaMMwjSF3k1OAID3F9npqWVxreQaoZ8wn7X8x1FZw,1637
41
- cgc/sdk/redis.py,sha256=W5wS9Sgyv4098yzWAwG7qEk4HEDwscE3JmWgPC3NCzc,2844
42
- cgc/sdk/resource.py,sha256=85-XjTbXDvIj8aB6QIyeEfMV3G0pfV6v-sX0Y6a0GAQ,13528
51
+ cgc/sdk/resource.py,sha256=Wodt8pe15zg1uuclfV4Qxntffph70ULhNig_gOgMKz8,13544
43
52
  cgc/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
53
  cgc/telemetry/basic.py,sha256=XagCcyH4QSEPmfiQ1WCjqXslnJO6IaJCY0AMPySd5rc,3175
45
54
  cgc/tests/__init__.py,sha256=8aI3MVpkzaj0_UX02kZCtY5vmGO0rnq0mw2H04-OHf8,102743
@@ -52,26 +61,26 @@ cgc/tests/desired_responses/test_compute_list.txt,sha256=3CDAuILJdwBmX6-GLj3zDbn
52
61
  cgc/tests/desired_responses/test_compute_list_no_labels.txt,sha256=-OeQIaEHHsHZ81tCOI5j6VQYUMlj8VYcyyOU_DhPOpU,155
53
62
  cgc/tests/desired_responses/test_tabulate_response.txt,sha256=beNyCTS9fwrHn4ueEOVk2BpOeSYZWumIa3H5EUGnW1I,789
54
63
  cgc/tests/desired_responses/test_volume_list.txt,sha256=vYB1p50BBHD801q7LUdDc_aca4ezQ8CFLWw7I-b4Uao,309
55
- cgc/utils/__init__.py,sha256=l9JF-WnvmhlolxbDKlJPsxquZ-fjtvv7wKvn2zpu5IM,3466
64
+ cgc/utils/__init__.py,sha256=o3YYCh02WiAvmHw-8Hy3FJA4LjGWwPkaLTur6tEvsbE,3669
56
65
  cgc/utils/click_group.py,sha256=Scfw8eMIyt2dE1ezUq2JuiI-E_LklqXQXJEr7L-EG6A,633
57
- cgc/utils/config_utils.py,sha256=VFTrcN9QeOByIobhh48TfAm-BWON4PN8zX0H8PdUNTU,2729
58
- cgc/utils/custom_exceptions.py,sha256=rMlMfSG-pqkVH0B7tUdWTt6w2oRGovJZO9lnXcuoHPM,2148
59
- cgc/utils/message_utils.py,sha256=jdUHtR2-gEvyxYu1T0OY-a6cBz5N8TatRaxKNuNcJtU,1766
60
- cgc/utils/prepare_headers.py,sha256=xNDins83jdMre80s3orsR3Xu0jPUd82CHppvLq2tbeA,2561
61
- cgc/utils/requests_helper.py,sha256=ghn8LTxWqfRvy7BXQdxD4VHX8b-ypHkbnFXY05ig7_A,2050
66
+ cgc/utils/config_utils.py,sha256=NlPs334y6BSNGoYbFjrB5cKc9trTWIXOn8UN6O4ztNU,2884
67
+ cgc/utils/custom_exceptions.py,sha256=qvHdzaunZswZgN96iOHZIfLjehlJ79mcjqoMoW-tqEM,2628
68
+ cgc/utils/message_utils.py,sha256=FAiUC-0zJiMhfPQAQC0ki1ZUs1vI_QqHwLmfoCDbLeU,1790
69
+ cgc/utils/prepare_headers.py,sha256=67YMPogNoGbKnHQmGFc3iJCbsDZbRVjAIe3kBY-Dq98,2838
70
+ cgc/utils/requests_helper.py,sha256=1gorWHXtFkb8eSIXfftiPyqagHGVyJpD5yx2IF8mFHU,2038
62
71
  cgc/utils/response_utils.py,sha256=9vJqAt2UFJ1n-oesFPe6CB_ooGoStjl-twY_31Jt4_I,7374
63
72
  cgc/utils/update.py,sha256=AsQwhcBqsjgNPKn6AN6ojt0Ew5otvJXyshys6bjr7DQ,413
64
73
  cgc/utils/version_control.py,sha256=VsqNzNYWDvU3VsoPuYIaZV7Img-K2_DmEOHd7rZlRxk,3267
65
74
  cgc/utils/consts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
- cgc/utils/consts/env_consts.py,sha256=sHO1vzWZALiXB4Ej2E7S5v0i-DfTwHBIIC1fIP_MocI,1286
75
+ cgc/utils/consts/env_consts.py,sha256=8huPDBkbNEXoPHskFhYwiRi6TTw0_e9ylClpgh1NF2E,1290
67
76
  cgc/utils/consts/message_consts.py,sha256=8CIe3N_HL6Pj-gSArkPkpegsvm-QMWxqqnSgtzG08Qw,1218
68
77
  cgc/utils/cryptography/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
78
  cgc/utils/cryptography/aes_crypto.py,sha256=S0rKg38oy7rM5lTrP6DDpjLA-XRxuZggAXyxMFHtyzY,3333
70
79
  cgc/utils/cryptography/encryption_module.py,sha256=rbblBBorHYPGl-iKblyZX3_NuPEvUTpnH1l_RgNGCbA,1958
71
80
  cgc/utils/cryptography/rsa_crypto.py,sha256=h3jU5qPpj9uVjP1rTqZJTdYB5yjhD9HZpr_nD439h9Q,4180
72
- cgcsdk-1.0.6.dist-info/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- cgcsdk-1.0.6.dist-info/METADATA,sha256=TZ5gU13dcNS5yiB8j6FCilYesOtAUwghjYjPlkMbe5Y,1418
74
- cgcsdk-1.0.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
75
- cgcsdk-1.0.6.dist-info/entry_points.txt,sha256=bdfIHeJ6Y-BBr5yupCVoK7SUrJj1yNdew8OtIOg_3No,36
76
- cgcsdk-1.0.6.dist-info/top_level.txt,sha256=nqW9tqcIcCXFigQT69AuOk7XHKc4pCuv4HGJQGXb6iA,12
77
- cgcsdk-1.0.6.dist-info/RECORD,,
81
+ cgcsdk-1.0.9.dist-info/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
+ cgcsdk-1.0.9.dist-info/METADATA,sha256=wjetOTsxZ1T4g0eJ0DrDkkwCTHcVhJy8eGYZ5NEUR5w,3057
83
+ cgcsdk-1.0.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
84
+ cgcsdk-1.0.9.dist-info/entry_points.txt,sha256=bdfIHeJ6Y-BBr5yupCVoK7SUrJj1yNdew8OtIOg_3No,36
85
+ cgcsdk-1.0.9.dist-info/top_level.txt,sha256=nqW9tqcIcCXFigQT69AuOk7XHKc4pCuv4HGJQGXb6iA,12
86
+ cgcsdk-1.0.9.dist-info/RECORD,,
cgc/sdk/handlers.py DELETED
@@ -1,24 +0,0 @@
1
- from pymongo.errors import OperationFailure, ConnectionFailure
2
- # TODO: redis, postgres
3
- # TODO: print -> click.echo ?
4
-
5
- def exception_handler(func):
6
- def inner_function(*args, **kwargs):
7
- err_count = 0
8
- err_limit = 3
9
- while True and err_count < err_limit:
10
- try:
11
- err_count += 1
12
- return func(*args, **kwargs)
13
- except (ConnectionFailure,) as e:
14
- print(f"MongoDB connection error: {e}")
15
- print(f"retrying {err_count}/{err_limit} ...")
16
- # args[0]._reset_connection()
17
- except OperationFailure as e:
18
- print(f"MongoDB OperationFailure: {e}")
19
- raise e
20
- else:
21
- print(f"MongoDB exception for customer")
22
- # TODO: HTTP EXCEPTION FOR CUSTOMER, but keep thread alive
23
-
24
- return inner_function