Mercurial > repos > geco-team > gmql_queries_editor
comparison dynamic_utils.py @ 0:c74a1c7121ec draft default tip
planemo upload for repository https://github.com/lu-brn/gmql-galaxy commit 953ee36ceda5814dc9baa03427bc0eb4ee2e93bd-dirty
| author | geco-team |
|---|---|
| date | Tue, 26 Jun 2018 08:59:49 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:c74a1c7121ec |
|---|---|
| 1 #!/usr/bin/env python | |
| 2 # -------------------------------------------------------------------------------- | |
| 3 # Class for the dynamic options in the GMQL tools | |
| 4 # -------------------------------------------------------------------------------- | |
| 5 # Luana Brancato, luana.brancato@mail.polimi.it | |
| 6 # -------------------------------------------------------------------------------- | |
| 7 | |
| 8 import sys, requests | |
| 9 | |
| 10 | |
| 11 def validate(request_context, error_map, params, inputs): | |
| 12 """Generic validate function, it checks if the user is valid.""" | |
| 13 | |
| 14 user = params.get('authToken', '') | |
| 15 | |
| 16 if user: | |
| 17 try: | |
| 18 validate_user(user.file_name) | |
| 19 except: | |
| 20 error_msg = 'User has expired' | |
| 21 error_map['authToken'] = error_msg | |
| 22 | |
| 23 | |
| 24 def validate_upload(request_context, error_map, params, inputs): | |
| 25 """Validate function for uploading tool. It also checks the chosen ds name does not exists already.""" | |
| 26 | |
| 27 validate(request_context, error_map, params, inputs) | |
| 28 | |
| 29 name = params.get('name') | |
| 30 | |
| 31 user = params.get('authToken') | |
| 32 | |
| 33 #This MUST be changed in the future to a parametric solution. Hopefully in the future Galaxy will allow | |
| 34 #validation without external scripts | |
| 35 | |
| 36 url = 'http://genomic.elet.polimi.it/gmql-rest/datasets' | |
| 37 | |
| 38 datasets = get(url, user=user.file_name) | |
| 39 list_datasets = [x['name'] for x in datasets['datasets']] | |
| 40 | |
| 41 if name in list_datasets: | |
| 42 error_msg = 'Dataset already exists. Choose another name.' | |
| 43 error_map['name'] = error_msg | |
| 44 | |
| 45 | |
| 46 def validate_variables(request_context, error_map, params, inputs): | |
| 47 """Validate function for gmql_compositor. It checks that all queries input variables | |
| 48 have been previously defined. """ | |
| 49 | |
| 50 validate(request_context, error_map, params, inputs) | |
| 51 | |
| 52 output_vars = set([]) | |
| 53 | |
| 54 # TODO: Include in the check output variables eventually defined previously in another query | |
| 55 | |
| 56 for op in params.get('operations'): | |
| 57 op_curr = op.get('operation') | |
| 58 if op_curr.get('input', ''): | |
| 59 input_var = op_curr.get('input').get('input_var', '') | |
| 60 if input_var: | |
| 61 if input_var not in output_vars: | |
| 62 error_msg = '%s has not been defined yet\n' % (input_var) | |
| 63 name = '|'.join(['operations_%d' % (op.get('__index__')), 'operation', 'input', 'input_var']) | |
| 64 error_map[name] = error_msg | |
| 65 else: | |
| 66 for key in op_curr.keys(): | |
| 67 if key.startswith('input_var'): | |
| 68 input_var = op_curr.get(key) | |
| 69 if input_var: | |
| 70 if input_var not in output_vars: | |
| 71 error_msg = '%s has not been defined yet\n' % (input_var) | |
| 72 name = '|'.join(['operations_%d' % (op.get('__index__')), 'operation', key]) | |
| 73 error_map[name] = error_msg | |
| 74 | |
| 75 # Update output_vars with the result of current operation | |
| 76 output_vars.add(op_curr.get('output_var')) | |
| 77 | |
| 78 | |
| 79 def validate_user(user): | |
| 80 """Check if the user is a valid one""" | |
| 81 | |
| 82 if user: | |
| 83 with open(user, 'r') as f: | |
| 84 valid = f.readline().rstrip('\n').split('\t')[2] | |
| 85 if valid == 'False': | |
| 86 raise Exception, "User has expired" | |
| 87 | |
| 88 | |
| 89 def get_metadata_attr(user, ds, ds_list): | |
| 90 options = [] | |
| 91 | |
| 92 try: | |
| 93 validate_user(user) | |
| 94 if ds_list: | |
| 95 | |
| 96 owner = '' | |
| 97 | |
| 98 with open(ds_list, 'r') as f: | |
| 99 for d in f.readlines(): | |
| 100 if d.split('\t')[0] == ds: | |
| 101 owner = d.split('\t')[1].rstrip('\n') | |
| 102 f.close() | |
| 103 | |
| 104 attr_list = get_metadata(user, ds, str(owner)) | |
| 105 | |
| 106 for i, att in enumerate(attr_list['attributes']): | |
| 107 options.append((att.get('key', ' '), att.get('key', ' '), i == 0)) | |
| 108 | |
| 109 return options | |
| 110 | |
| 111 else: | |
| 112 return options | |
| 113 except: | |
| 114 return options | |
| 115 | |
| 116 | |
| 117 def get_metadata_values(user, ds, ds_list, att): | |
| 118 options = [] | |
| 119 | |
| 120 try: | |
| 121 validate_user(user) | |
| 122 if ds_list: | |
| 123 | |
| 124 owner = '' | |
| 125 | |
| 126 with open(ds_list, 'r') as f: | |
| 127 for d in f.readlines(): | |
| 128 if d.split('\t')[0] == ds: | |
| 129 owner = d.split('\t')[1].rstrip('\n') | |
| 130 f.close() | |
| 131 | |
| 132 attr_list = get_metadata(user, ds, str(owner), att) | |
| 133 | |
| 134 # By default first option is '*' i.e. any value | |
| 135 options.append(('any value', '*', 0)) | |
| 136 | |
| 137 for i, att in enumerate(attr_list['values']): | |
| 138 options.append(('%s (%d)' % (att.get('text', ' '), att.get('count', 0)), att.get('text', ' '), i == 0)) | |
| 139 | |
| 140 return options | |
| 141 | |
| 142 else: | |
| 143 return options | |
| 144 except: | |
| 145 return options | |
| 146 | |
| 147 | |
| 148 def get_metadata(user, ds, owner='', att_name=''): | |
| 149 """Return the metadata attributes names for the given dataset""" | |
| 150 | |
| 151 url = 'http://genomic.elet.polimi.it/gmql-rest/metadata/{datasetName}/filter' | |
| 152 | |
| 153 # Format url | |
| 154 if (owner == 'public'): | |
| 155 url = url.format(datasetName='public.' + ds) | |
| 156 else: | |
| 157 url = url.format(datasetName=ds) | |
| 158 | |
| 159 if att_name: | |
| 160 url = '{url}/{att}'.format(url=url, att=att_name) | |
| 161 | |
| 162 content = dict() | |
| 163 content.update(attributes=[]) | |
| 164 | |
| 165 metadata = post(url, content, user=user) | |
| 166 | |
| 167 return metadata | |
| 168 | |
| 169 | |
| 170 def read_token(input): | |
| 171 """It takes the tabular file with the information over the user | |
| 172 name authToken valid_flag | |
| 173 It checks if the user is still valid and extract the authToken for the REST calls""" | |
| 174 | |
| 175 with open(input, 'r') as f_in: | |
| 176 user = f_in.readline().rstrip('\n').split('\t') | |
| 177 | |
| 178 if user[2]: | |
| 179 token = user[1] | |
| 180 else: | |
| 181 stop_err("This session is no longer valid") | |
| 182 | |
| 183 return token | |
| 184 | |
| 185 | |
| 186 def get(url, user=None, response_type='json'): | |
| 187 """GET Request | |
| 188 :param url: url where to fetch the requested resource | |
| 189 :param user: for authenticated requests; if not provided make an unauthenticated request (es. for login) | |
| 190 :param response_type: type of the fetched response. | |
| 191 JSON ( Default ) | |
| 192 TEXT | |
| 193 ZIP | |
| 194 FILE | |
| 195 """ | |
| 196 | |
| 197 # Set request headers | |
| 198 headers = dict() | |
| 199 | |
| 200 if user: | |
| 201 headers.update({'X-AUTH-TOKEN': read_token(user)}) | |
| 202 | |
| 203 if response_type == 'text': | |
| 204 headers.update({'Accept': 'text/plain'}) | |
| 205 elif response_type == 'zip': | |
| 206 pass | |
| 207 elif response_type == 'file': | |
| 208 headers.update({'Accept': 'file'}) | |
| 209 else: | |
| 210 headers.update({'Accept': 'application/json'}) | |
| 211 | |
| 212 # Make the request | |
| 213 response = requests.get(url, headers=headers) | |
| 214 | |
| 215 # Check returned server status | |
| 216 status_code = response.status_code | |
| 217 | |
| 218 # Read result. If Server OK, read according to response_type. Raise an error otherwise. | |
| 219 if status_code == requests.codes.ok: | |
| 220 if response_type == 'json': | |
| 221 return response.json() | |
| 222 elif response_type == 'text': | |
| 223 return response.text | |
| 224 else: | |
| 225 return response | |
| 226 elif status_code == requests.codes.unauthorized: | |
| 227 #expire_user(user) | |
| 228 stop_err("You are not authorized to do this. \nPlease login first.") | |
| 229 elif status_code == requests.codes.not_found: | |
| 230 stop_err("Resource not found for this user.") | |
| 231 else: | |
| 232 stop_err("Error {code}: {reason}\n{message}".format(code=status_code, | |
| 233 reason=response.reason, | |
| 234 message=response.content)) | |
| 235 | |
| 236 def post(url, payload, user=None, params=None, content_type='json', response_type='json') : | |
| 237 """ POST Request | |
| 238 :param url: url where to post data | |
| 239 :param payload: payload for the post request. Type is specified by content_type. | |
| 240 :param user: for authenticated requests; if not provided make an unauthenticated request (es. for registration) | |
| 241 :param params: optional query parameters | |
| 242 :param content_type | |
| 243 :param response_type: Default is json | |
| 244 """ | |
| 245 | |
| 246 | |
| 247 # Set request headers | |
| 248 headers = dict() | |
| 249 | |
| 250 if user: | |
| 251 headers.update({'X-AUTH-TOKEN': read_token(user)}) | |
| 252 | |
| 253 headers.update({'Accept': 'application/json'}) | |
| 254 | |
| 255 if content_type == 'text' : | |
| 256 headers.update({'Content-Type' : 'text/plain'}) | |
| 257 response = requests.post(url, params=params, headers=headers, data=payload) | |
| 258 elif content_type == 'multiform' : | |
| 259 response = requests.post(url, params=params, headers=headers, files=payload) | |
| 260 else : | |
| 261 headers.update({'Content-Type': 'application/json'}) | |
| 262 response = requests.post(url, params=params, headers=headers, json=payload) | |
| 263 | |
| 264 # Check returned server status | |
| 265 status_code = response.status_code | |
| 266 | |
| 267 | |
| 268 if status_code == requests.codes.ok : | |
| 269 return response.json() | |
| 270 elif status_code == requests.codes.unauthorized : | |
| 271 #expire_user(user) | |
| 272 stop_err("You are not authorized to do this. \nPlease login first.") | |
| 273 else : | |
| 274 stop_err("Error {code}: {reason}\n{message}".format(code=status_code, | |
| 275 reason=response.reason, | |
| 276 message=response.content)) | |
| 277 | |
| 278 | |
| 279 def stop_err(msg): | |
| 280 sys.stderr.write("%s\n" % msg) | |
| 281 sys.exit() |
