basepair 1.5__0-py3.8.egg
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.
- EGG-INFO/PKG-INFO +27 -0
- EGG-INFO/SOURCES.txt +38 -0
- EGG-INFO/dependency_links.txt +1 -0
- EGG-INFO/requires.txt +5 -0
- EGG-INFO/scripts/basepair +637 -0
- EGG-INFO/top_level.txt +1 -0
- EGG-INFO/zip-safe +1 -0
- basepair/__init__.py +32 -0
- basepair/__pycache__/__init__.cpython-38.pyc +0 -0
- basepair/__pycache__/api.cpython-38.pyc +0 -0
- basepair/api.py +1353 -0
- basepair/helpers/__init__.py +3 -0
- basepair/helpers/__pycache__/__init__.cpython-38.pyc +0 -0
- basepair/helpers/__pycache__/eprint.cpython-38.pyc +0 -0
- basepair/helpers/__pycache__/nice_print.cpython-38.pyc +0 -0
- basepair/helpers/__pycache__/set_filter.cpython-38.pyc +0 -0
- basepair/helpers/eprint.py +8 -0
- basepair/helpers/nice_print.py +170 -0
- basepair/helpers/set_filter.py +18 -0
- basepair/infra/__init__.py +0 -0
- basepair/infra/__pycache__/__init__.cpython-38.pyc +0 -0
- basepair/infra/configuration/__init__.py +1 -0
- basepair/infra/configuration/__pycache__/__init__.cpython-38.pyc +0 -0
- basepair/infra/configuration/__pycache__/parser.cpython-38.pyc +0 -0
- basepair/infra/configuration/parser.py +67 -0
- basepair/infra/webapp/__init__.py +12 -0
- basepair/infra/webapp/__pycache__/__init__.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/abstract.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/analysis.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/file.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/gene.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/genome.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/genome_file.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/host.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/module.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/pipeline.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/project.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/sample.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/upload.cpython-38.pyc +0 -0
- basepair/infra/webapp/__pycache__/user.cpython-38.pyc +0 -0
- basepair/infra/webapp/abstract.py +128 -0
- basepair/infra/webapp/analysis.py +10 -0
- basepair/infra/webapp/file.py +10 -0
- basepair/infra/webapp/gene.py +10 -0
- basepair/infra/webapp/genome.py +10 -0
- basepair/infra/webapp/genome_file.py +10 -0
- basepair/infra/webapp/host.py +10 -0
- basepair/infra/webapp/module.py +10 -0
- basepair/infra/webapp/pipeline.py +10 -0
- basepair/infra/webapp/project.py +10 -0
- basepair/infra/webapp/sample.py +10 -0
- basepair/infra/webapp/upload.py +10 -0
- basepair/infra/webapp/user.py +48 -0
- basepair/utils/__init__.py +0 -0
- basepair/utils/__pycache__/__init__.cpython-38.pyc +0 -0
- basepair/utils/__pycache__/colors.cpython-38.pyc +0 -0
- basepair/utils/__pycache__/monitor.cpython-38.pyc +0 -0
- basepair/utils/__pycache__/s3.cpython-38.pyc +0 -0
- basepair/utils/__pycache__/sqs.cpython-38.pyc +0 -0
- basepair/utils/__pycache__/swf.cpython-38.pyc +0 -0
- basepair/utils/colors.py +43 -0
- basepair/utils/monitor.py +38 -0
- basepair/utils/s3.py +77 -0
- basepair/utils/sqs.py +147 -0
- basepair/utils/swf.py +129 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
'''Helper to print object nicely'''
|
|
2
|
+
|
|
3
|
+
# General imports
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
# Lib imports
|
|
7
|
+
from tabulate import tabulate
|
|
8
|
+
|
|
9
|
+
class NicePrint:
|
|
10
|
+
'''Helper class to print nice objects'''
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def analyses(data):
|
|
14
|
+
'''Print analyses'''
|
|
15
|
+
to_print = [
|
|
16
|
+
[
|
|
17
|
+
analysis['id'],
|
|
18
|
+
analysis['name'],
|
|
19
|
+
analysis['started_on'],
|
|
20
|
+
analysis['completed_on'],
|
|
21
|
+
analysis['status'],
|
|
22
|
+
analysis['meta']['num_files'],
|
|
23
|
+
analysis['tags']
|
|
24
|
+
] for analysis in data
|
|
25
|
+
]
|
|
26
|
+
print(tabulate(to_print, headers=[
|
|
27
|
+
'id',
|
|
28
|
+
'name',
|
|
29
|
+
'started on',
|
|
30
|
+
'completed on',
|
|
31
|
+
'status',
|
|
32
|
+
'num files',
|
|
33
|
+
'tags',
|
|
34
|
+
]))
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def analysis(data):
|
|
38
|
+
'''Print analysis'''
|
|
39
|
+
for analysis in data:
|
|
40
|
+
to_print = [
|
|
41
|
+
['id', analysis['id']],
|
|
42
|
+
['name', analysis['name']],
|
|
43
|
+
['date_created', analysis['date_created']],
|
|
44
|
+
['completed_on', analysis['completed_on']],
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
for sample in analysis['samples']:
|
|
48
|
+
to_print.append(['sample', sample.split('/')[-1]])
|
|
49
|
+
|
|
50
|
+
if analysis['controls']:
|
|
51
|
+
for control in analysis['controls']:
|
|
52
|
+
to_print.append(['control', control['id']])
|
|
53
|
+
|
|
54
|
+
print('\nAnalysis info:')
|
|
55
|
+
print(tabulate(to_print, headers=['Variable', 'Value']))
|
|
56
|
+
|
|
57
|
+
print('\nAnalysis files:')
|
|
58
|
+
|
|
59
|
+
# convert only filesizes that are not None
|
|
60
|
+
for filedata in analysis['files']:
|
|
61
|
+
filedata['filesize'] = filedata['filesize']/(1024.**3) if filedata['filesize'] else 'NA'
|
|
62
|
+
|
|
63
|
+
to_print = [
|
|
64
|
+
[
|
|
65
|
+
file['id'],
|
|
66
|
+
file['filesize'],
|
|
67
|
+
file['source'],
|
|
68
|
+
os.path.split(file['path'])[1],
|
|
69
|
+
file['tags'],
|
|
70
|
+
] for file in analysis['files']
|
|
71
|
+
]
|
|
72
|
+
print(tabulate(
|
|
73
|
+
to_print,
|
|
74
|
+
floatfmt='.4f',
|
|
75
|
+
headers=[
|
|
76
|
+
'id',
|
|
77
|
+
'filesize (Gigabytes)',
|
|
78
|
+
'source',
|
|
79
|
+
'name',
|
|
80
|
+
'tags',
|
|
81
|
+
],
|
|
82
|
+
numalign='right',
|
|
83
|
+
))
|
|
84
|
+
print('\n\n')
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def genome(data):
|
|
88
|
+
'''Print genome'''
|
|
89
|
+
to_print = [[genome['id'], genome['name'], genome['created_on']] for genome in data]
|
|
90
|
+
print(tabulate(to_print, headers=['id', 'name', 'created_on']))
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def genomes(data):
|
|
94
|
+
'''Print genomes'''
|
|
95
|
+
NicePrint.genome(data)
|
|
96
|
+
|
|
97
|
+
@staticmethod
|
|
98
|
+
def sample(data):
|
|
99
|
+
'''Print sample'''
|
|
100
|
+
for sample in data:
|
|
101
|
+
print('Sample id: {}'.format(sample['id']))
|
|
102
|
+
print('Sample name: {}'.format(sample['name']))
|
|
103
|
+
print('Sample datatype: {}'.format(sample['datatype']))
|
|
104
|
+
print('Sample genome: {}'.format(sample['genome_name'] or sample['genome']))
|
|
105
|
+
print('Sample data created: {}'.format(sample['date_created']))
|
|
106
|
+
print('Sample num reads: {}'.format(sample['meta']['num_reads']))
|
|
107
|
+
print('Analyses:')
|
|
108
|
+
to_print = [
|
|
109
|
+
[
|
|
110
|
+
analysis['id'],
|
|
111
|
+
analysis['name'],
|
|
112
|
+
analysis['started_on'],
|
|
113
|
+
analysis['completed_on'],
|
|
114
|
+
analysis['status'],
|
|
115
|
+
analysis['meta']['num_files'],
|
|
116
|
+
analysis['tags']
|
|
117
|
+
] for analysis in sample['analyses_full']
|
|
118
|
+
]
|
|
119
|
+
print(tabulate(to_print, headers=[
|
|
120
|
+
'id',
|
|
121
|
+
'name',
|
|
122
|
+
'started on',
|
|
123
|
+
'completed on',
|
|
124
|
+
'status',
|
|
125
|
+
'num files',
|
|
126
|
+
'tags',
|
|
127
|
+
]))
|
|
128
|
+
print('\n\n')
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
def samples(data):
|
|
132
|
+
'''Print samples'''
|
|
133
|
+
to_print = [
|
|
134
|
+
[
|
|
135
|
+
sample['id'],
|
|
136
|
+
sample['name'],
|
|
137
|
+
sample['datatype'],
|
|
138
|
+
sample['genome_name'] or sample['genome'],
|
|
139
|
+
sample['date_created'],
|
|
140
|
+
sample['meta']['num_reads']
|
|
141
|
+
] for sample in data
|
|
142
|
+
]
|
|
143
|
+
print(tabulate(to_print, headers=[
|
|
144
|
+
'id',
|
|
145
|
+
'name',
|
|
146
|
+
'datatype',
|
|
147
|
+
'genome',
|
|
148
|
+
'date created',
|
|
149
|
+
'num reads',
|
|
150
|
+
]))
|
|
151
|
+
|
|
152
|
+
@staticmethod
|
|
153
|
+
def workflows(data):
|
|
154
|
+
'''Print pipelines'''
|
|
155
|
+
to_print = [
|
|
156
|
+
[
|
|
157
|
+
pipeline['id'],
|
|
158
|
+
pipeline['name'],
|
|
159
|
+
pipeline['datatype'],
|
|
160
|
+
pipeline['description'],
|
|
161
|
+
pipeline['tags']
|
|
162
|
+
] for pipeline in data
|
|
163
|
+
]
|
|
164
|
+
print(tabulate(to_print, headers=[
|
|
165
|
+
'id',
|
|
166
|
+
'name',
|
|
167
|
+
'datatype',
|
|
168
|
+
'description',
|
|
169
|
+
'tags',
|
|
170
|
+
]))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'''Helper to filter sets of data'''
|
|
2
|
+
|
|
3
|
+
class SetFilter:
|
|
4
|
+
'''Helper class to filter list'''
|
|
5
|
+
@staticmethod
|
|
6
|
+
def diff(a_set, b_set):
|
|
7
|
+
'''Filter by not intersection'''
|
|
8
|
+
return not set(b_set).intersection(set(a_set))
|
|
9
|
+
|
|
10
|
+
@staticmethod
|
|
11
|
+
def exact(a_set, b_set):
|
|
12
|
+
'''Filter by eq'''
|
|
13
|
+
return set(a_set) == set(b_set)
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def subset(a_set, b_set):
|
|
17
|
+
'''Filter by intersection'''
|
|
18
|
+
return set(a_set).intersection(set(b_set))
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .parser import Parser
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'''Configuration parser'''
|
|
2
|
+
|
|
3
|
+
# General imports
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
# App imports
|
|
8
|
+
from basepair.helpers import eprint
|
|
9
|
+
|
|
10
|
+
class Parser(): # pylint: disable=too-few-public-methods
|
|
11
|
+
'''Configuration parser class'''
|
|
12
|
+
def __init__(self, source):
|
|
13
|
+
# check if local json file
|
|
14
|
+
self.cfg = {}
|
|
15
|
+
if isinstance(source, dict):
|
|
16
|
+
self.cfg = source
|
|
17
|
+
elif os.path.isfile(source):
|
|
18
|
+
try:
|
|
19
|
+
self.cfg = json.load(open(source))
|
|
20
|
+
except OSError as error:
|
|
21
|
+
eprint(f'ERROR: Not able to open config file: {error}')
|
|
22
|
+
except ValueError as error:
|
|
23
|
+
eprint(f'ERROR: Not able to read config file: {error}')
|
|
24
|
+
# TODO: if uri implement configuration manager
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def get_cli_credentials_from(cfg):
|
|
28
|
+
'''Get cli credential from service cfg'''
|
|
29
|
+
credentials = ''
|
|
30
|
+
credentials_cfg = cfg.get('credentials', {})
|
|
31
|
+
if credentials_cfg and not credentials_cfg.get('role'):
|
|
32
|
+
credentials = 'AWS_ACCESS_KEY_ID={} AWS_SECRET_ACCESS_KEY={} '.format(
|
|
33
|
+
credentials_cfg.get('id'),
|
|
34
|
+
credentials_cfg.get('secret'),
|
|
35
|
+
)
|
|
36
|
+
return credentials
|
|
37
|
+
|
|
38
|
+
def get_reflib_storage(self, bucket=None):
|
|
39
|
+
'''Get storage setting for reflibs'''
|
|
40
|
+
storages_cfg = self.cfg.get('storage', {}).get('reflib', {})
|
|
41
|
+
all_reflib_buckets = []
|
|
42
|
+
for storage_cfg in storages_cfg:
|
|
43
|
+
storage_settings = storage_cfg.get('settings', {})
|
|
44
|
+
all_reflib_buckets.append({
|
|
45
|
+
'bucket': bucket or storage_settings.get('bucket'),
|
|
46
|
+
'credentials': storage_cfg.get('credentials'),
|
|
47
|
+
'region': storage_settings.get('region'),
|
|
48
|
+
})
|
|
49
|
+
return all_reflib_buckets
|
|
50
|
+
|
|
51
|
+
def get_user_storage(self, bucket=None):
|
|
52
|
+
'''Get storage setting'''
|
|
53
|
+
storage_cfg = self.cfg.get('storage', {}).get('user', {})
|
|
54
|
+
storage_settings = storage_cfg.get('settings', {})
|
|
55
|
+
return {
|
|
56
|
+
'bucket': bucket or storage_settings.get('bucket'),
|
|
57
|
+
'credentials': storage_cfg.get('credentials'),
|
|
58
|
+
'region': storage_settings.get('region'),
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def get_webapp_api(self):
|
|
62
|
+
'''Get webapp api settings'''
|
|
63
|
+
return self.cfg.get('api', {})
|
|
64
|
+
|
|
65
|
+
def is_empty(self):
|
|
66
|
+
'''Check if cfg is empty'''
|
|
67
|
+
return not self.cfg
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .analysis import Analysis
|
|
2
|
+
from .file import File
|
|
3
|
+
from .gene import Gene
|
|
4
|
+
from .genome import Genome
|
|
5
|
+
from .genome_file import GenomeFile
|
|
6
|
+
from .host import Host
|
|
7
|
+
from .module import Module
|
|
8
|
+
from .pipeline import Pipeline
|
|
9
|
+
from .project import Project
|
|
10
|
+
from .sample import Sample
|
|
11
|
+
from .upload import Upload
|
|
12
|
+
from .user import User
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
'''Webapp API'''
|
|
2
|
+
|
|
3
|
+
# General imports
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
# Lib imports
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
# App imports
|
|
11
|
+
from basepair.helpers import eprint
|
|
12
|
+
|
|
13
|
+
class Abstract:
|
|
14
|
+
'''Webapp abastract class'''
|
|
15
|
+
def __init__(self, cfg):
|
|
16
|
+
protocol = 'https' if cfg.get('ssl', True) else 'http'
|
|
17
|
+
self.endpoint = protocol + '://' + cfg.get('host') + cfg.get('prefix')
|
|
18
|
+
self.payload = {
|
|
19
|
+
'username': cfg.get('username'),
|
|
20
|
+
'api_key': cfg.get('key')
|
|
21
|
+
}
|
|
22
|
+
self.headers = {'content-type': 'application/json'}
|
|
23
|
+
|
|
24
|
+
def delete(self, obj_id, verify=True):
|
|
25
|
+
'''Delete resource'''
|
|
26
|
+
try:
|
|
27
|
+
response = requests.delete(
|
|
28
|
+
'{}{}'.format(self.endpoint, obj_id),
|
|
29
|
+
params=self.payload,
|
|
30
|
+
verify=verify
|
|
31
|
+
)
|
|
32
|
+
return self._parse_response(response)
|
|
33
|
+
except requests.exceptions.RequestException as error:
|
|
34
|
+
eprint('ERROR: {}'.format(error))
|
|
35
|
+
return { 'error': True, 'msg': error}
|
|
36
|
+
|
|
37
|
+
def get(self, obj_id, cache=False, params={}, verify=True): # pylint: disable=dangerous-default-value
|
|
38
|
+
'''Get detail of an resource'''
|
|
39
|
+
if cache:
|
|
40
|
+
filename = os.path.expanduser(cache)
|
|
41
|
+
if os.path.exists(filename) and os.path.getsize(filename):
|
|
42
|
+
return json.loads(open(filename, 'r').read().strip())
|
|
43
|
+
|
|
44
|
+
params.update(self.payload)
|
|
45
|
+
try:
|
|
46
|
+
response = requests.get(
|
|
47
|
+
'{}{}'.format(self.endpoint, obj_id),
|
|
48
|
+
params=params,
|
|
49
|
+
verify=verify,
|
|
50
|
+
)
|
|
51
|
+
parsed = self._parse_response(response)
|
|
52
|
+
|
|
53
|
+
# save in cache if required
|
|
54
|
+
if cache and parsed and not parsed.get('error'):
|
|
55
|
+
directory = os.path.dirname(filename)
|
|
56
|
+
if not os.path.exists(directory):
|
|
57
|
+
os.makedirs(directory)
|
|
58
|
+
with open(filename, 'w') as handle:
|
|
59
|
+
handle.write(json.dumps(parsed, indent=2))
|
|
60
|
+
return parsed
|
|
61
|
+
except requests.exceptions.RequestException as error:
|
|
62
|
+
eprint('ERROR: {}'.format(error))
|
|
63
|
+
return {'error': True, 'msg': error}
|
|
64
|
+
|
|
65
|
+
def list(self, params={'limit': 100}, verify=True): # pylint: disable=dangerous-default-value
|
|
66
|
+
'''Get a list of items'''
|
|
67
|
+
params.update(self.payload)
|
|
68
|
+
try:
|
|
69
|
+
response = requests.get(
|
|
70
|
+
self.endpoint.rstrip('/'),
|
|
71
|
+
params=params,
|
|
72
|
+
verify=verify,
|
|
73
|
+
)
|
|
74
|
+
return self._parse_response(response)
|
|
75
|
+
except requests.exceptions.RequestException as error:
|
|
76
|
+
eprint('ERROR: {}'.format(error))
|
|
77
|
+
return {'error': True, 'msg': error}
|
|
78
|
+
|
|
79
|
+
def list_all(self): # pylint: disable=dangerous-default-value
|
|
80
|
+
'''Get a list of all items'''
|
|
81
|
+
item_list = []
|
|
82
|
+
limit = 500
|
|
83
|
+
offset = 0
|
|
84
|
+
total_count = 1
|
|
85
|
+
while len(item_list) < total_count:
|
|
86
|
+
response = self.list({'limit': limit, 'offset': offset})
|
|
87
|
+
if response.get('error'):
|
|
88
|
+
return {'error': True, 'msg': response.get('msg')}
|
|
89
|
+
total_count = response.get('meta', {}).get('total_count')
|
|
90
|
+
item_list += response.get('objects')
|
|
91
|
+
offset += limit
|
|
92
|
+
return item_list
|
|
93
|
+
|
|
94
|
+
def save(self, obj_id=None, params={}, payload={}, verify=True): # pylint: disable=dangerous-default-value
|
|
95
|
+
'''Save or update resource'''
|
|
96
|
+
params.update(self.payload)
|
|
97
|
+
try:
|
|
98
|
+
response = getattr(requests, 'put' if obj_id else 'post')(
|
|
99
|
+
'{}{}'.format(self.endpoint, obj_id or ''),
|
|
100
|
+
data=json.dumps(payload),
|
|
101
|
+
headers=self.headers,
|
|
102
|
+
params=params,
|
|
103
|
+
verify=verify,
|
|
104
|
+
)
|
|
105
|
+
return self._parse_response(response)
|
|
106
|
+
except requests.exceptions.RequestException as error:
|
|
107
|
+
eprint('ERROR: {}'.format(error))
|
|
108
|
+
return {'error': True, 'msg': error}
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def _parse_response(cls, response):
|
|
112
|
+
'''General response parser'''
|
|
113
|
+
error_msgs = {
|
|
114
|
+
401: 'You don\'t have access to this resource.',
|
|
115
|
+
404: 'Resource not found.',
|
|
116
|
+
500: 'Error retrieving data from API!'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if response.status_code in error_msgs:
|
|
120
|
+
eprint('ERROR: {}'.format(error_msgs[response.status_code]))
|
|
121
|
+
return {'error': True, 'msg': error_msgs[response.status_code]}
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
return response.json()
|
|
125
|
+
except json.decoder.JSONDecodeError as error:
|
|
126
|
+
msg = 'ERROR: Not able to parse response: {}.'.format(error)
|
|
127
|
+
eprint(msg)
|
|
128
|
+
return {'error': True, 'msg': msg}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'''User webapp api wrapper'''
|
|
2
|
+
|
|
3
|
+
# General imports
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
# Lib imports
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
# App imports
|
|
11
|
+
from basepair.helpers import eprint
|
|
12
|
+
from .abstract import Abstract
|
|
13
|
+
|
|
14
|
+
class User(Abstract):
|
|
15
|
+
'''Webapp User class'''
|
|
16
|
+
def __init__(self, cfg):
|
|
17
|
+
super().__init__(cfg)
|
|
18
|
+
self.endpoint += 'users/'
|
|
19
|
+
|
|
20
|
+
def get_configuration(self, cache=False, verify=True):
|
|
21
|
+
'''Get host configuration for user'''
|
|
22
|
+
if cache:
|
|
23
|
+
filename = os.path.expanduser(cache)
|
|
24
|
+
if os.path.exists(filename) and os.path.getsize(filename):
|
|
25
|
+
return json.loads(open(filename, 'r').read().strip())
|
|
26
|
+
|
|
27
|
+
params = {'origin': 'cli'}
|
|
28
|
+
params.update(self.payload)
|
|
29
|
+
try:
|
|
30
|
+
response = requests.get(
|
|
31
|
+
'{}get_configuration'.format(self.endpoint),
|
|
32
|
+
params=params,
|
|
33
|
+
verify=verify,
|
|
34
|
+
)
|
|
35
|
+
parsed = self._parse_response(response)
|
|
36
|
+
|
|
37
|
+
# save in cache if required
|
|
38
|
+
if cache and parsed and not parsed.get('error'):
|
|
39
|
+
directory = os.path.dirname(filename)
|
|
40
|
+
if not os.path.exists(directory):
|
|
41
|
+
os.makedirs(directory)
|
|
42
|
+
eprint('Saving configuration into:', filename)
|
|
43
|
+
with open(filename, 'w') as handle:
|
|
44
|
+
handle.write(json.dumps(parsed, indent=2))
|
|
45
|
+
return parsed
|
|
46
|
+
except requests.exceptions.RequestException as error:
|
|
47
|
+
eprint('ERROR: {}'.format(error))
|
|
48
|
+
return { 'error': True, 'msg': error}
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|