oscar-python 1.3.2__py3-none-any.whl → 1.3.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.
oscar_python/_oidc.py CHANGED
@@ -77,14 +77,14 @@ class OIDC(object):
77
77
  return True
78
78
 
79
79
  @staticmethod
80
- def refresh_access_token(refresh_token, scopes, token_endpoint):
80
+ def refresh_access_token(refresh_token, scopes, token_endpoint, client_id="token-portal"):
81
81
  """
82
82
  Refresh the access token using the refresh token
83
83
  """
84
84
  data = {
85
85
  'grant_type': 'refresh_token',
86
86
  'refresh_token': refresh_token,
87
- 'client_id': 'token-portal',
87
+ 'client_id': client_id,
88
88
  'scope': ' '.join(scopes)
89
89
  }
90
90
 
oscar_python/client.py CHANGED
@@ -41,6 +41,7 @@ _DELETE = "delete"
41
41
  # Default values for OIDC refresh token using EGI CheckIn
42
42
  _DEFAULT_SCOPES = ['openid', 'email', 'profile', 'voperson_id', 'eduperson_entitlement']
43
43
  _DEFAULT_TOKEN_ENDPOINT = 'https://aai.egi.eu/auth/realms/egi/protocol/openid-connect/token'
44
+ _DEFAULT_CLIENT_ID = 'token-portal'
44
45
 
45
46
 
46
47
  class Client(DefaultClient):
@@ -72,6 +73,8 @@ class Client(DefaultClient):
72
73
  self.token_endpoint = options.get('token_endpoint',
73
74
  _DEFAULT_TOKEN_ENDPOINT)
74
75
  self.ssl = bool(options['ssl'])
76
+ self.client_id = options.get('client_id',
77
+ _DEFAULT_CLIENT_ID)
75
78
 
76
79
  def set_auth_type(self, options):
77
80
  if 'user' in options:
@@ -91,7 +94,8 @@ class Client(DefaultClient):
91
94
  if self.refresh_token and OIDC.is_access_token_expired(self.oidc_token):
92
95
  self.oidc_token = OIDC.refresh_access_token(self.refresh_token,
93
96
  self.scopes,
94
- self.token_endpoint)
97
+ self.token_endpoint,
98
+ self.client_id)
95
99
  return self.oidc_token
96
100
 
97
101
  """ Creates a generic storage client to interact with the storage providers
@@ -132,9 +136,14 @@ class Client(DefaultClient):
132
136
  except KeyError as err:
133
137
  raise Exception("FDL clusterID does not match current clusterID: {0}".format(err))
134
138
  try:
135
- with open(svc["script"]) as s:
139
+ if os.path.isabs(svc["script"]):
140
+ script_path = svc["script"]
141
+ else:
142
+ fdl_directory = os.path.dirname(fdl_path)
143
+ script_path = os.path.join(fdl_directory, svc['script'])
144
+ with open(script_path) as s:
136
145
  svc["script"] = s.read()
137
- except IOError:
146
+ except IOError as e:
138
147
  raise Exception("Couldn't read script")
139
148
 
140
149
  # cpu parameter has to be string on the request
@@ -205,8 +214,8 @@ class Client(DefaultClient):
205
214
  return utils.make_request(self, _LOGS_PATH+"/"+svc+"/"+job, _GET)
206
215
 
207
216
  """ List a service jobs """
208
- def list_jobs(self, svc):
209
- return utils.make_request(self, _LOGS_PATH+"/"+svc, _GET)
217
+ def list_jobs(self, svc, page=""):
218
+ return utils.make_request(self, _LOGS_PATH+"/"+svc+"?page="+page, _GET)
210
219
 
211
220
  """ Remove a service job """
212
221
  def remove_job(self, svc, job):
@@ -1,37 +1,30 @@
1
1
  Metadata-Version: 2.4
2
- Name: oscar_python
3
- Version: 1.3.2
4
- Summary: OSCAR API for python
5
- Home-page: https://github.com/grycap/oscar_python
6
- Author: GRyCAP - Universitat Politecnica de Valencia
7
- Author-email: calarcon@i3m.upv.es
8
- License: Apache 2.0
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: Apache Software License
2
+ Name: oscar-python
3
+ Version: 1.3.3
4
+ Summary: Python client for OSCAR clusters
5
+ Author: GRyCAP - I3M - UPV
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/grycap/oscar-python
8
+ Project-URL: Repository, https://github.com/grycap/oscar-python
9
+ Keywords: oscar,faas,serverless
10
+ Requires-Python: >=3.8
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
- Requires-Dist: webdavclient3==3.14.6
14
13
  Requires-Dist: requests
14
+ Requires-Dist: webdavclient3>=3.14.6
15
15
  Requires-Dist: boto3
16
- Requires-Dist: setuptools>=40.8.0
17
16
  Requires-Dist: pyyaml
18
17
  Requires-Dist: aiohttp
19
18
  Requires-Dist: liboidcagent
20
- Dynamic: author
21
- Dynamic: author-email
22
- Dynamic: classifier
23
- Dynamic: description
24
- Dynamic: description-content-type
25
- Dynamic: home-page
26
- Dynamic: license
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest; extra == "dev"
21
+ Requires-Dist: pytest-cov; extra == "dev"
27
22
  Dynamic: license-file
28
- Dynamic: requires-dist
29
- Dynamic: summary
30
23
 
31
24
  ## Python OSCAR client
32
25
 
33
- [![Build](https://github.com/grycap/oscar_python/actions/workflows/release.yaml/badge.svg)](https://github.com/grycap/oscar_python/actions/workflows/main.yaml)
34
- ![PyPI](https://img.shields.io/pypi/v/oscar_python)
26
+ [![Tests](https://github.com/grycap/oscar_python/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/grycap/oscar_python/actions/workflows/tests.yaml)
27
+ [![PyPI](https://img.shields.io/pypi/v/oscar-python)](https://pypi.org/project/oscar-python/)
35
28
 
36
29
  This package provides a client to interact with OSCAR (https://oscar.grycap.net) clusters and services. It is available on Pypi with the name [oscar-python](https://pypi.org/project/oscar-python/).
37
30
 
@@ -107,6 +100,7 @@ and `scopes`:
107
100
  'refresh_token':'token',
108
101
  'scopes': ["openid", "profile", "email"],
109
102
  'token_endpoint': "http://issuer.com/token",
103
+ 'client_id': "your_client_id"
110
104
  'ssl':'True'}
111
105
 
112
106
  client = Client(options = options_oidc_auth)
@@ -231,6 +225,8 @@ logs = client.get_job_logs("service_name", "job_id") # returns an http response
231
225
  ``` python
232
226
  # get a list of jobs in a service
233
227
  log_list = client.list_jobs("service_name") # returns an http response
228
+ # to get more jobs use the page parameter
229
+ log_list = client.list_jobs("service_name",page="token_to_next_page") # returns an http response
234
230
  ```
235
231
 
236
232
  **remove_job**
@@ -0,0 +1,18 @@
1
+ oscar_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
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=eM9FaxEVZnqlLa_Z9Hf4Pgqf63UUNT0BqyXb2SSgrcw,8957
5
+ oscar_python/client_anon.py,sha256=glGC0kfb2iTTcdFhY5oBtQT7l4OriZfSkswQ3icS_YM,311
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
9
+ oscar_python/_providers/_minio.py,sha256=k74Xh11Gk6xkKhIMq3jY-4Xq-jpxiZSMc2RLS6WUuq0,1267
10
+ oscar_python/_providers/_onedata.py,sha256=wKxSAO77ipy8Wm-sybqPo_l2BZYg0cj9B53Ebc92kFs,3469
11
+ oscar_python/_providers/_providers_base.py,sha256=Wmse3xheb1UQRulF2IdtJkq2w96l21anQVAA2ChI63Y,1202
12
+ oscar_python/_providers/_s3.py,sha256=kVK6GhkCqRDvUOzopsRFgt9ZS-KK2ugjPRqJYJG9MO8,3260
13
+ oscar_python/_providers/_webdav.py,sha256=Nt0w87L9K6iGLoMOgHoSfiZpjOd1eYkvuJ8Kopf2IQU,2332
14
+ oscar_python-1.3.3.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
15
+ oscar_python-1.3.3.dist-info/METADATA,sha256=efgJdP09L39GOldIBgrG9xnsn70XU0mn4DP_DptFhiE,9612
16
+ oscar_python-1.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ oscar_python-1.3.3.dist-info/top_level.txt,sha256=0sLOepeO4vz_8o3vBJyTRRvgJN1TFF1T3SESlIwoJQk,13
18
+ oscar_python-1.3.3.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+ oscar_python
@@ -1,26 +0,0 @@
1
- oscar_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- oscar_python/_oidc.py,sha256=Rhsw0ywfkZvDOElMOK8DOBfBkA2H_NmbBn5_0bQoo34,2590
3
- oscar_python/_utils.py,sha256=e6DJA_Vziy-3xt_-MEOg_7CM2mNIJNqCaFKD79Spug4,3707
4
- oscar_python/client.py,sha256=3W55myFdqaMZ9zQVfj3iOcw8QUVzXxvWImsMN7-RLAQ,8416
5
- oscar_python/client_anon.py,sha256=glGC0kfb2iTTcdFhY5oBtQT7l4OriZfSkswQ3icS_YM,311
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
9
- oscar_python/_providers/_minio.py,sha256=k74Xh11Gk6xkKhIMq3jY-4Xq-jpxiZSMc2RLS6WUuq0,1267
10
- oscar_python/_providers/_onedata.py,sha256=wKxSAO77ipy8Wm-sybqPo_l2BZYg0cj9B53Ebc92kFs,3469
11
- oscar_python/_providers/_providers_base.py,sha256=Wmse3xheb1UQRulF2IdtJkq2w96l21anQVAA2ChI63Y,1202
12
- oscar_python/_providers/_s3.py,sha256=kVK6GhkCqRDvUOzopsRFgt9ZS-KK2ugjPRqJYJG9MO8,3260
13
- oscar_python/_providers/_webdav.py,sha256=Nt0w87L9K6iGLoMOgHoSfiZpjOd1eYkvuJ8Kopf2IQU,2332
14
- oscar_python-1.3.2.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
15
- tests/test_client.py,sha256=arhLqBVCWVfbVAKaNY3mavAz0hW16odmqY8QI8SyX5o,5097
16
- tests/test_default_client.py,sha256=hXWUHS1UI-GWTtK1D6lA8xW8TpgUhzlIbP4mOhiyY-o,2606
17
- tests/test_oidc.py,sha256=SBeKfXHH_Rej1I1xt6Tripy7GALPVohqnb03PMTRPYs,1641
18
- tests/test_onedata.py,sha256=XwAQ6GCMHecM8ak8XMjkM5X9JTlajrvQXHsy6-eMYOM,2586
19
- tests/test_s3.py,sha256=M-PsoGtc006is8dTXWVl7Q2rOJ6ZroMBE6EO49gLdXA,1882
20
- tests/test_storage.py,sha256=JaD-Vs1nJVN7FH4jljvsogWaGmO2MoQn6Xza7PoyhEg,1879
21
- tests/test_utils.py,sha256=RfzBpmc0HhLklLUs9ukZx7bStHlL0JBYn3q9i5mJHQM,3307
22
- tests/test_webdav.py,sha256=Vv0y2CrXAt8z73lgpmC81Vib16qlguGgwTxB9JEcq14,1568
23
- oscar_python-1.3.2.dist-info/METADATA,sha256=dV_lqMzrc-MhM8BkvtAs2vEZnavMqEsEfdMRDZwwgsM,9525
24
- oscar_python-1.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- oscar_python-1.3.2.dist-info/top_level.txt,sha256=JlQqH-wbX-NZn0xlDIEZUOMjymNz_9fHfC4goTMZaPY,35
26
- oscar_python-1.3.2.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
- jupyter_example
2
- oscar_python
3
- tests
tests/test_client.py DELETED
@@ -1,138 +0,0 @@
1
- import pytest
2
- import json
3
- from unittest.mock import patch, mock_open
4
- from oscar_python.client import Client
5
-
6
-
7
- @pytest.fixture
8
- def options():
9
- return {
10
- 'cluster_id': 'test_cluster',
11
- 'endpoint': 'http://test.endpoint',
12
- 'user': 'test_user',
13
- 'password': 'test_password',
14
- 'ssl': True,
15
- 'shortname': 'test_shortname',
16
- 'oidc_token': 'test_oidc_token'
17
- }
18
-
19
-
20
- def test_basic_auth_client(options):
21
- client = Client(options)
22
- assert client.id == options['cluster_id']
23
- assert client.endpoint == options['endpoint']
24
- assert client.user == options['user']
25
- assert client.password == options['password']
26
- assert client.ssl == options['ssl']
27
-
28
-
29
- def test_oidc_agent_client(options):
30
- del options['user']
31
- client = Client(options)
32
- assert client.id == options['cluster_id']
33
- assert client.endpoint == options['endpoint']
34
- assert client.shortname == options['shortname']
35
- assert client.ssl == options['ssl']
36
-
37
-
38
- def test_oidc_client(options):
39
- del options['user']
40
- del options['shortname']
41
- client = Client(options)
42
- assert client.id == options['cluster_id']
43
- assert client.endpoint == options['endpoint']
44
- assert client.oidc_token == options['oidc_token']
45
- assert client.ssl == options['ssl']
46
-
47
- del options['oidc_token']
48
- options['refresh_token'] = 'test_refresh_token'
49
- options['scopes'] = ['openid', 'profile', 'email']
50
- options['token_endpoint'] = 'test_token_endpoint'
51
- client = Client(options)
52
- assert client.refresh_token == options['refresh_token']
53
- assert client.scopes == ['openid', 'profile', 'email']
54
- assert client.token_endpoint == options['token_endpoint']
55
-
56
-
57
- def test_set_auth_type(options):
58
- client = Client(options)
59
- assert client._AUTH_TYPE == "basicauth"
60
-
61
- del options['user']
62
- client = Client(options)
63
- assert client._AUTH_TYPE == "oidc-agent"
64
-
65
- del options['shortname']
66
- options['oidc_token'] = 'test_oidc_token'
67
- client = Client(options)
68
- assert client._AUTH_TYPE == "oidc"
69
-
70
-
71
- def test_get_cluster_info(options):
72
- client = Client(options)
73
- with patch('oscar_python._utils.make_request') as mock_request:
74
- client.get_cluster_info()
75
- mock_request.assert_called_once_with(client, "/system/info", "get")
76
-
77
-
78
- def test_get_cluster_config(options):
79
- client = Client(options)
80
- with patch('oscar_python._utils.make_request') as mock_request:
81
- client.get_cluster_config()
82
- mock_request.assert_called_once_with(client, "/system/config", "get")
83
-
84
-
85
- def test_list_services(options):
86
- client = Client(options)
87
- with patch('oscar_python._utils.make_request') as mock_request:
88
- client.list_services()
89
- mock_request.assert_called_once_with(client, "/system/services", "get")
90
-
91
-
92
- def test_get_service(options):
93
- client = Client(options)
94
- with patch('oscar_python._utils.make_request') as mock_request:
95
- client.get_service("test_service")
96
- mock_request.assert_called_once_with(client, "/system/services/test_service", "get")
97
-
98
-
99
- def test_create_service_from_dict(options):
100
- client = Client(options)
101
- service_definition = {"name": "test_service"}
102
- with patch('oscar_python._utils.make_request') as mock_request:
103
- client.create_service(service_definition)
104
- mock_request.assert_called_with(client, "/system/services", "post",
105
- data=json.dumps(service_definition))
106
-
107
-
108
- def test_create_service_from_file(options):
109
- client = Client(options)
110
- service_definition = "functions:\n oscar:\n - test_cluster:\n name: test_service\n script: test_script\n cpu: 1"
111
- service_file = "path/to/service.yaml"
112
- with patch('os.path.isfile', return_value=True), \
113
- patch('builtins.open', mock_open(read_data=service_definition)), \
114
- patch('oscar_python._utils.make_request') as mock_request:
115
- client.create_service(service_file)
116
- assert mock_request.call_args[0][0] == client
117
- assert mock_request.call_args[0][1] == "/system/services"
118
- assert mock_request.call_args[0][2] == "post"
119
- assert json.loads(mock_request.call_args[1]['data']) == {"name": "test_service",
120
- "cpu": "1",
121
- "script": service_definition}
122
-
123
-
124
- def test_update_service_from_dict(options):
125
- client = Client(options)
126
- new_service = {"name": "test_service"}
127
- with patch('oscar_python._utils.make_request') as mock_request:
128
- mock_request.return_value.status_code = 200
129
- client.update_service("test_service", new_service)
130
- mock_request.assert_called_with(client, "/system/services",
131
- "put", data=json.dumps(new_service))
132
-
133
-
134
- def test_remove_service(options):
135
- client = Client(options)
136
- with patch('oscar_python._utils.make_request') as mock_request:
137
- client.remove_service("test_service")
138
- mock_request.assert_called_once_with(client, "/system/services/test_service", "delete")
@@ -1,61 +0,0 @@
1
- import pytest
2
- from unittest.mock import patch, MagicMock
3
- from oscar_python.default_client import DefaultClient, _RUN_PATH, _POST, _JOB_PATH
4
-
5
-
6
- class TestDefaultClient(DefaultClient):
7
- def _get_token(self, name):
8
- return "test_token"
9
-
10
-
11
- @pytest.fixture
12
- def client():
13
- return TestDefaultClient()
14
-
15
-
16
- @patch('oscar_python._utils.make_request')
17
- @patch('oscar_python._utils.encode_input')
18
- @patch('oscar_python._utils.decode_output')
19
- def test_run_service_with_input_and_token(mock_decode_output, mock_encode_input, mock_make_request, client):
20
- mock_response = MagicMock()
21
- mock_response.text = "response_text"
22
- mock_make_request.return_value = mock_response
23
- mock_encode_input.return_value = "encoded_input"
24
-
25
- response = client.run_service("test_service", input="test_input", token="test_token", output="output_file", timeout=30)
26
-
27
- mock_encode_input.assert_called_once_with("test_input")
28
- mock_make_request.assert_called_once_with(client, _RUN_PATH+"/test_service", _POST, data="encoded_input", token="test_token", timeout=30)
29
- mock_decode_output.assert_called_once_with("response_text", "output_file")
30
- assert response == mock_response
31
-
32
-
33
- @patch('oscar_python._utils.make_request')
34
- @patch('oscar_python._utils.encode_input')
35
- def test_run_service_with_input_no_token(mock_encode_input, mock_make_request, client):
36
- mock_response = MagicMock()
37
- mock_response.text = "response_text"
38
- mock_make_request.return_value = mock_response
39
- mock_encode_input.return_value = "encoded_input"
40
-
41
- response = client.run_service("test_service", input="test_input")
42
-
43
- mock_encode_input.assert_called_once_with("test_input")
44
- mock_make_request.assert_called_once_with(client, _RUN_PATH+"/test_service", _POST, data="encoded_input", token="test_token", timeout=None)
45
- assert response == mock_response
46
-
47
-
48
- @patch('oscar_python._utils.make_request')
49
- def test_run_service_no_input(mock_make_request, client):
50
- mock_response = MagicMock()
51
- mock_response.text = "response_text"
52
- mock_make_request.return_value = mock_response
53
-
54
- response = client.run_service("test_service", input="data")
55
- mock_make_request.assert_called_with(client, _RUN_PATH+"/test_service", _POST,
56
- token="test_token", data=b'ZGF0YQ==', timeout=None)
57
-
58
- response = client.run_service("test_service", input="data", async_call=True, timeout=30)
59
- mock_make_request.assert_called_with(client, _JOB_PATH+"/test_service", _POST,
60
- token="test_token", data=b'ZGF0YQ==', timeout=30)
61
- assert response == mock_response
tests/test_oidc.py DELETED
@@ -1,38 +0,0 @@
1
- from unittest.mock import patch, MagicMock
2
- from oscar_python._oidc import OIDC
3
-
4
-
5
- def test_is_access_token_expired():
6
- token = ("eyJraWQiOiJyc2ExIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkYzVkNWFiNy02ZGI5LTQwNzktOTg1Yy04MGFjMDUwMTcw"
7
- "NjYiLCJpc3MiOiJodHRwczpcL1wvaWFtLXRlc3QuaW5kaWdvLWRhdGFjbG91ZC5ldVwvIiwiZXhwIjoxNDY2MDkzOTE3LCJ"
8
- "pYXQiOjE0NjYwOTAzMTcsImp0aSI6IjE1OTU2N2U2LTdiYzItNDUzOC1hYzNhLWJjNGU5MmE1NjlhMCJ9.eINKxJa2J--xd"
9
- "GAZWIOKtx9Wi0Vz3xHzaSJWWY-UHWy044TQ5xYtt0VTvmY5Af-ngwAMGfyaqAAvNn1VEP-_fMYQZdwMqcXLsND4KkDi1ygiC"
10
- "IwQ3JBz9azBT1o_oAHE5BsPsE2BjfDoVRasZxxW5UoXCmBslonYd8HK2tUVjz0")
11
- assert OIDC.is_access_token_expired(token)
12
-
13
-
14
- def test_refresh_access_token():
15
- mock_response = MagicMock()
16
- mock_response.status_code = 200
17
- mock_response.json.return_value = {
18
- "access_token": "new_access_token",
19
- "expires_in": 3600,
20
- "refresh_token": "new_refresh_token"
21
- }
22
-
23
- with patch("requests.post") as mock_post:
24
- mock_post.return_value = mock_response
25
- access_token = OIDC.refresh_access_token("old_refresh_token",
26
- ["openid", "profile", "email"],
27
- "http://test.com/token")
28
-
29
- assert access_token == "new_access_token"
30
- mock_post.assert_called_once_with(
31
- "http://test.com/token",
32
- data={
33
- "grant_type": "refresh_token",
34
- "refresh_token": "old_refresh_token",
35
- "client_id": "token-portal",
36
- "scope": "openid profile email"
37
- }
38
- )
tests/test_onedata.py DELETED
@@ -1,66 +0,0 @@
1
- import pytest
2
- from oscar_python._providers._onedata import Onedata
3
- from unittest.mock import MagicMock, patch, mock_open
4
-
5
-
6
- @pytest.fixture
7
- def onedata():
8
- credentials = {
9
- "token": "token",
10
- "space": "space",
11
- "oneprovider_host": "oneprovider_host"
12
- }
13
- return Onedata(credentials)
14
-
15
-
16
- def test_onedata_initialization(onedata):
17
- assert isinstance(onedata, Onedata)
18
-
19
-
20
- @patch('oscar_python._providers._onedata.requests')
21
- def test_onedata_upload_file(mock_requests, onedata):
22
- mock_response = MagicMock()
23
- mock_response.status_code = 201
24
- mock_requests.put.return_value = mock_response
25
- with patch("builtins.open", mock_open()):
26
- response = onedata.upload_file('file_path', 'remote_path')
27
- assert response is None
28
- mock_requests.get.assert_called_with(
29
- url='https://oneprovider_host/cdmi/space//remote_path/',
30
- headers={'X-CDMI-Specification-Version': '1.1.1', 'X-Auth-Token': 'token'}
31
- )
32
- mock_requests.put.call_args_list[0][1]['url'] == 'https://oneprovider_host/cdmi/space//remote_path/file_path'
33
- mock_requests.put.call_args_list[0][1]['headers'] == {'X-Auth-Token', 'token'}
34
-
35
- mock_requests.put.call_args_list[1][0] == 'https://oneprovider_host/cdmi/space//remote_path/file_path'
36
- mock_requests.put.call_args_list[1][1]['headers'] == {'X-Auth-Token', 'token'}
37
-
38
-
39
- @patch('oscar_python._providers._onedata.requests')
40
- def test_onedata_download_file(mock_requests, onedata):
41
- mock_response = MagicMock()
42
- mock_response.status_code = 200
43
- mock_response.content = b'content'
44
- mock_requests.get.return_value = mock_response
45
- with patch("builtins.open", mock_open()) as mock_file:
46
- onedata.download_file('local_path', 'remote_path')
47
- mock_file.assert_called_with('local_path/remote_path', 'wb')
48
- mock_file().write.assert_called_with(b'content')
49
- mock_requests.get.assert_called_with(
50
- url='https://oneprovider_host/cdmi/space/remote_path',
51
- headers={'X-Auth-Token': 'token'}
52
- )
53
- mock_requests.get.return_value.content == b'content'
54
-
55
-
56
- @patch('oscar_python._providers._onedata.requests')
57
- def test_onedata_list_files_from_path(mock_requests, onedata):
58
- mock_response = MagicMock()
59
- mock_response.status_code = 200
60
- mock_requests.get.return_value = mock_response
61
- response = onedata.list_files_from_path('path')
62
- assert response == mock_response
63
- mock_requests.get.assert_called_with(
64
- url='https://oneprovider_host/cdmi/space/path/',
65
- headers={'X-CDMI-Specification-Version': '1.1.1', 'X-Auth-Token': 'token'}
66
- )
tests/test_s3.py DELETED
@@ -1,48 +0,0 @@
1
- import pytest
2
- from oscar_python._providers._s3 import S3
3
- from unittest.mock import MagicMock, patch, mock_open
4
-
5
-
6
- @pytest.fixture
7
- def s3_client():
8
- credentials = {
9
- "access_key": "access_key",
10
- "secret_key": "secret_key",
11
- "region": "region"
12
- }
13
- return S3(credentials)
14
-
15
-
16
- def test_s3_initialization(s3_client):
17
- assert s3_client is not None
18
-
19
-
20
- def test_s3_upload_file(s3_client):
21
- s3_client.client = MagicMock(["upload_fileobj"])
22
- with patch("builtins.open", mock_open(read_data="data")) as mock_file:
23
- result = s3_client.upload_file('path/file.txt', 'test_bucket/folder')
24
- mock_file.assert_called_once_with("path/file.txt", "rb")
25
- s3_client.client.upload_fileobj.assert_called_once()
26
- s3_client.client.upload_fileobj.call_args[0][1] == 'test_bucket'
27
- s3_client.client.upload_fileobj.call_args[0][2] == 'folder/file.txt'
28
- assert result is True
29
-
30
-
31
- def test_s3_download_file(s3_client):
32
- s3_client.client = MagicMock(["download_fileobj"])
33
- with patch("builtins.open", mock_open()) as mock_file:
34
- result = s3_client.download_file('path/folder', 'test_bucket/file.txt')
35
- mock_file.assert_called_once_with("path/folder/file.txt", "wb")
36
- s3_client.client.download_fileobj.assert_called_once()
37
- s3_client.client.download_fileobj.call_args[0][1] == 'test_bucket'
38
- s3_client.client.download_fileobj.call_args[0][2] == 'folder/file.txt'
39
- assert result is True
40
-
41
-
42
- def test_s3_list_files(s3_client):
43
- s3_client.client = MagicMock(["list_objects"])
44
- s3_client.client.list_objects.return_value = ['file1', 'file2']
45
- result = s3_client.list_files_from_path('test_bucket/*.txt')
46
- assert result == ['file1', 'file2']
47
- s3_client.client.list_objects.assert_called_once_with(Bucket='test_bucket',
48
- Prefix='*.txt')
tests/test_storage.py DELETED
@@ -1,51 +0,0 @@
1
- import pytest
2
- from unittest.mock import MagicMock, patch
3
- from oscar_python.storage import Storage
4
-
5
-
6
- @pytest.fixture
7
- def mock_client_obj():
8
- return MagicMock()
9
-
10
-
11
- @pytest.fixture
12
- def storage(mock_client_obj):
13
- mock_response = MagicMock()
14
- mock_response.text = '{"minio_provider": {"access_key": "key","secret_key": "secret", "endpoint": "http://test.endpoint", "region": "us-east-1", "verify": false}}'
15
- with patch('oscar_python._utils.make_request', return_value=mock_response):
16
- return Storage(mock_client_obj)
17
-
18
-
19
- def test_get_provider_creds(storage):
20
- creds = storage._get_provider_creds("minio", "default")
21
- assert creds["access_key"] == "key"
22
- assert creds["secret_key"] == "secret"
23
-
24
-
25
- def test_get_client_minio(storage):
26
- client = storage._get_client("minio.default")
27
- assert client.__class__.__name__ == "Minio"
28
-
29
-
30
- def test_list_files_from_path(storage):
31
- with patch.object(storage, '_get_client') as mock_get_client:
32
- mock_client = MagicMock()
33
- mock_get_client.return_value = mock_client
34
- storage.list_files_from_path("minio.default", "/path")
35
- mock_client.list_files_from_path.assert_called_once_with("/path")
36
-
37
-
38
- def test_upload_file(storage):
39
- with patch.object(storage, '_get_client') as mock_get_client:
40
- mock_client = MagicMock()
41
- mock_get_client.return_value = mock_client
42
- storage.upload_file("minio.default", "/local/path", "/remote/path")
43
- mock_client.upload_file.assert_called_once_with("/local/path", "/remote/path")
44
-
45
-
46
- def test_download_file(storage):
47
- with patch.object(storage, '_get_client') as mock_get_client:
48
- mock_client = MagicMock()
49
- mock_get_client.return_value = mock_client
50
- storage.download_file("minio.default", "/local/path", "/remote/path")
51
- mock_client.download_file.assert_called_once_with("/local/path", "/remote/path")
tests/test_utils.py DELETED
@@ -1,96 +0,0 @@
1
- import base64
2
- from unittest.mock import patch, MagicMock, mock_open
3
-
4
- import oscar_python._utils as utils
5
-
6
-
7
- def test_get_headers_with_basicauth():
8
- class MockClient:
9
- _AUTH_TYPE = "basicauth"
10
- user = "test_user"
11
- password = "test_password"
12
-
13
- c = MockClient()
14
- headers = utils.get_headers(c)
15
- assert headers["Authorization"].startswith("Basic ")
16
-
17
-
18
- def test_get_headers_with_oidc_agent():
19
- class MockClient:
20
- _AUTH_TYPE = "oidc-agent"
21
- shortname = "test_shortname"
22
-
23
- with patch("liboidcagent.get_access_token", return_value="test_token"):
24
- c = MockClient()
25
- headers = utils.get_headers(c)
26
- assert headers["Authorization"] == "Bearer test_token"
27
-
28
-
29
- def test_get_headers_with_oidc():
30
- class MockClient:
31
- _AUTH_TYPE = "oidc"
32
-
33
- def get_access_token(self):
34
- return "test_oidc_token"
35
-
36
- c = MockClient()
37
- headers = utils.get_headers(c)
38
- assert headers["Authorization"] == "Bearer test_oidc_token"
39
-
40
-
41
- def test_encode_input_with_string():
42
- test_data = "test_data"
43
- encoded = utils.encode_input(test_data)
44
- assert base64.b64encode(test_data.encode()) == encoded
45
-
46
-
47
- def test_decode_output_with_base64():
48
- test_data = base64.b64encode(b"test_data").decode("utf-8")
49
- with patch("builtins.open", mock_open()) as mock_file:
50
- utils.decode_output(test_data, "test_output.txt")
51
- mock_file.assert_called_once_with("test_output.txt", "w")
52
- mock_file().write.assert_called_once_with("test_data")
53
-
54
-
55
- def test_decode_output_with_string():
56
- test_data = base64.b64encode(b"test_data")
57
- with patch("builtins.open", mock_open()) as mock_file:
58
- utils.decode_output(test_data, "test_output.txt")
59
- mock_file.assert_called_once_with("test_output.txt", "w")
60
- mock_file().write.assert_called_once_with("test_data")
61
-
62
-
63
- def test_make_request_post():
64
- class MockClient:
65
- endpoint = "http://test.com"
66
- ssl = True
67
- _AUTH_TYPE = "basicauth"
68
- user = "test_user"
69
- password = "test_password"
70
-
71
- c = MockClient()
72
- with patch("requests.request") as mock_request:
73
- mock_request.return_value.status_code = 200
74
- mock_request.return_value.raise_for_status = MagicMock()
75
- response = utils.make_request(c, "/test", "post", data="test_data", token="test_token")
76
- assert response.status_code == 200
77
- mock_request.assert_called_once_with("post", "http://test.com/test", headers={"Authorization": "Bearer test_token"}, verify=True, data="test_data", timeout=60)
78
-
79
-
80
- def test_make_request_get():
81
- class MockClient:
82
- endpoint = "http://test.com"
83
- ssl = True
84
- _AUTH_TYPE = "basicauth"
85
- user = "test_user"
86
- password = "test_password"
87
-
88
- c = MockClient()
89
- with patch("requests.request") as mock_request:
90
- mock_request.return_value.status_code = 200
91
- mock_request.return_value.raise_for_status = MagicMock()
92
- response = utils.make_request(c, "/test", "get")
93
- assert response.status_code == 200
94
- mock_request.assert_called_once_with("get", "http://test.com/test",
95
- headers={'Authorization': 'Basic dGVzdF91c2VyOnRlc3RfcGFzc3dvcmQ='},
96
- verify=True, timeout=60)
tests/test_webdav.py DELETED
@@ -1,50 +0,0 @@
1
- import pytest
2
- from oscar_python._providers._webdav import WebDav
3
- from unittest.mock import patch, mock_open, MagicMock
4
-
5
-
6
- @pytest.fixture
7
- def webdav():
8
- credentials = {
9
- "hostname": "hostname",
10
- "login": "login",
11
- "password": "password"
12
- }
13
- return WebDav(credentials)
14
-
15
-
16
- def test_webdav_initialization(webdav):
17
- assert isinstance(webdav, WebDav)
18
-
19
-
20
- def test_webdav_upload_file(webdav):
21
- webdav.client = MagicMock(["check", "mkdir", "upload_sync"])
22
- webdav.client.check.return_value = False
23
-
24
- with patch("builtins.open", mock_open()):
25
- response = webdav.upload_file('local_path/file.txt', 'remote_path')
26
- assert response is None
27
-
28
- webdav.client.check.assert_called_with('remote_path')
29
- webdav.client.mkdir.assert_called_with('remote_path')
30
- webdav.client.upload_sync.assert_called_with('remote_path/file.txt', 'local_path/file.txt')
31
-
32
-
33
- def test_webdav_download_file(webdav):
34
- webdav.client = MagicMock(["download_sync"])
35
- webdav.client.download_sync.return_value = None
36
-
37
- with patch("builtins.open", mock_open()) as mock_file:
38
- webdav.download_file('local_path', 'remote_path/file.txt')
39
-
40
- webdav.client.download_sync.assert_called_with('remote_path/file.txt', 'local_path/file.txt')
41
-
42
-
43
- def test_webdav_list_files_from_path(webdav):
44
- webdav.client = MagicMock(["list"])
45
- webdav.client.list.return_value = ['file1.txt', 'file2.txt']
46
-
47
- response = webdav.list_files_from_path('path')
48
- assert response == ['file1.txt', 'file2.txt']
49
-
50
- webdav.client.list.assert_called_with('path')