cgcsdk 1.0.5__py3-none-any.whl → 1.0.7__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.
@@ -0,0 +1,238 @@
1
+ import click
2
+ import json
3
+ import sys
4
+
5
+ from cgc.commands.jobs.job_utils import job_delete_payload, job_create_payload
6
+ from cgc.commands.jobs.jobs_responses import (
7
+ job_delete_response,
8
+ job_list_response,
9
+ job_create_response,
10
+ )
11
+ from cgc.commands.compute.compute_models import GPUsList
12
+ from cgc.utils.prepare_headers import get_api_url_and_prepare_headers
13
+ from cgc.utils.response_utils import (
14
+ retrieve_and_validate_response_send_metric,
15
+ )
16
+ from cgc.utils.click_group import CustomGroup, CustomCommand
17
+ from cgc.utils.requests_helper import call_api, EndpointTypes
18
+
19
+
20
+ @click.group(name="job", cls=CustomGroup, hidden=False)
21
+ def job_group():
22
+ """
23
+ Management of jobs.
24
+ """
25
+
26
+
27
+ @job_group.command("delete", cls=CustomCommand)
28
+ @click.argument("name", type=click.STRING)
29
+ def job_delete(name: str):
30
+ """
31
+ Delete an job using backend endpoint.
32
+ \f
33
+ :param name: name of job to delete
34
+ :type name: str
35
+ """
36
+ api_url, headers = get_api_url_and_prepare_headers()
37
+ url = f"{api_url}/v1/api/job/delete"
38
+ metric = "job.delete"
39
+ __payload = job_delete_payload(name=name)
40
+ __res = call_api(
41
+ request=EndpointTypes.delete,
42
+ url=url,
43
+ headers=headers,
44
+ data=json.dumps(__payload).encode("utf-8"),
45
+ )
46
+ click.echo(
47
+ job_delete_response(retrieve_and_validate_response_send_metric(__res, metric))
48
+ )
49
+
50
+
51
+ @job_group.command("list", cls=CustomCommand)
52
+ def job_list():
53
+ """List all ports for a running resource"""
54
+ api_url, headers = get_api_url_and_prepare_headers()
55
+ url = f"{api_url}/v1/api/job/list"
56
+ metric = "job.list"
57
+ __res = call_api(
58
+ request=EndpointTypes.get,
59
+ url=url,
60
+ headers=headers,
61
+ )
62
+ click.echo(
63
+ job_list_response(retrieve_and_validate_response_send_metric(__res, metric))
64
+ )
65
+
66
+
67
+ @job_group.command("create", cls=CustomCommand)
68
+ @click.argument("startup_command", required=False)
69
+ @click.option(
70
+ "-n", "--name", "name", type=click.STRING, required=True, help="Desired app name"
71
+ )
72
+ @click.option(
73
+ "-g",
74
+ "--gpu",
75
+ "gpu",
76
+ type=click.INT,
77
+ default=0,
78
+ help="How much GPU cards app will use",
79
+ )
80
+ @click.option(
81
+ "-gt",
82
+ "--gpu-type",
83
+ "gpu_type",
84
+ type=click.Choice(GPUsList.get_list(), case_sensitive=False),
85
+ default="A5000",
86
+ help="Graphic card used by the app",
87
+ )
88
+ @click.option(
89
+ "-c",
90
+ "--cpu",
91
+ "cpu",
92
+ type=click.INT,
93
+ default=1,
94
+ help="How much CPU cores app can use",
95
+ )
96
+ @click.option(
97
+ "-m",
98
+ "--memory",
99
+ "memory",
100
+ type=click.INT,
101
+ default=2,
102
+ help="How much Gi RAM app can use",
103
+ )
104
+ @click.option(
105
+ "-v",
106
+ "--volume",
107
+ "volumes",
108
+ multiple=True,
109
+ help="List of volume names to be mounted with default mount path",
110
+ )
111
+ @click.option(
112
+ "-fp",
113
+ "--full-path",
114
+ "volume_full_path",
115
+ type=click.STRING,
116
+ help="If set, full path will be used for volume mount. Valid for 1 volume.",
117
+ )
118
+ @click.option(
119
+ "-d",
120
+ "--resource-data",
121
+ "resource_data",
122
+ multiple=True,
123
+ help="List of optional arguments to be passed to the app, key=value format",
124
+ )
125
+ @click.option(
126
+ "--image",
127
+ "image_name",
128
+ type=click.STRING,
129
+ help="Image to be used by the app",
130
+ )
131
+ @click.option(
132
+ "--repository-secret",
133
+ "repository_secret",
134
+ type=click.STRING,
135
+ help="Use secret to pull image from private repository",
136
+ )
137
+ @click.option(
138
+ "-cm",
139
+ "--config-map",
140
+ "config_maps_data",
141
+ multiple=True,
142
+ help="List of optional arguments to be passed to the app, key=value format",
143
+ )
144
+ @click.option(
145
+ "--shm",
146
+ "shm_size",
147
+ type=click.IntRange(0, 1024, clamp=True),
148
+ default=0,
149
+ help="Size of shared memory in Gi",
150
+ )
151
+ @click.option(
152
+ "--ttl",
153
+ "ttl_seconds_after_finished",
154
+ type=click.INT,
155
+ default=None,
156
+ help="Time to live in seconds after app is finished",
157
+ )
158
+ def job_create(
159
+ gpu: int,
160
+ gpu_type: str,
161
+ cpu: int,
162
+ memory: int,
163
+ volumes: list[str],
164
+ volume_full_path: str,
165
+ resource_data: list[str],
166
+ config_maps_data: list[str],
167
+ name: str,
168
+ shm_size: int,
169
+ image_name: str,
170
+ startup_command: str,
171
+ repository_secret: str,
172
+ ttl_seconds_after_finished: int,
173
+ ):
174
+ """
175
+ Create job in user namespace.
176
+ \f
177
+ :param gpu: number of gpus to be used by app
178
+ :type gpu: int
179
+ :param cpu: number of cores to be used by app
180
+ :type cpu: int
181
+ :param memory: GB of memory to be used by app
182
+ :type memory: int
183
+ :param volumes: list of volumes to mount
184
+ :type volumes: list[str]
185
+ :param volume_full_path: if set, full path will be used for volume mount
186
+ :type volume_full_path: str
187
+ :param resource_data: list of optional arguments to be passed to the app
188
+ :type resource_data: list[str]
189
+ :param config_maps_data: list of optional arguments to be passed to the app
190
+ :type config_maps_data: list[str]
191
+ :param name: name of app
192
+ :type name: str
193
+ :param shm_size: size of shared memory
194
+ :type shm_size: int
195
+ :param image_name: name of image to be used by the app
196
+ :type image_name: str
197
+ :param startup_command: command to be executed on app startup; it is stdin input
198
+ :type startup_command: str
199
+ :param repository_secret: use secret to pull image from private repository
200
+ :type repository_secret: str
201
+ :param ttl_seconds_after_finished: time to live in seconds after app is finished
202
+ :type ttl_seconds_after_finished: int
203
+ """
204
+ api_url, headers = get_api_url_and_prepare_headers()
205
+ url = f"{api_url}/v1/api/job/create"
206
+ cleaned_data = ""
207
+ if not sys.stdin.isatty():
208
+ input_data = sys.stdin.read()
209
+ cleaned_data = input_data.replace("|", "")
210
+ startup_command = cleaned_data
211
+ elif startup_command:
212
+ cleaned_data = startup_command
213
+ metric = "job.create"
214
+ __payload = job_create_payload(
215
+ name=name,
216
+ cpu=cpu,
217
+ memory=memory,
218
+ gpu=gpu,
219
+ volumes=volumes,
220
+ volume_full_path=volume_full_path,
221
+ resource_data=resource_data,
222
+ config_maps_data=config_maps_data,
223
+ gpu_type=gpu_type,
224
+ shm_size=shm_size,
225
+ image_name=image_name,
226
+ startup_command=cleaned_data,
227
+ repository_secret=repository_secret,
228
+ ttl_seconds_after_finished=ttl_seconds_after_finished,
229
+ )
230
+ __res = call_api(
231
+ request=EndpointTypes.post,
232
+ url=url,
233
+ headers=headers,
234
+ data=json.dumps(__payload).encode("utf-8"),
235
+ )
236
+ click.echo(
237
+ job_create_response(retrieve_and_validate_response_send_metric(__res, metric))
238
+ )
@@ -0,0 +1,52 @@
1
+ from cgc.commands.jobs import NoJobsToList
2
+ from cgc.commands.jobs.job_utils import get_job_list
3
+ from cgc.telemetry.basic import change_gauge, setup_gauge
4
+ from cgc.utils.config_utils import get_namespace
5
+ from cgc.utils.message_utils import key_error_decorator_for_helpers
6
+ from cgc.utils.response_utils import (
7
+ fill_missing_values_in_a_response,
8
+ tabulate_a_response,
9
+ )
10
+
11
+
12
+ @key_error_decorator_for_helpers
13
+ def job_delete_response(data: dict) -> str:
14
+ """Create response string for job delete command.
15
+
16
+ :param response: dict object from API response.
17
+ :type response: requests.Response
18
+ :return: Response string.
19
+ :rtype: str
20
+ """
21
+ name = data.get("details", {}).get("job_deleted", {}).get("name")
22
+ change_gauge(f"{get_namespace()}.job.count", -1)
23
+ return f"Job {name} and its service successfully deleted."
24
+
25
+
26
+ @key_error_decorator_for_helpers
27
+ def job_list_response(data: dict) -> list:
28
+ job_pod_list = data.get("details", {}).get("job_pod_list", [])
29
+ job_list = data.get("details", {}).get("job_list", [])
30
+ setup_gauge(f"{get_namespace()}.job.count", len(job_list))
31
+
32
+ if not job_list:
33
+ raise NoJobsToList()
34
+
35
+ list_of_json_data = get_job_list(job_pod_list, job_list)
36
+ table = fill_missing_values_in_a_response(list_of_json_data)
37
+
38
+ return tabulate_a_response(table)
39
+
40
+
41
+ @key_error_decorator_for_helpers
42
+ def job_create_response(data: dict) -> str:
43
+ """Create response string for job create command.
44
+
45
+ :param response: dict object from API response.
46
+ :type response: requests.Response
47
+ :return: Response string.
48
+ :rtype: str
49
+ """
50
+ name = data.get("details", {}).get("job_created", {}).get("name")
51
+ change_gauge(f"{get_namespace()}.job.count", 1)
52
+ return f"Job {name} created successfully."
@@ -72,7 +72,7 @@ def compute_restart(name: str):
72
72
  request=EndpointTypes.post,
73
73
  url=url,
74
74
  headers=headers,
75
- data=json.dumps(__payload),
75
+ data=json.dumps(__payload).encode("utf-8"),
76
76
  )
77
77
  click.echo(
78
78
  compute_restart_response(
@@ -116,7 +116,7 @@ def resource_delete(name: str):
116
116
  request=EndpointTypes.delete,
117
117
  url=url,
118
118
  headers=headers,
119
- data=json.dumps(__payload),
119
+ data=json.dumps(__payload).encode("utf-8"),
120
120
  )
121
121
  click.echo(
122
122
  compute_delete_response(
@@ -94,7 +94,7 @@ def volume_create(name: str, size: int, disk_type: str, access: str):
94
94
  __res = call_api(
95
95
  request=EndpointTypes.post,
96
96
  url=url,
97
- data=json.dumps(__payload),
97
+ data=json.dumps(__payload).encode("utf-8"),
98
98
  headers=headers,
99
99
  )
100
100
  click.echo(
@@ -132,7 +132,7 @@ def volume_delete(name: str, force_delete: bool):
132
132
  __res = call_api(
133
133
  request=EndpointTypes.delete,
134
134
  url=url,
135
- data=json.dumps(__payload),
135
+ data=json.dumps(__payload).encode("utf-8"),
136
136
  headers=headers,
137
137
  )
138
138
  click.echo(
@@ -182,7 +182,7 @@ def volume_umount(name: str, target_template_names):
182
182
  __res = call_api(
183
183
  request=EndpointTypes.post,
184
184
  url=url,
185
- data=json.dumps(__payload),
185
+ data=json.dumps(__payload).encode("utf-8"),
186
186
  headers=headers,
187
187
  )
188
188
  click.echo(
@@ -270,7 +270,7 @@ def volume_mount(
270
270
  __res = call_api(
271
271
  request=EndpointTypes.post,
272
272
  url=url,
273
- data=json.dumps(__payload),
273
+ data=json.dumps(__payload).encode("utf-8"),
274
274
  headers=headers,
275
275
  )
276
276
  click.echo(
cgc/sdk/__init__.py CHANGED
@@ -3,4 +3,5 @@ from cgc.sdk.redis import get_redis_access as redis_client
3
3
  from cgc.sdk.postgresql import get_postgresql_access as postgresql_client
4
4
 
5
5
  import cgc.sdk.resource as resource
6
+ import cgc.sdk.job as job
6
7
  import cgc.sdk.exceptions as exceptions
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_pod_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
@@ -1,6 +1,6 @@
1
1
  import json as _json
2
- import re
3
2
  import cgc.sdk.exceptions as _exceptions
3
+ from cgc.utils.custom_exceptions import CUSTOM_EXCEPTIONS
4
4
  import cgc.utils.prepare_headers as _prepare_headers
5
5
  import cgc.commands.compute.compute_utills as _compute_utills
6
6
  import cgc.utils.requests_helper as _requests_helper
@@ -20,41 +20,36 @@ def start_function_loop(function, infinite: bool = True, *args, **kwargs):
20
20
  **kwargs: Keyword arguments to be passed to the function.
21
21
 
22
22
  Raises:
23
- _SDKException: If the app fails to start within 10 iterations (when infinite is False).
23
+ _SDKException: If the response code is not 200 after 5 attempts (if finite) or if the response code is 409.
24
24
 
25
25
  Returns:
26
26
  None
27
27
  """
28
- from time import sleep
28
+ import logging
29
29
 
30
30
  counter = 0
31
- try:
32
- response = function(*args, **kwargs)
33
- if type(response) is bool:
34
- while not response:
35
- counter += 1
36
- if not infinite and counter > 10:
37
- raise _exceptions.SDKException(-1, response)
38
- sleep(5)
39
- response = function(*args, **kwargs)
40
- elif type(response) is dict:
41
- while response["code"] != 200:
42
- counter += 1
43
- if not infinite and counter > 10:
44
- raise _exceptions.SDKException(-1, response)
45
- sleep(5)
46
- response = function(*args, **kwargs)
47
- else:
48
- raise _exceptions.SDKException(-1, response)
49
- except _exceptions.SDKException as e:
50
- import logging
51
-
52
- if e.code == 409:
53
- logging.warning(e)
54
- else:
55
- raise e
56
- else:
57
- return response
31
+ while True:
32
+ try:
33
+ counter += 1
34
+ response = function(*args, **kwargs)
35
+
36
+ if type(response) is bool:
37
+ if response:
38
+ break
39
+ elif type(response) is dict:
40
+ if response["code"] == 409:
41
+ raise _exceptions.SDKException(409, response)
42
+ return response
43
+ except _exceptions.SDKException as e:
44
+ if e.code == 409:
45
+ logging.warning(e)
46
+ return
47
+ logging.error(e)
48
+ finally:
49
+ if not infinite and counter > 4:
50
+ raise _exceptions.SDKException(
51
+ -1, "Response code not 200 after 5 attempts."
52
+ )
58
53
 
59
54
 
60
55
  def stop_function_loop(function, infinite: bool = True, *args, **kwargs):
@@ -68,32 +63,35 @@ def stop_function_loop(function, infinite: bool = True, *args, **kwargs):
68
63
  **kwargs: Arbitrary keyword arguments to be passed to the function.
69
64
 
70
65
  Raises:
71
- _SDKException: If the app fails to stop within 10 attempts (when infinite is False).
66
+ _SDKException: If the response code is not 200 after 5 attempts (if finite) or if the response code is 404.
72
67
 
73
68
  Returns:
74
69
  None
75
70
  """
76
- from time import sleep
71
+ import logging
77
72
 
78
73
  counter = 0
79
- response = function(*args, **kwargs)
80
- if type(response) is bool:
81
- while not response:
82
- counter += 1
83
- if not infinite and counter > 10:
84
- raise _exceptions.SDKException(-1, response)
85
- sleep(5)
86
- response = function(*args, **kwargs)
87
- elif type(response) is dict:
88
- while response["code"] != 200:
74
+ while True:
75
+ try:
89
76
  counter += 1
90
- if not infinite and counter > 10:
91
- raise _exceptions.SDKException(-1, response)
92
- sleep(5)
93
77
  response = function(*args, **kwargs)
94
- else:
95
- raise _exceptions.SDKException(-1, response)
96
- return response
78
+ if type(response) is bool:
79
+ if not response:
80
+ break
81
+ elif type(response) is dict:
82
+ if response["code"] == 404:
83
+ raise _exceptions.SDKException(404, response)
84
+ return response
85
+ except _exceptions.SDKException as e:
86
+ if e.code == 404:
87
+ logging.warning(e)
88
+ return
89
+ logging.error(e)
90
+ finally:
91
+ if not infinite and counter > 4:
92
+ raise _exceptions.SDKException(
93
+ -1, "Response code not 200 after 5 attempts."
94
+ )
97
95
 
98
96
 
99
97
  def compute_list():
@@ -116,6 +114,7 @@ def compute_list():
116
114
  class ResourceTypes(_Enum):
117
115
  compute = "compute"
118
116
  db = "db"
117
+ job = "job"
119
118
 
120
119
 
121
120
  def _resource_status_ready(name: str, response: dict):
@@ -266,7 +265,7 @@ def compute_create_custom(
266
265
  request=_requests_helper.EndpointTypes.post,
267
266
  url=url,
268
267
  headers=headers,
269
- data=_json.dumps(__payload),
268
+ data=_json.dumps(__payload).encode("utf-8"),
270
269
  )
271
270
 
272
271
  return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(
@@ -302,7 +301,7 @@ def resource_update_port(
302
301
  request=_requests_helper.EndpointTypes.post,
303
302
  url=url,
304
303
  headers=headers,
305
- data=_json.dumps(__payload),
304
+ data=_json.dumps(__payload).encode("utf-8"),
306
305
  )
307
306
 
308
307
  return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(
@@ -336,7 +335,7 @@ def resource_add_port(name: str, port_name: str, new_port: int, ingress: bool =
336
335
  request=_requests_helper.EndpointTypes.post,
337
336
  url=url,
338
337
  headers=headers,
339
- data=_json.dumps(__payload),
338
+ data=_json.dumps(__payload).encode("utf-8"),
340
339
  )
341
340
 
342
341
  return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(
@@ -369,7 +368,7 @@ def resource_delete_port(
369
368
  request=_requests_helper.EndpointTypes.post,
370
369
  url=url,
371
370
  headers=headers,
372
- data=_json.dumps(__payload),
371
+ data=_json.dumps(__payload).encode("utf-8"),
373
372
  )
374
373
 
375
374
  return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(
@@ -417,7 +416,7 @@ def resource_delete(name: str):
417
416
  request=_requests_helper.EndpointTypes.delete,
418
417
  url=url,
419
418
  headers=headers,
420
- data=_json.dumps(__payload),
419
+ data=_json.dumps(__payload).encode("utf-8"),
421
420
  )
422
421
 
423
422
  return _response_utils.retrieve_and_validate_response_send_metric_for_sdk(