oscar-python 1.3.4__py3-none-any.whl → 2.0.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.
@@ -59,7 +59,7 @@ class S3(StorageProvider):
59
59
  bucket_name = remote_path.split('/')[0]
60
60
  file_key = remote_path.split('/', 1)[1]
61
61
  file_name = local_path.split('/')[-1]
62
- print("Uploading to bucket '{0}' with key '{1}'".format(bucket_name,file_key))
62
+ print("Uploading to bucket '{0}' with key '{1}'".format(bucket_name, file_key))
63
63
  with open(local_path, 'rb') as data:
64
64
  try:
65
65
  self.client.upload_fileobj(data, bucket_name, file_key + "/" + file_name)
oscar_python/_utils.py CHANGED
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import base64
16
+ import json
16
17
  import os
17
18
  import requests
18
19
  import liboidcagent as agent
@@ -32,14 +33,16 @@ def make_request(c, path, method, **kwargs):
32
33
  url = c.endpoint+path
33
34
 
34
35
  if method in ["post", "put"]:
35
- if "token" in kwargs.keys() and kwargs["token"]:
36
+ if "token" in kwargs.keys() and kwargs["token"]:
36
37
  headers = get_headers_with_token(kwargs["token"])
38
+ req_kwargs = {"headers": headers, "verify": c.ssl, "timeout": timeout}
37
39
  if "data" in kwargs.keys() and kwargs["data"]:
38
- result = requests.request(method, url, headers=headers, verify=c.ssl, data=kwargs["data"], timeout=timeout)
40
+ req_kwargs["data"] = kwargs["data"]
41
+ result = requests.request(method, url, **req_kwargs)
39
42
  else:
40
43
  result = requests.request(method, url, headers=headers, verify=c.ssl, timeout=timeout)
41
44
 
42
- if "handle" in kwargs.keys() and kwargs["handle"] == False:
45
+ if "handle" in kwargs.keys() and kwargs["handle"] is False:
43
46
  return result
44
47
 
45
48
  result.raise_for_status()
@@ -94,7 +97,7 @@ def decode_b64(b64_str, file_out):
94
97
  except ValueError:
95
98
  print('Error decoding output: Invalid base64 string.')
96
99
  except OSError:
97
- print('Error decoding output: Failed to write decoded data to file.')
100
+ print('Error decoding output: Failed to write decoded data to file.')
98
101
 
99
102
 
100
103
  def encode_input(data):
@@ -111,6 +114,21 @@ def encode_input(data):
111
114
  return base64.b64encode(message_bytes)
112
115
 
113
116
 
117
+ def load_config(config_path, cluster_name="default"):
118
+ with open(config_path) as f:
119
+ config = json.load(f)
120
+ cluster = config["clusters"][cluster_name]
121
+ opts = {
122
+ "cluster_id": cluster_name,
123
+ "endpoint": cluster["endpoint"],
124
+ "ssl": cluster.get("ssl", True),
125
+ }
126
+ for key in ("user", "password", "shortname", "oidc_token", "refresh_token"):
127
+ if key in cluster:
128
+ opts[key] = cluster[key]
129
+ return opts
130
+
131
+
114
132
  def decode_output(output, file_path):
115
133
  if isBase64(output):
116
134
  decode_b64(output, file_path)
oscar_python/client.py CHANGED
@@ -27,7 +27,12 @@ _CONFIG_PATH = "/system/config"
27
27
  _SVC_PATH = "/system/services"
28
28
  _LOGS_PATH = "/system/logs"
29
29
  _RUN_PATH = "/run"
30
- _STATUS_PATH="/system/status"
30
+ _STATUS_PATH = "/system/status"
31
+ _HEALTH_PATH = "/health"
32
+ _VOLUMES_PATH = "/system/volumes"
33
+ _BUCKETS_PATH = "/system/buckets"
34
+ _METRICS_PATH = "/system/metrics"
35
+ _QUOTAS_USER_PATH = "/system/quotas/user"
31
36
 
32
37
 
33
38
  # _JOB_PATH = "/job"
@@ -101,13 +106,13 @@ class Client(DefaultClient):
101
106
  """ Creates a generic storage client to interact with the storage providers
102
107
  defined on a specific service of the refered OSCAR cluster """
103
108
  def create_storage_client(self, svc=None):
104
- if svc != None:
109
+ if svc is not None:
105
110
  return Storage(
106
111
  client_obj=self, svc_name=svc)
107
112
  else:
108
113
  return Storage(
109
114
  client_obj=self)
110
-
115
+
111
116
  """ Function to get cluster info """
112
117
  def get_cluster_info(self):
113
118
  return utils.make_request(self, _INFO_PATH, _GET)
@@ -137,17 +142,18 @@ class Client(DefaultClient):
137
142
  raise Exception("FDL clusterID does not match current clusterID: {0}".format(err))
138
143
  try:
139
144
  if os.path.isabs(svc["script"]):
140
- script_path = svc["script"]
145
+ script_path = svc["script"]
141
146
  else:
142
147
  fdl_directory = os.path.dirname(fdl_path)
143
148
  script_path = os.path.join(fdl_directory, svc['script'])
144
149
  with open(script_path) as s:
145
150
  svc["script"] = s.read()
146
- except IOError as e:
151
+ except IOError:
147
152
  raise Exception("Couldn't read script")
148
153
 
149
154
  # cpu parameter has to be string on the request
150
- if type(svc["cpu"]) is int or type(svc["cpu"]) is float: svc["cpu"] = str(svc["cpu"])
155
+ if type(svc["cpu"]) is int or type(svc["cpu"]) is float:
156
+ svc["cpu"] = str(svc["cpu"])
151
157
 
152
158
  except ValueError as err:
153
159
  print(err)
@@ -226,3 +232,111 @@ class Client(DefaultClient):
226
232
  """ Remove all service jobs """
227
233
  def remove_all_jobs(self, svc):
228
234
  return utils.make_request(self, _LOGS_PATH+"/"+svc, _DELETE)
235
+
236
+ """ Check cluster health """
237
+ def health_check(self):
238
+ return utils.make_request(self, _HEALTH_PATH, _GET)
239
+
240
+ """ Get deployment status of a service """
241
+ def get_deployment_status(self, name):
242
+ return utils.make_request(self, _SVC_PATH + "/" + name + "/deployment", _GET)
243
+
244
+ """ Get deployment logs of a service """
245
+ def get_deployment_logs(self, name):
246
+ return utils.make_request(self, _SVC_PATH + "/" + name + "/deployment/logs", _GET)
247
+
248
+ """ List all managed volumes """
249
+ def list_volumes(self):
250
+ return utils.make_request(self, _VOLUMES_PATH, _GET)
251
+
252
+ """ Create a new managed volume """
253
+ def create_volume(self, name, size):
254
+ data = json.dumps({"name": name, "size": size})
255
+ return utils.make_request(self, _VOLUMES_PATH, _POST, data=data)
256
+
257
+ """ Get a specific managed volume """
258
+ def get_volume(self, name):
259
+ return utils.make_request(self, _VOLUMES_PATH + "/" + name, _GET)
260
+
261
+ """ Delete a managed volume """
262
+ def delete_volume(self, name):
263
+ return utils.make_request(self, _VOLUMES_PATH + "/" + name, _DELETE)
264
+
265
+ """ Create a bucket """
266
+ def create_bucket(self, name, visibility="private", allowed_users=None):
267
+ data = json.dumps({
268
+ "bucket_name": name,
269
+ "visibility": visibility,
270
+ "allowed_users": allowed_users or []
271
+ })
272
+ return utils.make_request(self, _BUCKETS_PATH, _POST, data=data)
273
+
274
+ """ Update a bucket """
275
+ def update_bucket(self, name, visibility, allowed_users=None):
276
+ data = json.dumps({
277
+ "bucket_name": name,
278
+ "visibility": visibility,
279
+ "allowed_users": allowed_users or []
280
+ })
281
+ return utils.make_request(self, _BUCKETS_PATH, _PUT, data=data)
282
+
283
+ """ List all buckets """
284
+ def list_buckets(self):
285
+ return utils.make_request(self, _BUCKETS_PATH, _GET)
286
+
287
+ """ Get a specific bucket """
288
+ def get_bucket(self, name):
289
+ return utils.make_request(self, _BUCKETS_PATH + "/" + name, _GET)
290
+
291
+ """ Delete a bucket """
292
+ def delete_bucket(self, name):
293
+ return utils.make_request(self, _BUCKETS_PATH + "/" + name, _DELETE)
294
+
295
+ """ Get a presigned URL for a bucket file """
296
+ def presign_bucket(self, name, object_key, operation="download", expires=0, content_type="", extra_headers=None):
297
+ path = _BUCKETS_PATH + "/" + name + "/presign"
298
+ data = json.dumps({
299
+ "object_key": object_key,
300
+ "operation": operation,
301
+ "expires": expires,
302
+ "content_type": content_type,
303
+ "extra_headers": extra_headers or {},
304
+ })
305
+ return utils.make_request(self, path, _POST, data=data)
306
+
307
+ """ Get system logs (admin only) """
308
+ def get_system_logs(self, timestamps=False, previous=False):
309
+ path = _LOGS_PATH
310
+ params = []
311
+ if timestamps:
312
+ params.append("timestamps=true")
313
+ if previous:
314
+ params.append("previous=true")
315
+ if params:
316
+ path += "?" + "&".join(params)
317
+ return utils.make_request(self, path, _GET)
318
+
319
+ """ Get metrics summary """
320
+ def get_metrics_summary(self):
321
+ return utils.make_request(self, _METRICS_PATH, _GET)
322
+
323
+ """ Get metrics breakdown """
324
+ def get_metrics_breakdown(self, group_by="service"):
325
+ return utils.make_request(self, _METRICS_PATH + "/breakdown?group_by=" + group_by, _GET)
326
+
327
+ """ Get metrics for a specific service """
328
+ def get_service_metrics(self, service_name):
329
+ return utils.make_request(self, _METRICS_PATH + "/" + service_name, _GET)
330
+
331
+ """ Get own quota """
332
+ def get_own_quota(self):
333
+ return utils.make_request(self, _QUOTAS_USER_PATH, _GET)
334
+
335
+ """ Get quota for a specific user """
336
+ def get_user_quota(self, user_id):
337
+ return utils.make_request(self, _QUOTAS_USER_PATH + "/" + user_id, _GET)
338
+
339
+ """ Update quota for a user """
340
+ def update_user_quota(self, user_id, cpu, memory):
341
+ data = json.dumps({"cpu": cpu, "memory": memory})
342
+ return utils.make_request(self, _QUOTAS_USER_PATH + "/" + user_id, _PUT, data=data)
@@ -1,6 +1,6 @@
1
1
  from client import Client
2
2
 
3
- client = Client("oscar-gpu-cluster","https://focused-boyd8.im.grycap.net", "oscar", "oscar123", True)
3
+ client = Client("oscar-gpu-cluster", "https://focused-boyd8.im.grycap.net", "oscar", "oscar123", True)
4
4
 
5
5
  res = client.remove_service("cowsay")
6
6
  if res:
oscar_python/storage.py CHANGED
@@ -31,10 +31,10 @@ _SVC_PATH = "/system/services"
31
31
 
32
32
  # TODO check returns from functions
33
33
  class Storage:
34
- def __init__(self, client_obj, svc_name = None) -> None:
34
+ def __init__(self, client_obj, svc_name=None) -> None:
35
35
  self.client_obj = client_obj
36
36
  self.storage_providers = {}
37
- if svc_name != None:
37
+ if svc_name is not None:
38
38
  self.svc_name = svc_name
39
39
  self._store_provider_from_service()
40
40
  self._store_default_minio_provider()
@@ -46,13 +46,12 @@ class Storage:
46
46
 
47
47
  """ Function to store the user credentials for the default MinIO provider """
48
48
  def _store_default_minio_provider(self):
49
- config = utils.make_request(self.client_obj, _CONFIG_PATH + "/" , _GET)
49
+ config = utils.make_request(self.client_obj, _CONFIG_PATH + "/", _GET)
50
50
  if _MINIO in self.storage_providers:
51
51
  self.storage_providers[_MINIO]["default"] = json.loads(config.text)["minio_provider"]
52
52
  else:
53
53
  default = {"default": json.loads(config.text)["minio_provider"]}
54
54
  self.storage_providers[_MINIO] = default
55
-
56
55
 
57
56
  """ Function to retreive credentials of a specific storage provider """
58
57
  def _get_provider_creds(self, provider, provider_name):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oscar-python
3
- Version: 1.3.4
3
+ Version: 2.0.0
4
4
  Summary: Python client for OSCAR clusters
5
5
  Author: GRyCAP - I3M - UPV
6
6
  License: Apache-2.0
@@ -1,18 +1,18 @@
1
1
  oscar_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  oscar_python/_oidc.py,sha256=0JqOuASAnyOVWKxqIWFN9jFZgYY4p-rZwa8Lq3JWfNk,2611
3
- oscar_python/_utils.py,sha256=e6DJA_Vziy-3xt_-MEOg_7CM2mNIJNqCaFKD79Spug4,3707
4
- oscar_python/client.py,sha256=Xp2J2Jd3_9diLooMlUpX63tkSMSmjyXsKoFp5DxNGkg,9043
3
+ oscar_python/_utils.py,sha256=OxQu5Bv_CSvsbTxQcGCfvO_PEaBDGngWotIMsFPxb5s,4247
4
+ oscar_python/client.py,sha256=kMFnVr1lbatf1X8FFbPIY0AI8jgIlkBAoyNR1yB99xU,13353
5
5
  oscar_python/client_anon.py,sha256=glGC0kfb2iTTcdFhY5oBtQT7l4OriZfSkswQ3icS_YM,311
6
6
  oscar_python/default_client.py,sha256=jjIoZ_BkIkCchlTiUoWddEz6UhCFOEVZMCYcSh-E_y8,1154
7
- oscar_python/local_test.py,sha256=0i_vGn-N735pvx1JcG4GmjpNmqwXmx5LExVELtW5ECs,251
8
- oscar_python/storage.py,sha256=BVQ7NHqY5OT2WBXqGTsshCX9b0FNqc0SqMoawvsWxiI,3976
7
+ oscar_python/local_test.py,sha256=8UN86bho2JkjVjcOtQiBvZepjFdacEJ8FIDLxOBXlIM,252
8
+ oscar_python/storage.py,sha256=__GkTbJ_uHzRxcSO_CgXpryRWJVNttUnM43ET83MGqs,3968
9
9
  oscar_python/_providers/_minio.py,sha256=k74Xh11Gk6xkKhIMq3jY-4Xq-jpxiZSMc2RLS6WUuq0,1267
10
10
  oscar_python/_providers/_onedata.py,sha256=wKxSAO77ipy8Wm-sybqPo_l2BZYg0cj9B53Ebc92kFs,3469
11
11
  oscar_python/_providers/_providers_base.py,sha256=Wmse3xheb1UQRulF2IdtJkq2w96l21anQVAA2ChI63Y,1202
12
- oscar_python/_providers/_s3.py,sha256=kVK6GhkCqRDvUOzopsRFgt9ZS-KK2ugjPRqJYJG9MO8,3260
12
+ oscar_python/_providers/_s3.py,sha256=Uwgd8RM0reQEdHprrjivFLJIVhFBhvHt3pE1lENpKrs,3261
13
13
  oscar_python/_providers/_webdav.py,sha256=Nt0w87L9K6iGLoMOgHoSfiZpjOd1eYkvuJ8Kopf2IQU,2332
14
- oscar_python-1.3.4.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
15
- oscar_python-1.3.4.dist-info/METADATA,sha256=GXveCYiEk8vZSQGbde50odDqlYzf0D6VVeEUkO9e5Jc,9612
16
- oscar_python-1.3.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
17
- oscar_python-1.3.4.dist-info/top_level.txt,sha256=0sLOepeO4vz_8o3vBJyTRRvgJN1TFF1T3SESlIwoJQk,13
18
- oscar_python-1.3.4.dist-info/RECORD,,
14
+ oscar_python-2.0.0.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
15
+ oscar_python-2.0.0.dist-info/METADATA,sha256=-Y3snOPm_npxgZXlI94guglmgLYFzn94R1BbKQN4S2Y,9612
16
+ oscar_python-2.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
17
+ oscar_python-2.0.0.dist-info/top_level.txt,sha256=0sLOepeO4vz_8o3vBJyTRRvgJN1TFF1T3SESlIwoJQk,13
18
+ oscar_python-2.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.2)
2
+ Generator: setuptools (82.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5