Skip to content

Commit 826eedc

Browse files
authored
feat: DS Client Library (#94)
* feat: add AUDIT log level for upload * chore: update outdated tests * fix: allow empty str as RESULT_PATH_PREFIX & replace w/ default val * fix: add option to run no ssl es for demo purposes * feat: DS python client * feat: add method to query granules * fix: client example / test case + passing sort keys
1 parent 8c1b092 commit 826eedc

File tree

14 files changed

+1065
-239
lines changed

14 files changed

+1065
-239
lines changed

mdps_ds_lib/ds_client/__init__.py

Whitespace-only changes.

mdps_ds_lib/ds_client/auth_token/__init__.py

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from abc import ABC, abstractmethod
2+
3+
4+
class TokenAbstract(ABC):
5+
@abstractmethod
6+
def get_token(self):
7+
return ''
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import os
2+
3+
from mdps_ds_lib.ds_client.auth_token.token_abstract import TokenAbstract
4+
from mdps_ds_lib.lib.cognito_login.cognito_token_retriever import CognitoTokenRetriever
5+
6+
7+
class TokenCognito(TokenAbstract):
8+
def get_token(self):
9+
token_retriever = CognitoTokenRetriever()
10+
token = token_retriever.start()
11+
header = {'Authorization': f'Bearer {token}'}
12+
return token
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import os
2+
3+
from mdps_ds_lib.ds_client.auth_token.token_abstract import TokenAbstract
4+
5+
6+
class TokenDummy(TokenAbstract):
7+
def get_token(self):
8+
env_token = os.getenv('DS_TOKEN', None)
9+
if env_token is None:
10+
raise ValueError(f'missing env_token DS_TOKEN')
11+
return env_token
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from mdps_ds_lib.lib.utils.factory_abstract import FactoryAbstract
2+
3+
4+
class TokenFactory(FactoryAbstract):
5+
DUMMY = 'DUMMY'
6+
COGNITO = 'COGNITO'
7+
8+
def get_instance(self, class_type, **kwargs):
9+
ct = class_type.upper()
10+
if ct == self.DUMMY:
11+
from mdps_ds_lib.ds_client.auth_token.token_dummy import TokenDummy
12+
return TokenDummy()
13+
if ct == self.COGNITO:
14+
from mdps_ds_lib.ds_client.auth_token.token_cognito import TokenCognito
15+
return TokenCognito()
16+
raise ModuleNotFoundError(f'cannot find ES class for {ct}')
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import json
2+
import logging
3+
4+
import requests
5+
6+
from mdps_ds_lib.ds_client.auth_token.token_abstract import TokenAbstract
7+
from mdps_ds_lib.ds_client.ds_client_base import DsClient
8+
LOGGER = logging.getLogger(__name__)
9+
10+
11+
class DsClientAdmin(DsClient):
12+
13+
14+
def __init__(self, token_retriever: TokenAbstract, ds_url: str, ds_stage: str):
15+
super().__init__(token_retriever, ds_url, ds_stage)
16+
17+
def add_admin_group(self, crud_actions: list, group_name: str):
18+
request_url = f'{self._uds_url}admin/auth'
19+
LOGGER.debug(f'request_url: {request_url}')
20+
collection_complete_name = '.*' if self.collection is None else \
21+
f'{self.collection}.*' if self.collection_venue is None else f'{self.collection}___{self.collection_venue}'
22+
resources = [self.urn, self.org, self.project,
23+
self.tenant if self.tenant is not None else '*',
24+
self.tenant_venue if self.tenant_venue is not None else '*',
25+
collection_complete_name
26+
]
27+
admin_add_body = {
28+
"actions": [k.upper() for k in crud_actions],
29+
"resources": [':'.join(resources)],
30+
"tenant": self.tenant,
31+
"venue": self.tenant_venue,
32+
"group_name": group_name
33+
}
34+
LOGGER.debug(f"admin_add_body: {admin_add_body}")
35+
s = requests.session()
36+
s.trust_env = self._trust_env
37+
response = s.put(url=request_url, headers={
38+
'Authorization': f'Bearer {self._token_retriever.get_token()}',
39+
'Content-Type': 'application/json',
40+
}, verify=self._trust_env, data=json.dumps(admin_add_body))
41+
response.raise_for_status()
42+
return response.text
43+
44+
def delete_admin_group(self, group_name: str):
45+
request_url = f'{self._uds_url}admin/auth'
46+
LOGGER.debug(f'request_url: {request_url}')
47+
admin_delete_body = {
48+
"tenant": self.tenant,
49+
"venue": self.tenant_venue,
50+
"group_name": group_name
51+
}
52+
LOGGER.debug(f"admin_add_body: {admin_delete_body}")
53+
s = requests.session()
54+
s.trust_env = self._trust_env
55+
response = s.delete(url=request_url, headers={
56+
'Authorization': f'Bearer {self._token_retriever.get_token()}',
57+
'Content-Type': 'application/json',
58+
}, verify=self._trust_env, data=json.dumps(admin_delete_body))
59+
response.raise_for_status()
60+
return response.text
61+
62+
def list_admin_group(self, group_names: list=[]):
63+
request_url = f'{self._uds_url}admin/auth'
64+
params = [
65+
f'tenant={self.tenant}',
66+
f'venue={self.tenant_venue}',
67+
]
68+
if len(group_names) < 1:
69+
params.append(f'group_names={",".join(group_names)}')
70+
params = '&'.join(params)
71+
request_url = f'{request_url}?{params}'
72+
LOGGER.debug(f'request_url: {request_url}')
73+
s = requests.session()
74+
s.trust_env = self._trust_env
75+
response = s.get(url=request_url, headers={
76+
'Authorization': f'Bearer {self._token_retriever.get_token()}',
77+
'Content-Type': 'application/json',
78+
}, verify=self._trust_env)
79+
response.raise_for_status()
80+
return json.loads(response.text)
81+
82+
def update_admin_group(self, crud_actions: list, group_name: str):
83+
raise NotImplementedError(f'TO DO')
84+
85+
def setup_database(self):
86+
es_setup_url = f'{self._uds_url}admin/system/es_setup/'
87+
print(f'es_setup_url: {es_setup_url}')
88+
s = requests.session()
89+
s.trust_env = self._trust_env
90+
response = s.put(url=es_setup_url, headers={'Authorization': f'Bearer {self._token_retriever.get_token()}'}, verify=self._trust_env)
91+
response.raise_for_status()
92+
return response.text
93+
94+
def add_tenant_database_index(self, custom_metadata_es_index: dict):
95+
request_url = f'{self._uds_url}admin/custom_metadata/{self.tenant}/'
96+
if self.tenant_venue is not None:
97+
request_url = f'{request_url}?venue={self.tenant_venue}'
98+
print(f'request_url: {request_url}')
99+
s = requests.session()
100+
s.trust_env = self._trust_env
101+
response = s.put(url=request_url, headers={
102+
'Authorization': f'Bearer {self._token_retriever.get_token()}',
103+
'Content-Type': 'application/json',
104+
}, verify=self._trust_env, data=json.dumps(custom_metadata_es_index))
105+
response.raise_for_status()
106+
return response.text
107+
108+
def get_tenant_database_index(self):
109+
request_url = f'{self._uds_url}admin/custom_metadata/{self.tenant}/'
110+
if self.tenant_venue is not None:
111+
request_url = f'{request_url}?venue={self.tenant_venue}'
112+
print(f'request_url: {request_url}')
113+
s = requests.session()
114+
s.trust_env = self._trust_env
115+
response = s.get(url=request_url, headers={
116+
'Authorization': f'Bearer {self._token_retriever.get_token()}',
117+
'Content-Type': 'application/json',
118+
}, verify=self._trust_env)
119+
response.raise_for_status()
120+
return json.loads(response.text)
121+
122+
def delete_tenant_database_index(self):
123+
request_url = f'{self._uds_url}admin/custom_metadata/{self.tenant}/'
124+
if self.tenant_venue is not None:
125+
request_url = f'{request_url}?venue={self.tenant_venue}'
126+
print(f'request_url: {request_url}')
127+
s = requests.session()
128+
s.trust_env = self._trust_env
129+
response = s.delete(url=request_url, headers={
130+
'Authorization': f'Bearer {self._token_retriever.get_token()}',
131+
'Content-Type': 'application/json',
132+
}, verify=self._trust_env)
133+
response.raise_for_status()
134+
return response.text
135+
136+
def destroy_tenant_database_index(self):
137+
request_url = f'{self._uds_url}admin/custom_metadata/{self.tenant}/destroy/'
138+
if self.tenant_venue is not None:
139+
request_url = f'{request_url}?venue={self.tenant_venue}'
140+
print(f'request_url: {request_url}')
141+
s = requests.session()
142+
s.trust_env = self._trust_env
143+
response = s.delete(url=request_url, headers={
144+
'Authorization': f'Bearer {self._token_retriever.get_token()}',
145+
'Content-Type': 'application/json',
146+
}, verify=self._trust_env)
147+
response.raise_for_status()
148+
return response.text
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import json
2+
import logging
3+
import os
4+
5+
import requests
6+
7+
from dotenv import load_dotenv
8+
from mdps_ds_lib.ds_client.auth_token.token_abstract import TokenAbstract
9+
from mdps_ds_lib.ds_client.auth_token.token_factory import TokenFactory
10+
LOGGER = logging.getLogger(__name__)
11+
12+
13+
class DsClient:
14+
def __init__(self, token_retriever: TokenAbstract, ds_url: str, ds_stage: str):
15+
load_dotenv()
16+
self._trust_env = os.getenv('TRUST_ENV', 'FALSE').upper().strip() == 'TRUE'
17+
self._token_retriever = token_retriever
18+
self._uds_url = f'{ds_url}/{ds_stage}/'
19+
self.__urn, self.__org, self.__project = 'URN', 'NASA', 'UNITY'
20+
self.__tenant, self.__tenant_venue, self.__collection, self.__collection_venue = None, None, None, None
21+
self.__granule = None
22+
self.__default_collection_venue = '001'
23+
24+
def get_complete_collection(self):
25+
return f'{self.collection}{self.__default_collection_venue}' if self.collection_venue is None else f'{self.collection}___{self.collection_venue}'
26+
27+
@property
28+
def granule(self):
29+
return self.__granule
30+
31+
@granule.setter
32+
def granule(self, val):
33+
"""
34+
:param val:
35+
:return: None
36+
"""
37+
self.__granule = val
38+
return
39+
40+
@property
41+
def project(self):
42+
return self.__project
43+
44+
@project.setter
45+
def project(self, val):
46+
"""
47+
:param val:
48+
:return: None
49+
"""
50+
self.__project = val
51+
return
52+
@property
53+
def urn(self):
54+
return self.__urn
55+
56+
@urn.setter
57+
def urn(self, val):
58+
"""
59+
:param val:
60+
:return: None
61+
"""
62+
self.__urn = val
63+
return
64+
@property
65+
def org(self):
66+
return self.__org
67+
68+
@org.setter
69+
def org(self, val):
70+
"""
71+
:param val:
72+
:return: None
73+
"""
74+
self.__org = val
75+
return
76+
@property
77+
def tenant(self):
78+
return self.__tenant
79+
80+
@tenant.setter
81+
def tenant(self, val):
82+
"""
83+
:param val:
84+
:return: None
85+
"""
86+
self.__tenant = val
87+
return
88+
@property
89+
def tenant_venue(self):
90+
return self.__tenant_venue
91+
92+
@tenant_venue.setter
93+
def tenant_venue(self, val):
94+
"""
95+
:param val:
96+
:return: None
97+
"""
98+
self.__tenant_venue = val
99+
return
100+
@property
101+
def collection(self):
102+
return self.__collection
103+
104+
@collection.setter
105+
def collection(self, val):
106+
"""
107+
:param val:
108+
:return: None
109+
"""
110+
self.__collection = val
111+
return
112+
@property
113+
def collection_venue(self):
114+
return self.__collection_venue
115+
116+
@collection_venue.setter
117+
def collection_venue(self, val):
118+
"""
119+
:param val:
120+
:return: None
121+
"""
122+
self.__collection_venue = val
123+
return
124+
125+

0 commit comments

Comments
 (0)