From 7903f1c71dcac47cd876f0e2b86107e1987b474f Mon Sep 17 00:00:00 2001 From: echyam Date: Thu, 13 Aug 2020 11:55:38 -0700 Subject: [PATCH] add underline to clickable texts, set default display text for jobs list if no job history yet --- dps_info/src/jobinfo.ts | 29 +- submit_jobs/submit_jobs/handlers.py | 2667 ++++++++++++++------------- 2 files changed, 1355 insertions(+), 1341 deletions(-) diff --git a/dps_info/src/jobinfo.ts b/dps_info/src/jobinfo.ts index d4ad57c1..ebc7a7a9 100644 --- a/dps_info/src/jobinfo.ts +++ b/dps_info/src/jobinfo.ts @@ -76,20 +76,23 @@ export class JobTable extends Widget { let disp = ''; if (this._job_id !== undefined || this._job_id !== ''){ disp = DISPLAYS[this._job_id]; + console.log(disp); } if (document.getElementById('job-detail-display') != null) { // console.log(this._job_id); - (document.getElementById('job-detail-display') as HTMLTextAreaElement).innerHTML = disp; + (document.getElementById('job-detail-display') as HTMLDivElement).innerHTML = disp; } else { // create textarea if it doesn't already exist // detailed info on one job - let display:HTMLTextAreaElement = document.createElement("textarea"); + //
+ let display:HTMLDivElement = document.createElement("div"); display.id = 'job-detail-display'; - display.readOnly = true; - display.cols = 30; + // display.readOnly = true; + // display.cols = 30; display.innerHTML = disp; - display.setAttribute('style', 'margin: 0px; height:17%; width: 98%; border: none; resize: none'); + // display.setAttribute('contenteditable', 'true'); + display.setAttribute('style', 'margin: 0px; height:17%; width: 105%; border: none; resize: none; font-size: 11px;'); display.className = 'jp-JSONEditor-host'; div2.appendChild(display); } @@ -146,7 +149,7 @@ export class JobTable extends Widget { // console.log(json_response); if (json_response['status_code'] === 200){ // let resp = json_response['result']; - me._table = json_response['result']; + me._table = json_response['results']; JOBS = json_response['jobs']; DISPLAYS = json_response['displays']; @@ -292,7 +295,8 @@ export class JobTable extends Widget { if (json_response['status_code'] === 200) { INotification.success("Get user job metrics success."); - this._results = json_response['results']; + this._metrics = json_response['results']; + console.log(this._metrics); } else { console.log('get user job result != 200'); INotification.error("Get user job metrics failed."); @@ -324,7 +328,7 @@ export class JobTable extends Widget { _setRowClick(tableId:string, setDisplays:any) { let me = this; onRowClick(tableId, function(row:HTMLTableRowElement){ - let job_id = row.getElementsByTagName('td')[0].innerHTML; + let job_id = row.getElementsByTagName('td')[0].innerText; console.log('set new job id '+job_id); me._job_id = job_id; setDisplays(me); @@ -444,7 +448,7 @@ export class JobWidget extends Widget { // new table row per algo let arow:HTMLTableRowElement = algoList.insertRow() as HTMLTableRowElement; let acell = arow.insertCell(); - acell.innerHTML = algo+':'+version; + acell.innerHTML = ''+algo+':'+version+''; arow.onclick = function() { me._algorithm = algo; me._version = version; @@ -907,14 +911,15 @@ export class JobWidget extends Widget { console.log('job not complete'); } else { console.log('looking up job results'); + let me = this; const res:RequestResult = await getResults(this._job_id,this._username); // console.log(res); if (res.ok) { let json_response:any = res.json(); - + // console.log(json_response); if (json_response['status_code'] === 200) { INotification.success("Get user job result success."); - this._results = json_response['results']; + me._results = json_response['results']; } else { console.log('get user job result != 200'); INotification.error("Get user job result failed."); @@ -1179,7 +1184,7 @@ export class JobWidget extends Widget { _setJobClick(tableId:string, setDisplays:any) { let me = this; onRowClick(tableId, function(row:HTMLTableRowElement){ - let job_id = row.getElementsByTagName('td')[0].innerHTML; + let job_id = row.getElementsByTagName('td')[0].innerText; console.log('widget set new job id '+job_id); me._job_id = job_id; setDisplays(me); diff --git a/submit_jobs/submit_jobs/handlers.py b/submit_jobs/submit_jobs/handlers.py index f08c5ba2..fecf5f03 100644 --- a/submit_jobs/submit_jobs/handlers.py +++ b/submit_jobs/submit_jobs/handlers.py @@ -30,1378 +30,1387 @@ # helper to parse out algorithm parameters for execute, describe def getParams(node): - tag = node.tag[node.tag.index('}')+1:] - if tag in ['Title','Identifier']: - return (tag,node.text) - elif tag == 'LiteralData': - return (node[1][1].tag.split('}')[-1],list(node[1][1].attrib.values())[0].split(':')[-1]) - else: - return (tag,[getParams(e) for e in node]) + tag = node.tag[node.tag.index('}')+1:] + if tag in ['Title','Identifier']: + return (tag,node.text) + elif tag == 'LiteralData': + return (node[1][1].tag.split('}')[-1],list(node[1][1].attrib.values())[0].split(':')[-1]) + else: + return (tag,[getParams(e) for e in node]) # helper to parse out products of result def getProds(node): - tag = node.tag[node.tag.index('}')+1:] - if tag in ['JobID']: - return (tag,node.text) - elif tag == 'Output': - return (tag,[loc.text for loc in node]) - else: - return (tag,[getProds(e) for e in node]) + tag = node.tag[node.tag.index('}')+1:] + if tag in ['JobID']: + return (tag,node.text) + elif tag == 'Output': + return (tag,[loc.text for loc in node]) + else: + return (tag,[getProds(e) for e in node]) # helper to parse out user-defined inputs when registering algorithm def parseInputs(popped): - p1 = [{e['name']:str(e['download']).lower()} for e in popped] # parse {"name":"varname","download":boolean} to {"varname":boolean}, convert boolean to lower - return {k: v for d in p1 for k, v in d.items()} # flatten list of dicts to just 1 dict + p1 = [{e['name']:str(e['download']).lower()} for e in popped] # parse {"name":"varname","download":boolean} to {"varname":boolean}, convert boolean to lower + return {k: v for d in p1 for k, v in d.items()} # flatten list of dicts to just 1 dict # helper to print accepted user-defined inputs when registering algorithm def printInputs(resp,inputs): - result = resp['message'] + '\nInputs:\n' - for name in inputs.keys(): - if len(name) > 0: - if inputs[name] == 'true': - result += '\t{} (download)\n'.format(name) - else: - result += '\t{} (no download)\n'.format(name) - return result + result = resp['message'] + '\nInputs:\n' + for name in inputs.keys(): + if len(name) > 0: + if inputs[name] == 'true': + result += '\t{} (download)\n'.format(name) + else: + result += '\t{} (no download)\n'.format(name) + return result # helper to parse user job history # convert list of strings to list of jobs, rep as dicts def parse_job(job): - job = eval(job) - job_id = job[0] - status = job[1] - algo_id = job[2] - inputs = job[3] - [x.pop('destination') for x in inputs] - ts = list(filter(lambda j: j['name'] == 'timestamp', inputs)) - ts = '0' if ts == [] else ts[0]['value'] - return {'job_id':job_id, 'status':status, 'algo_id':algo_id, 'inputs':inputs, 'timestamp':ts} + job = eval(job) + job_id = job[0] + status = job[1] + algo_id = job[2] + inputs = job[3] + [x.pop('destination') for x in inputs] + ts = list(filter(lambda j: j['name'] == 'timestamp', inputs)) + ts = '0' if ts == [] else ts[0]['value'] + return {'job_id':job_id, 'status':status, 'algo_id':algo_id, 'inputs':inputs, 'timestamp':ts} # helper to parse listed job's detailed info in HTML def detailed_display(job): - job_id = job['job_id'] - status = job['status'] - algo_id = job['algo_id'] - inputs = job['inputs'] + job_id = job['job_id'] + status = job['status'] + algo_id = job['algo_id'] + inputs = job['inputs'] - result = 'JobID: {}\nStatus: {}\nAlgorithm: {}\nInputs:\n'.format(job_id,status, algo_id) - for i in inputs: - result +=' {}: {}\n'.format(i['name'],i['value']) - return result + result = 'JobID: {}
Status: {}
Algorithm: {}
Inputs:
'.format(job_id,status, algo_id) + for i in inputs: + result +='        {}: {}
'.format(i['name'],i['value']) + return result # currently allows repos from both repo.nasa.maap and mas.maap-project class RegisterAlgorithmHandler(IPythonHandler): - def get(self,**params): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - # logging.debug('workdir is '+WORKDIR) - fields = ['config_path'] - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - # logging.debug('found '+f) - except: - params[f] = '' - # logging.debug('no '+f) - - # load register fields from config yaml - config = {} - os.path.exists(params['config_path']) - with open(params['config_path'], 'r') as stream: - config = yaml.load(stream) - - logging.debug('fields') - logging.debug(fields) - - logging.debug('config params are') - logging.debug(config) - - json_file = WORKDIR+"/submit_jobs/register_url.json" - - # only description and inputs are allowed to be empty - for f in ['algo_name','version','environment','run_command','repository_url','docker_url']: - if config[f] == '' or config[f] == None: - self.finish({"status_code": 412, "result": "Error: Register field {} cannot be empty".format(f)}) - return - - if not 'inputs' in config.keys(): - config['inputs']= {} - - # replace spaces in algorithm name - config['algo_name'] = config['algo_name'].replace(' ', '_') - - logging.debug('repo url is {}'.format(config['repository_url'])) - - # check if repo is hosted on a MAAP GitLab instance - if (not ('repo.nasa.maap') in config['repository_url']) and (not ('mas.maap-project') in config['repository_url']): - self.finish({"status_code": 412, "result": "Error: Your git repo is not from a supported host (repo.nasa.maap.xyz or mas.maap-project.org)"}) - return - - # ================================== - # Part 2: Check if User Has Committed - # ================================== - if params['config_path'] != '': - # navigate to project directory - # proj_path = ('/').join(['/projects']+params['config_path'].split('/')[:-1]) - proj_path = ('/').join(params['config_path'].split('/')[:-1]) - # proj_path = params['config_path'] - os.chdir(proj_path) - - # get git status - try: - git_status_out = subprocess.check_output("git status --branch --porcelain", shell=True).decode("utf-8") - logger.debug(git_status_out) - - # is there a git repo? - except: - # subprocess could also error out (nonzero exit code) - self.finish({"status_code": 412, "result": "Error: \nThe code you want to register is not saved in a git repository."}) - return - - git_status = git_status_out.splitlines()[1:] - git_status = [e.strip() for e in git_status] - - # filter for unsaved python, julia, matlab shell files - unsaved = list(filter(lambda e: ( (e.split('.')[-1] in ['ipynb','py','sh','jl','r','m','mat']) and (e[0] in ['M','?']) ), git_status)) - if len(unsaved) != 0: - self.finish({"status_code": 412, "result": "Error: Notebook(s) and/or script(s) have not been committed\n{}".format('\n'.join(unsaved))}) - return - - git_unpushed = ('[ahead' in git_status_out[0].strip()) - if git_unpushed: - self.finish({"status_code": 412, "result": "Error: Recent commits have not been pushed"}) - return - - # ================================== - # Part 3: Build & Send Request - # ================================== - json_in_file = WORKDIR+"/submit_jobs/register_inputs.json" - url = BASE_URL+'/mas/algorithm' - headers = {'Content-Type':'application/json'} - - if 'proxy-ticket' in params.keys(): - headers['proxy-ticket'] = params.get('proxy-ticket') - - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - - with open(json_in_file) as f: - ins_json = f.read() - - # build inputs json - popped = config.pop('inputs') - inputs = parseInputs(popped) if popped != None else {} - - ins = '' - for name in inputs.keys(): - if len(name) > 0: - ins += ins_json.format(field_name=name,dl=inputs[name]) - - # print(ins) - # add inputs json to config for template substitution - config['algo_inputs'] = ins - - with open(json_file) as jso: - req_json = jso.read() - - req_json = req_json.format(**config) - logging.debug('request is') - logging.debug(req_json) - - # ================================== - # Part 4: Check Response - # ================================== - try: - r = requests.post( - url=url, - data=req_json, - headers=headers - ) - print(r.text) - if r.status_code == 200: - try: - # MAAP API response - resp = json.loads(r.text) - # show registered inputs - result = printInputs(resp,inputs) - self.finish({"status_code": resp['code'], "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - else: - print('failed') - self.finish({"status_code": r.status_code, "result": r.reason}) - except: - self.finish({"status_code": 400, "result": "Bad Request"}) + def get(self,**params): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + # logging.debug('workdir is '+WORKDIR) + fields = ['config_path'] + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + # logging.debug('found '+f) + except: + params[f] = '' + # logging.debug('no '+f) + + # load register fields from config yaml + config = {} + os.path.exists(params['config_path']) + with open(params['config_path'], 'r') as stream: + config = yaml.load(stream) + + logging.debug('fields') + logging.debug(fields) + + logging.debug('config params are') + logging.debug(config) + + json_file = WORKDIR+"/submit_jobs/register_url.json" + + # only description and inputs are allowed to be empty + for f in ['algo_name','version','environment','run_command','repository_url','docker_url']: + if config[f] == '' or config[f] == None: + self.finish({"status_code": 412, "result": "Error: Register field {} cannot be empty".format(f)}) + return + + if not 'inputs' in config.keys(): + config['inputs']= {} + + # replace spaces in algorithm name + config['algo_name'] = config['algo_name'].replace(' ', '_') + + logging.debug('repo url is {}'.format(config['repository_url'])) + + # check if repo is hosted on a MAAP GitLab instance + if (not ('repo.nasa.maap') in config['repository_url']) and (not ('mas.maap-project') in config['repository_url']): + self.finish({"status_code": 412, "result": "Error: Your git repo is not from a supported host (repo.nasa.maap.xyz or mas.maap-project.org)"}) + return + + # ================================== + # Part 2: Check if User Has Committed + # ================================== + if params['config_path'] != '': + # navigate to project directory + # proj_path = ('/').join(['/projects']+params['config_path'].split('/')[:-1]) + proj_path = ('/').join(params['config_path'].split('/')[:-1]) + # proj_path = params['config_path'] + os.chdir(proj_path) + + # get git status + try: + git_status_out = subprocess.check_output("git status --branch --porcelain", shell=True).decode("utf-8") + logger.debug(git_status_out) + + # is there a git repo? + except: + # subprocess could also error out (nonzero exit code) + self.finish({"status_code": 412, "result": "Error: \nThe code you want to register is not saved in a git repository."}) + return + + git_status = git_status_out.splitlines()[1:] + git_status = [e.strip() for e in git_status] + + # filter for unsaved python, julia, matlab shell files + unsaved = list(filter(lambda e: ( (e.split('.')[-1] in ['ipynb','py','sh','jl','r','m','mat']) and (e[0] in ['M','?']) ), git_status)) + if len(unsaved) != 0: + self.finish({"status_code": 412, "result": "Error: Notebook(s) and/or script(s) have not been committed\n{}".format('\n'.join(unsaved))}) + return + + git_unpushed = ('[ahead' in git_status_out[0].strip()) + if git_unpushed: + self.finish({"status_code": 412, "result": "Error: Recent commits have not been pushed"}) + return + + # ================================== + # Part 3: Build & Send Request + # ================================== + json_in_file = WORKDIR+"/submit_jobs/register_inputs.json" + url = BASE_URL+'/mas/algorithm' + headers = {'Content-Type':'application/json'} + + if 'proxy-ticket' in params.keys(): + headers['proxy-ticket'] = params.get('proxy-ticket') + + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + + with open(json_in_file) as f: + ins_json = f.read() + + # build inputs json + popped = config.pop('inputs') + inputs = parseInputs(popped) if popped != None else {} + + ins = '' + for name in inputs.keys(): + if len(name) > 0: + ins += ins_json.format(field_name=name,dl=inputs[name]) + + # print(ins) + # add inputs json to config for template substitution + config['algo_inputs'] = ins + + with open(json_file) as jso: + req_json = jso.read() + + req_json = req_json.format(**config) + logging.debug('request is') + logging.debug(req_json) + + # ================================== + # Part 4: Check Response + # ================================== + try: + r = requests.post( + url=url, + data=req_json, + headers=headers + ) + print(r.text) + if r.status_code == 200: + try: + # MAAP API response + resp = json.loads(r.text) + # show registered inputs + result = printInputs(resp,inputs) + self.finish({"status_code": resp['code'], "result": result}) + except: + self.finish({"status_code": r.status_code, "result": r.text}) + else: + print('failed') + self.finish({"status_code": r.status_code, "result": r.reason}) + except: + self.finish({"status_code": 400, "result": "Bad Request"}) class DeleteAlgorithmHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - complete = True - fields = getFields('deleteAlgorithm') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - complete = False - - if all(e == '' for e in list(params.values())): - complete = False - - print(complete) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - # return all algorithms if malformed request - headers = {'Content-Type':'application/json'} - logging.debug('headers:') - logging.debug(headers) - - if complete: - url = BASE_URL+'/mas/algorithm/{algo_id}:{version}'.format(**params) - logging.debug('request sent to {}'.format(url)) - r = requests.delete( - url, - headers=headers - ) - else: - url = BASE_URL+'/mas/algorithm' - logging.debug('request sent to {}'.format(url)) - r = requests.get( - url, - headers=headers - ) - - # print(url) - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check & Parse Response - # ================================== - - if r.status_code == 200: - try: - if complete: - # MAAP API response - resp = json.loads(r.text) - # show registered inputs - result = resp['message'] - else: - resp = json.loads(r.text) - result = 'Algorithms:\n' - for e in resp['algorithms']: - result += '\t{}:{}\n'.format(e['type'],e['version']) - - if result.strip() == '': - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result}) - return - - # print(result) - self.finish({"status_code": r.status_code, "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - - # malformed request will still give 500 - elif r.status_code == 500: - if 'AttributeError' in r.text: - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) - else: - self.finish({"status_code": 400, "result": "Bad Request"}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + complete = True + fields = getFields('deleteAlgorithm') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + complete = False + + if all(e == '' for e in list(params.values())): + complete = False + + print(complete) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + # return all algorithms if malformed request + headers = {'Content-Type':'application/json'} + logging.debug('headers:') + logging.debug(headers) + + if complete: + url = BASE_URL+'/mas/algorithm/{algo_id}:{version}'.format(**params) + logging.debug('request sent to {}'.format(url)) + r = requests.delete( + url, + headers=headers + ) + else: + url = BASE_URL+'/mas/algorithm' + logging.debug('request sent to {}'.format(url)) + r = requests.get( + url, + headers=headers + ) + + # print(url) + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check & Parse Response + # ================================== + + if r.status_code == 200: + try: + if complete: + # MAAP API response + resp = json.loads(r.text) + # show registered inputs + result = resp['message'] + else: + resp = json.loads(r.text) + result = 'Algorithms:\n' + for e in resp['algorithms']: + result += '\t{}:{}\n'.format(e['type'],e['version']) + + if result.strip() == '': + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result}) + return + + # print(result) + self.finish({"status_code": r.status_code, "result": result}) + except: + self.finish({"status_code": r.status_code, "result": r.text}) + + # malformed request will still give 500 + elif r.status_code == 500: + if 'AttributeError' in r.text: + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result}) + else: + self.finish({"status_code": r.status_code, "result": r.reason}) + else: + self.finish({"status_code": 400, "result": "Bad Request"}) class PublishAlgorithmHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - complete = True - fields = getFields('publishAlgorithm') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - complete = False - - if all(e == '' for e in list(params.values())): - complete = False - - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - # return all algorithms if malformed request - headers = {'Content-Type':'application/json'} - if 'proxy-ticket' in params.keys(): - headers['proxy-ticket'] = params.get('proxy-ticket') - - logging.debug('headers:') - logging.debug(headers) - - url = BASE_URL+'/mas/publish' - body = {'algo_id': params['algo_id'], 'version': params['version']} - logging.debug('request sent to {}'.format(url)) - r = requests.post( - url, - headers=headers, - data=body - ) - - # print(url) - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check & Parse Response - # ================================== - - if r.status_code == 200: - try: - if complete: - # MAAP API response - resp = json.loads(r.text) - # show registered inputs - result = resp['message'] - else: - resp = json.loads(r.text) - result = 'Algorithms:\n' - for e in resp['algorithms']: - result += '\t{}:{}\n'.format(e['type'],e['version']) - - if result.strip() == '': - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result}) - return - - # print(result) - self.finish({"status_code": r.status_code, "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - - # malformed request will still give 500 - elif r.status_code == 500: - if 'AttributeError' in r.text: - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + complete = True + fields = getFields('publishAlgorithm') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + complete = False + + if all(e == '' for e in list(params.values())): + complete = False + + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + # return all algorithms if malformed request + headers = {'Content-Type':'application/json'} + if 'proxy-ticket' in params.keys(): + headers['proxy-ticket'] = params.get('proxy-ticket') + + logging.debug('headers:') + logging.debug(headers) + + url = BASE_URL+'/mas/publish' + body = {'algo_id': params['algo_id'], 'version': params['version']} + logging.debug('request sent to {}'.format(url)) + r = requests.post( + url, + headers=headers, + data=body + ) + + # print(url) + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check & Parse Response + # ================================== + + if r.status_code == 200: + try: + if complete: + # MAAP API response + resp = json.loads(r.text) + # show registered inputs + result = resp['message'] + else: + resp = json.loads(r.text) + result = 'Algorithms:\n' + for e in resp['algorithms']: + result += '\t{}:{}\n'.format(e['type'],e['version']) + + if result.strip() == '': + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result}) + return + + # print(result) + self.finish({"status_code": r.status_code, "result": result}) + except: + self.finish({"status_code": r.status_code, "result": r.text}) + + # malformed request will still give 500 + elif r.status_code == 500: + if 'AttributeError' in r.text: + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result}) + else: + self.finish({"status_code": r.status_code, "result": r.reason}) + else: + self.finish({"status_code": r.status_code, "result": r.reason}) class GetCapabilitiesHandler(IPythonHandler): - def get(self): - # No Required Arguments - # ================================== - # Part 1: Build & Send Request - # ================================== - url = BASE_URL+'/dps/job' - headers = {'Content-Type':'application/json'} - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - - r = requests.get( - url, - headers=headers - ) - - # ================================== - # Part 2: Check & Parse Response - # ================================== - try: - try: - # parse out capability names & request info - rt = ET.fromstring(r.text) - result = '' - - meta = rt[0] - info = [(n.tag[n.tag.index('}')+1:], n.text) for n in meta] - for (tag,txt) in info: - result += '{tag}: {txt}\n'.format(tag=tag,txt=txt) - result += '\n' - - cap = rt[2] - cap_info = [ \ - ( e.attrib['name'], \ - e[0][0][0].tag[ e[0][0][0].tag.index('}')+1 : ], \ - list(e[0][0][0].attrib.values())[0] \ - ) for e in cap ] - - # print request type and url in indented new line below capability name - for (title, req_type, req_url) in cap_info: - result += '{title}\n {req_type}\n {req_url}\n\n'.format(title=title,req_type=req_type,req_url=req_url) - - # print(result) - self.finish({"status_code": r.status_code, "result": result}) - - except: - self.finish({"status_code": r.status_code, "result": r.text}) - except: - print('failed') - self.finish({"status_code": r.status_code, "result": r.reason}) + def get(self): + # No Required Arguments + # ================================== + # Part 1: Build & Send Request + # ================================== + url = BASE_URL+'/dps/job' + headers = {'Content-Type':'application/json'} + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + + r = requests.get( + url, + headers=headers + ) + + # ================================== + # Part 2: Check & Parse Response + # ================================== + try: + try: + # parse out capability names & request info + rt = ET.fromstring(r.text) + result = '' + + meta = rt[0] + info = [(n.tag[n.tag.index('}')+1:], n.text) for n in meta] + for (tag,txt) in info: + result += '{tag}: {txt}\n'.format(tag=tag,txt=txt) + result += '\n' + + cap = rt[2] + cap_info = [ \ + ( e.attrib['name'], \ + e[0][0][0].tag[ e[0][0][0].tag.index('}')+1 : ], \ + list(e[0][0][0].attrib.values())[0] \ + ) for e in cap ] + + # print request type and url in indented new line below capability name + for (title, req_type, req_url) in cap_info: + result += '{title}\n {req_type}\n {req_url}\n\n'.format(title=title,req_type=req_type,req_url=req_url) + + # print(result) + self.finish({"status_code": r.status_code, "result": result}) + + except: + self.finish({"status_code": r.status_code, "result": r.text}) + except: + print('failed') + self.finish({"status_code": r.status_code, "result": r.reason}) class ExecuteHandler(IPythonHandler): - def get(self): - xml_file = WORKDIR+"/submit_jobs/execute.xml" - input_xml = WORKDIR+"/submit_jobs/execute_inputs.xml" - - # ================================== - # Part 1: Parse Required Arguments - # ================================== - fields = getFields('execute') - input_names = self.get_argument("inputs", '').split(',')[:-1] - if not 'username' in input_names: - input_names.append('username') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - params[f] = '' - - inputs = {} - for f in input_names: - try: - arg = self.get_argument(f.lower(), '').strip() - inputs[f] = arg - except: - inputs[f] = '' - - logging.debug('fields are') - logging.debug(fields) - - logging.debug('params are') - logging.debug(params) - - logging.debug('inputs are') - logging.debug(inputs) - - params['timestamp'] = str(datetime.datetime.today()) - if 'username' in params.keys() and inputs['username'] =='': - inputs['username'] = 'anonymous' - # if inputs['localize_urls'] == '': - # inputs['localize_urls'] = [] - # print(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - req_xml = '' - ins_xml = '' - url = BASE_URL+'/dps/job' - headers = {'Content-Type':'application/xml'} - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - - other = '' - with open(input_xml) as xml: - ins_xml = xml.read() - - # ------------------------------- - # Insert XML for algorithm inputs - # ------------------------------- - for i in range(len(input_names)): - name = input_names[i] - other += ins_xml.format(name=name).format(value=inputs[name]) - other += '\n' - - # print(other) - params['other_inputs'] = other - - with open(xml_file) as xml: - req_xml = xml.read() - - req_xml = req_xml.format(**params) - - logging.debug('request is') - logging.debug(req_xml) - - # ------------------------------- - # Send Request - # ------------------------------- - try: - r = requests.post( - url=url, - data=req_xml, - headers=headers - ) - logging.debug('status code '+str(r.status_code)) - logging.debug('response text\n'+r.text) - - # ================================== - # Part 3: Check & Parse Response - # ================================== - # malformed request will still give 200 - if r.status_code == 200: - try: - # parse out JobID from response - rt = ET.fromstring(r.text) - - # if bad request, show provided parameters - if 'Exception' in r.text: - result = 'Exception: {}\n'.format(rt[0].attrib['exceptionCode']) - result += 'Bad Request\nThe provided parameters were:\n' - for f in fields: - result += '\t{}: {}\n'.format(f,params[f]) - result += '\n' - self.finish({"status_code": 400, "result": result}) - - else: - job_id = rt[0].text - # print(job_id) - - result = 'JobID is {}'.format(job_id) - # print("success!") - self.finish({"status_code": r.status_code, "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) - except: - self.finish({"status_code": 400, "result": "Bad Request"}) + def get(self): + xml_file = WORKDIR+"/submit_jobs/execute.xml" + input_xml = WORKDIR+"/submit_jobs/execute_inputs.xml" + + # ================================== + # Part 1: Parse Required Arguments + # ================================== + fields = getFields('execute') + input_names = self.get_argument("inputs", '').split(',')[:-1] + if not 'username' in input_names: + input_names.append('username') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + params[f] = '' + + inputs = {} + for f in input_names: + try: + arg = self.get_argument(f.lower(), '').strip() + inputs[f] = arg + except: + inputs[f] = '' + + logging.debug('fields are') + logging.debug(fields) + + logging.debug('params are') + logging.debug(params) + + logging.debug('inputs are') + logging.debug(inputs) + + params['timestamp'] = str(datetime.datetime.today()) + if 'username' in params.keys() and inputs['username'] =='': + inputs['username'] = 'anonymous' + # if inputs['localize_urls'] == '': + # inputs['localize_urls'] = [] + # print(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + req_xml = '' + ins_xml = '' + url = BASE_URL+'/dps/job' + headers = {'Content-Type':'application/xml'} + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + + other = '' + with open(input_xml) as xml: + ins_xml = xml.read() + + # ------------------------------- + # Insert XML for algorithm inputs + # ------------------------------- + for i in range(len(input_names)): + name = input_names[i] + other += ins_xml.format(name=name).format(value=inputs[name]) + other += '\n' + + # print(other) + params['other_inputs'] = other + + with open(xml_file) as xml: + req_xml = xml.read() + + req_xml = req_xml.format(**params) + + logging.debug('request is') + logging.debug(req_xml) + + # ------------------------------- + # Send Request + # ------------------------------- + try: + r = requests.post( + url=url, + data=req_xml, + headers=headers + ) + logging.debug('status code '+str(r.status_code)) + logging.debug('response text\n'+r.text) + + # ================================== + # Part 3: Check & Parse Response + # ================================== + # malformed request will still give 200 + if r.status_code == 200: + try: + # parse out JobID from response + rt = ET.fromstring(r.text) + + # if bad request, show provided parameters + if 'Exception' in r.text: + result = 'Exception: {}\n'.format(rt[0].attrib['exceptionCode']) + result += 'Bad Request\nThe provided parameters were:\n' + for f in fields: + result += '\t{}: {}\n'.format(f,params[f]) + result += '\n' + self.finish({"status_code": 400, "result": result}) + + else: + job_id = rt[0].text + # print(job_id) + + result = 'JobID is {}'.format(job_id) + # print("success!") + self.finish({"status_code": r.status_code, "result": result}) + except: + self.finish({"status_code": r.status_code, "result": r.text}) + else: + self.finish({"status_code": r.status_code, "result": r.reason}) + except: + self.finish({"status_code": 400, "result": "Bad Request"}) class GetStatusHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - fields = getFields('getStatus') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - arg = '' - - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - url = BASE_URL+'/dps/job/{job_id}/status'.format(**params) - headers = {'Content-Type':'application/xml'} - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - # print(url) - # print(req_xml) - - try: - r = requests.get( - url, - headers=headers - ) - - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check Response - # ================================== - # bad job id will still give 200 - if r.status_code == 200: - try: - # parse out JobID from response - rt = ET.fromstring(r.text) - - job_id = rt[0].text - job_status = rt[1].text - # print(job_id) - - result = 'JobID is {}\nStatus: {}'.format(job_id,job_status) - # print("success!") - self.finish({"status_code": r.status_code, "result": result, "job_status":job_status}) - except: - self.finish({"status_code": r.status_code, "result": r.text, "job_status":''}) - # if no job id provided - elif r.status_code in [404]: - # if bad job id, show provided parameters - result = 'Exception: {}\nMessage: {}\n(Did you provide a valid JobID?)\n'.format(rt[0].attrib['exceptionCode'], rt[0][0].text) - result += '\nThe provided parameters were:\n' - for f in fields: - result += '\t{}: {}\n'.format(f,params[f]) - result += '\n' - self.finish({"status_code": 404, "result": result, "job_status":''}) - else: - self.finish({"status_code": r.status_code, "result": r.reason, "job_status":''}) - except: - self.finish({"status_code": 400, "result": "Bad Request","job_status":''}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + fields = getFields('getStatus') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + arg = '' + + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + url = BASE_URL+'/dps/job/{job_id}/status'.format(**params) + headers = {'Content-Type':'application/xml'} + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + # print(url) + # print(req_xml) + + try: + r = requests.get( + url, + headers=headers + ) + + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check Response + # ================================== + # bad job id will still give 200 + if r.status_code == 200: + try: + # parse out JobID from response + rt = ET.fromstring(r.text) + + job_id = rt[0].text + job_status = rt[1].text + # print(job_id) + + result = 'JobID is {}\nStatus: {}'.format(job_id,job_status) + # print("success!") + self.finish({"status_code": r.status_code, "result": result, "job_status":job_status}) + except: + self.finish({"status_code": r.status_code, "result": r.text, "job_status":''}) + # if no job id provided + elif r.status_code in [404]: + # if bad job id, show provided parameters + result = 'Exception: {}\nMessage: {}\n(Did you provide a valid JobID?)\n'.format(rt[0].attrib['exceptionCode'], rt[0][0].text) + result += '\nThe provided parameters were:\n' + for f in fields: + result += '\t{}: {}\n'.format(f,params[f]) + result += '\n' + self.finish({"status_code": 404, "result": result, "job_status":''}) + else: + self.finish({"status_code": r.status_code, "result": r.reason, "job_status":''}) + except: + self.finish({"status_code": 400, "result": "Bad Request","job_status":''}) class GetMetricsHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - fields = getFields('getMetrics') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - arg = '' - - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - url = BASE_URL+'/dps/job/{job_id}/metrics'.format(**params) - headers = {'Content-Type':'application/xml'} - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - # print(url) - # print(req_xml) - - try: - r = requests.get( - url, - headers=headers - ) - - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check Response - # ================================== - if r.status_code == 200: - try: - # parse XML response - metrics = ET.fromstring(r.text) - logging.debug(metrics) - - # format metrics into html table - result = '' - result += '' - for n in metrics: - result += ''.format(n.tag,n.text) - result += '' - result += '
{}{}
' - logging.debug(result) - # print("success!") - self.finish({"status_code": r.status_code, "results": result, "metrics":r.text}) - except: - self.finish({"status_code": r.status_code, "results": r.text, "metrics":{}}) - else: - self.finish({"status_code": r.status_code, "results": r.reason, "metrics":{}}) - - except: - self.finish({"status_code": 400, "results": "Bad Request","metrics":{}}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + fields = getFields('getMetrics') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + arg = '' + + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + url = BASE_URL+'/dps/job/{job_id}/metrics'.format(**params) + headers = {'Content-Type':'application/xml'} + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + # print(url) + # print(req_xml) + + try: + r = requests.get( + url, + headers=headers + ) + + print(r.status_code) + print(r.text) + + # ================================== + # Part 3: Check Response + # ================================== + if r.status_code == 200: + try: + # parse XML response + metrics = ET.fromstring(r.text) + logging.debug(metrics) + + # format metrics into html table + result = '' + result += '' + for n in metrics: + result += ''.format(n.tag,n.text) + result += '' + result += '
{}{}
' + logging.debug(result) + # print("success!") + self.finish({"status_code": r.status_code, "results": result, "metrics":r.text}) + except: + self.finish({"status_code": r.status_code, "results": r.text, "metrics":{}}) + else: + self.finish({"status_code": r.status_code, "results": r.reason, "metrics":{}}) + + except: + self.finish({"status_code": 400, "results": "Bad Request","metrics":{}}) class GetResultHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - fields = getFields('getResult') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - arg = '' - - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - url = BASE_URL+'/dps/job/{job_id}'.format(**params) - headers = {'Content-Type':'application/xml'} - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - # print(url) - # print(req_xml) - - try: - r = requests.get( - url, - headers=headers - ) - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check & Parse Response - # ================================== - if r.status_code == 200: - try: - # parse out JobID from response - rt = ET.fromstring(r.text) - - # if bad job id, show provided parameters - if 'Exception' in r.text: - result = 'Exception: {}\nMessage: {}\n'.format(rt[0].attrib['exceptionCode'], rt[0][0].text) - result += '\nThe provided parameters were:\n' - for f in fields: - result += '\t{}: {}\n'.format(f,params[f]) - result += '\n' - - self.finish({"status_code": 404, "result": result}) - else: - job_id = rt[0].text - logging.debug('job_id is {}'.format(job_id)) - # print(job_id) - - result = '' - # result += '' - result += '' - result += ''.format(job_id) - - # get product name - product_name = rt[1].attrib['id'] - logging.debug('product name is {}'.format(product_name)) - result += ''.format(product_name) - - # format urls for table - prods = rt[1] - p = getProds(prods) #(Output,['url1','url2']) - - url_lst = p[1] - - ## make the last link clickable - lnk = url_lst[-1] - url_lst[-1] = '{}'.format(lnk,lnk) - - urls_str = '• '+('
• ').join(url_lst) - result += ''.format('Locations',urls_str) - - result += '' - result += '
Job Results
JobID: {}
ProductName: {}
{}: {}
' - logging.debug(result) - - # print("success!") - self.finish({"status_code": r.status_code, "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - # if no job id provided - elif r.status_code in [404]: - # print('404?') - # if bad job id, show provided parameters - result = 'Exception: {}\nMessage: {}\n(Did you provide a valid JobID?)\n'.format(rt[0].attrib['exceptionCode'], rt[0][0].text) - result += '\nThe provided parameters were:\n' - for f in fields: - result += '\t{}: {}\n'.format(f,params[f]) - result += '\n' - self.finish({"status_code": 404, "result": result}) - - else: - try: - rt = ET.fromstring(r.text) - result = rt[0][0].text - self.finish({"status_code": r.status_code, "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.reason}) - except: - self.finish({"status_code": 400, "result": "Bad Request"}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + fields = getFields('getResult') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + arg = '' + + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + url = BASE_URL+'/dps/job/{job_id}'.format(**params) + headers = {'Content-Type':'application/xml'} + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + # print(url) + # print(req_xml) + + try: + r = requests.get( + url, + headers=headers + ) + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check & Parse Response + # ================================== + if r.status_code == 200: + try: + # parse out JobID from response + rt = ET.fromstring(r.text) + + # if bad job id, show provided parameters + if 'Exception' in r.text: + result = 'Exception: {}\nMessage: {}\n'.format(rt[0].attrib['exceptionCode'], rt[0][0].text) + result += '\nThe provided parameters were:\n' + for f in fields: + result += '\t{}: {}\n'.format(f,params[f]) + result += '\n' + + self.finish({"status_code": 404, "results": result}) + else: + job_id = rt[0].text + logging.debug('job_id is {}'.format(job_id)) + # print(job_id) + + result = '' + # result += '' + result += '' + result += ''.format(job_id) + + # get product name + product_name = rt[1].attrib['id'] + logging.debug('product name is {}'.format(product_name)) + result += ''.format(product_name) + + # format urls for table + prods = rt[1] + p = getProds(prods) #(Output,['url1','url2']) + + url_lst = p[1] + + ## make the last link clickable + lnk = url_lst[-1] + url_lst[-1] = '{}'.format(lnk,lnk) + + urls_str = '• '+('
• ').join(url_lst) + result += ''.format('Locations',urls_str) + + result += '' + result += '
Job Results
JobID: {}
ProductName: {}
{}: {}
' + logging.debug(result) + + # print("success!") + self.finish({"status_code": r.status_code, "results": result}) + except: + self.finish({"status_code": r.status_code, "results": r.text}) + # if no job id provided + elif r.status_code in [404]: + # print('404?') + # if bad job id, show provided parameters + result = 'Exception: {}\nMessage: {}\n(Did you provide a valid JobID?)\n'.format(rt[0].attrib['exceptionCode'], rt[0][0].text) + result += '\nThe provided parameters were:\n' + for f in fields: + result += '\t{}: {}\n'.format(f,params[f]) + result += '\n' + self.finish({"status_code": 404, "results": result}) + + else: + try: + rt = ET.fromstring(r.text) + result = rt[0][0].text + self.finish({"status_code": r.status_code, "result": result}) + except: + self.finish({"status_code": r.status_code, "results": r.reason}) + except: + self.finish({"status_code": 400, "results": "Bad Request"}) class DismissHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - fields = getFields('dismiss') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - arg = '' - - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - url = BASE_URL+'/dps/job/revoke/{job_id}'.format(**params) - headers = {'Content-Type':'application/xml'} - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - # print(url) - # print(req_xml) - - try: - r = requests.delete( - url, - headers=headers - ) - - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check Response - # ================================== - # if no job id provided - if params['job_id'] == '': - result = 'Exception: \nMessage: {}\nEmpty JobID provided.\n' - result += '\nThe provided parameters were:\n' - for f in fields: - result += '\t{}: {}\n'.format(f,params[f]) - result += '\n' - self.finish({"status_code": 404, "result": result}) - elif 'Exception' in r.text: - # parse exception code and message from xml response - rt = ET.fromstring(r.text) - exception_code = rt[0].attrib['exceptionCode'] - exception_text = rt[0][0].text - - result = 'Exception: {}\nMessage: {}\n'.format(exception_code, exception_text) - result += '\nThe provided parameters were:\n' - - for f in fields: - result += '\t{}: {}\n'.format(f,params[f]) - result += '\n' - self.finish({"status_code": 404, "result": result}) - # if dismissal successful - elif r.status_code == 200: - try: - # parse out JobID from response - rt = ET.fromstring(r.text) - - job_id = rt[0].text - status = rt[1].text - # print(job_id) - - result = 'JobID is {}\nStatus: {}'.format(job_id,status) - # print("success!") - self.finish({"status_code": r.status_code, "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) - except: - self.finish({"status_code": 400, "result": "Bad Request"}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + fields = getFields('dismiss') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + arg = '' + + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + url = BASE_URL+'/dps/job/revoke/{job_id}'.format(**params) + headers = {'Content-Type':'application/xml'} + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + # print(url) + # print(req_xml) + + try: + r = requests.delete( + url, + headers=headers + ) + + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check Response + # ================================== + # if no job id provided + if params['job_id'] == '': + result = 'Exception: \nMessage: {}\nEmpty JobID provided.\n' + result += '\nThe provided parameters were:\n' + for f in fields: + result += '\t{}: {}\n'.format(f,params[f]) + result += '\n' + self.finish({"status_code": 404, "result": result}) + elif 'Exception' in r.text: + # parse exception code and message from xml response + rt = ET.fromstring(r.text) + exception_code = rt[0].attrib['exceptionCode'] + exception_text = rt[0][0].text + + result = 'Exception: {}\nMessage: {}\n'.format(exception_code, exception_text) + result += '\nThe provided parameters were:\n' + + for f in fields: + result += '\t{}: {}\n'.format(f,params[f]) + result += '\n' + self.finish({"status_code": 404, "result": result}) + # if dismissal successful + elif r.status_code == 200: + try: + # parse out JobID from response + rt = ET.fromstring(r.text) + + job_id = rt[0].text + status = rt[1].text + # print(job_id) + + result = 'JobID is {}\nStatus: {}'.format(job_id,status) + # print("success!") + self.finish({"status_code": r.status_code, "result": result}) + except: + self.finish({"status_code": r.status_code, "result": r.text}) + else: + self.finish({"status_code": r.status_code, "result": r.reason}) + except: + self.finish({"status_code": 400, "result": "Bad Request"}) class DeleteHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - fields = getFields('delete') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - arg = '' - - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - url = BASE_URL+'/dps/job/{job_id}'.format(**params) - headers = {'Content-Type':'application/xml'} - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - # print(url) - # print(req_xml) - - try: - r = requests.delete( - url, - headers=headers - ) - - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check Response - # ================================== - # if no job id provided - if params['job_id'] == '': - result = 'Exception: \nMessage: {}\nEmpty JobID provided.\n' - result += '\nThe provided parameters were:\n' - for f in fields: - result += '\t{}: {}\n'.format(f,params[f]) - result += '\n' - self.finish({"status_code": 404, "result": result}) - # if deletion successful - elif r.status_code == 200: - try: - # parse out JobID from response - rt = ET.fromstring(r.text) - - job_id = rt[0].text - status = rt[1].text - # print(job_id) - - result = 'JobID is {}\nStatus: {}'.format(job_id,status) - # print("success!") - self.finish({"status_code": r.status_code, "result": result}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) - except: - self.finish({"status_code": 400, "result": "Bad Request"}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + fields = getFields('delete') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + arg = '' + + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + url = BASE_URL+'/dps/job/{job_id}'.format(**params) + headers = {'Content-Type':'application/xml'} + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + # print(url) + # print(req_xml) + + try: + r = requests.delete( + url, + headers=headers + ) + + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check Response + # ================================== + # if no job id provided + if params['job_id'] == '': + result = 'Exception: \nMessage: {}\nEmpty JobID provided.\n' + result += '\nThe provided parameters were:\n' + for f in fields: + result += '\t{}: {}\n'.format(f,params[f]) + result += '\n' + self.finish({"status_code": 404, "result": result}) + # if deletion successful + elif r.status_code == 200: + try: + # parse out JobID from response + rt = ET.fromstring(r.text) + + job_id = rt[0].text + status = rt[1].text + # print(job_id) + + result = 'JobID is {}\nStatus: {}'.format(job_id,status) + # print("success!") + self.finish({"status_code": r.status_code, "result": result}) + except: + self.finish({"status_code": r.status_code, "result": r.text}) + else: + self.finish({"status_code": r.status_code, "result": r.reason}) + except: + self.finish({"status_code": 400, "result": "Bad Request"}) class DescribeProcessHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - complete = True - fields = getFields('describeProcess') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - complete = False - - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - headers = {'Content-Type':'application/json'} - if 'proxy-ticket' in params.keys(): - ticket = params.get('proxy-ticket') - if not ticket == 'undefined': - headers['proxy-ticket'] = ticket - - params.pop('proxy-ticket') - if all(e == '' for e in list(params.values())): - complete = False - - logging.debug(list(params.values())) - logging.debug(complete) - - # return all algorithms if malformed request - if complete: - url = BASE_URL+'/mas/algorithm/{algo_id}:{version}'.format(**params) - else: - url = BASE_URL+'/mas/algorithm' - - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - - r = requests.get( - url, - headers=headers - ) - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check & Parse Response - # ================================== - - if r.status_code == 200: - algo_lst = [] - try: - if complete: - # parse out capability names & request info - rt = ET.fromstring(r.text) - attrib = [getParams(e) for e in rt[0][0]] - - result = '' - for (tag,txt) in attrib: - if tag == 'Input': - result += '{}\n'.format(tag) - for (tag1,txt1) in txt: - if tag1 != 'Identifier': - result += '\t{tag1}:\t{txt1}\n'.format(tag1=tag1,txt1=txt1) - if tag1 == 'Title:': - algo_lst.append(txt1) - result += '\n' - - elif tag == 'Title': - txt = txt.split(';') - for itm in txt: - result += '{}\n'.format(itm.strip()) - elif tag != 'Identifier': - result += '{tag}:\t{txt}\n'.format(tag=tag,txt=txt) - - # if no algorithm passed, list all algorithms - else: - resp = json.loads(r.text) - result = 'Algorithms:\n' - for e in resp['algorithms']: - result += '\t{}:{}\n'.format(e['type'],e['version']) - - # return set of algos, each mapped to list of versions - lst = result.replace('\n','').split('\t')[1:] - splt_lst = [e.split(':') for e in lst] - algo_lst = {} - - for a in splt_lst: - if not a[0] in algo_lst: - algo_lst[a[0]] = [a[1]] - else: - algo_lst[a[0]].append(a[1]) - - if result.strip() == '': - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result}) - return - - # print(result) - self.finish({"status_code": r.status_code, "result": result, "algo_set": algo_lst}) - except: - self.finish({"status_code": r.status_code, "result": r.text}) - - # malformed request will still give 500 - elif r.status_code == 500: - if 'AttributeError' in r.text: - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) - else: - self.finish({"status_code": 400, "result": "Bad Request"}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + complete = True + fields = getFields('describeProcess') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + complete = False + + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + headers = {'Content-Type':'application/json'} + if 'proxy-ticket' in params.keys(): + ticket = params.get('proxy-ticket') + if not ticket == 'undefined': + headers['proxy-ticket'] = ticket + + params.pop('proxy-ticket') + if all(e == '' for e in list(params.values())): + complete = False + + logging.debug(list(params.values())) + logging.debug(complete) + + # return all algorithms if malformed request + if complete: + url = BASE_URL+'/mas/algorithm/{algo_id}:{version}'.format(**params) + else: + url = BASE_URL+'/mas/algorithm' + + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + + r = requests.get( + url, + headers=headers + ) + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check & Parse Response + # ================================== + + if r.status_code == 200: + algo_lst = [] + try: + if complete: + # parse out capability names & request info + rt = ET.fromstring(r.text) + attrib = [getParams(e) for e in rt[0][0]] + + result = '' + for (tag,txt) in attrib: + if tag == 'Input': + result += '{}\n'.format(tag) + for (tag1,txt1) in txt: + if tag1 != 'Identifier': + result += '\t{tag1}:\t{txt1}\n'.format(tag1=tag1,txt1=txt1) + if tag1 == 'Title:': + algo_lst.append(txt1) + result += '\n' + + elif tag == 'Title': + txt = txt.split(';') + for itm in txt: + result += '{}\n'.format(itm.strip()) + elif tag != 'Identifier': + result += '{tag}:\t{txt}\n'.format(tag=tag,txt=txt) + + # if no algorithm passed, list all algorithms + else: + resp = json.loads(r.text) + result = 'Algorithms:\n' + for e in resp['algorithms']: + result += '\t{}:{}\n'.format(e['type'],e['version']) + + # return set of algos, each mapped to list of versions + lst = result.replace('\n','').split('\t')[1:] + splt_lst = [e.split(':') for e in lst] + algo_lst = {} + + for a in splt_lst: + if not a[0] in algo_lst: + algo_lst[a[0]] = [a[1]] + else: + algo_lst[a[0]].append(a[1]) + + if result.strip() == '': + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result}) + return + + # print(result) + self.finish({"status_code": r.status_code, "result": result, "algo_set": algo_lst}) + except: + self.finish({"status_code": r.status_code, "result": r.text}) + + # malformed request will still give 500 + elif r.status_code == 500: + if 'AttributeError' in r.text: + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result}) + else: + self.finish({"status_code": r.status_code, "result": r.reason}) + else: + self.finish({"status_code": 400, "result": "Bad Request"}) class ExecuteInputsHandler(IPythonHandler): - def get(self): - # ================================== - # Part 1: Parse Required Arguments - # ================================== - complete = True - fields = getFields('executeInputs') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - params[f] = '' - complete = False - - if all(e == '' for e in list(params.values())): - complete = False - - # print(params) - params2 = copy.deepcopy(params) - # params2.pop('identifier') - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - headers = {'Content-Type':'application/json'} - - if 'proxy-ticket' in params.keys(): - headers['proxy-ticket'] = params.get('proxy-ticket') - - # return all algorithms if malformed request - if complete: - url = BASE_URL+'/mas/algorithm/{algo_id}:{version}'.format(**params2) - else: - url = BASE_URL+'/mas/algorithm' - - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - - - r = requests.get( - url, - headers=headers - ) - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check & Parse Response - # ================================== - - if r.status_code == 200: - try: - # print('200') - if complete: - # print('complete') - # parse out capability names & request info - rt = ET.fromstring(r.text) - attrib = [getParams(e) for e in rt[0][0]] # parse XML - inputs = [e[1] for e in attrib[2:-1]] - ins_req = [[e[1][1],e[2][1]] for e in inputs] # extract identifier & type for each input - ins_req = list(filter(lambda e: e[0] != 'timestamp', ins_req)) # filter out automatic timestamp req input - ins_req = list(filter(lambda e: e[0] != 'username', ins_req)) # filter out automatic username req input - - result = '' - for (identifier,typ) in ins_req: - result += '{identifier}:\t{typ}\n'.format(identifier=identifier,typ=typ) - # print(result) - - # if len(ins_req) > 0 and result.strip() == '': - # result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - # self.finish({"status_code": 400, "result": result}) - # return - - logging.debug(params) - logging.debug(ins_req) - self.finish({"status_code": r.status_code, "result": result, "ins": ins_req, "old":params}) - return - - else: - # print('failed 200') - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result, "ins": [], "old":params}) - return - - except: - self.finish({"status_code": 500, "result": r.text, "ins": [], "old":params}) - - # malformed request will still give 500 - elif r.status_code == 500: - if 'AttributeError' in r.text: - result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) - self.finish({"status_code": 400, "result": result, "ins": [], "old":params}) - else: - self.finish({"status_code": 500, "result": r.reason, "ins": [], "old":params}) - else: - self.finish({"status_code": 400, "result": "Bad Request", "ins": [], "old":params}) + def get(self): + # ================================== + # Part 1: Parse Required Arguments + # ================================== + complete = True + fields = getFields('executeInputs') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + params[f] = '' + complete = False + + if all(e == '' for e in list(params.values())): + complete = False + + # print(params) + params2 = copy.deepcopy(params) + # params2.pop('identifier') + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + headers = {'Content-Type':'application/json'} + + if 'proxy-ticket' in params.keys(): + headers['proxy-ticket'] = params.get('proxy-ticket') + + # return all algorithms if malformed request + if complete: + url = BASE_URL+'/mas/algorithm/{algo_id}:{version}'.format(**params2) + else: + url = BASE_URL+'/mas/algorithm' + + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + + + r = requests.get( + url, + headers=headers + ) + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check & Parse Response + # ================================== + + if r.status_code == 200: + try: + # print('200') + if complete: + # print('complete') + # parse out capability names & request info + rt = ET.fromstring(r.text) + attrib = [getParams(e) for e in rt[0][0]] # parse XML + inputs = [e[1] for e in attrib[2:-1]] + ins_req = [[e[1][1],e[2][1]] for e in inputs] # extract identifier & type for each input + ins_req = list(filter(lambda e: e[0] != 'timestamp', ins_req)) # filter out automatic timestamp req input + ins_req = list(filter(lambda e: e[0] != 'username', ins_req)) # filter out automatic username req input + + result = '' + for (identifier,typ) in ins_req: + result += '{identifier}:\t{typ}\n'.format(identifier=identifier,typ=typ) + # print(result) + + # if len(ins_req) > 0 and result.strip() == '': + # result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + # self.finish({"status_code": 400, "result": result}) + # return + + logging.debug(params) + logging.debug(ins_req) + self.finish({"status_code": r.status_code, "result": result, "ins": ins_req, "old":params}) + return + + else: + # print('failed 200') + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result, "ins": [], "old":params}) + return + + except: + self.finish({"status_code": 500, "result": r.text, "ins": [], "old":params}) + + # malformed request will still give 500 + elif r.status_code == 500: + if 'AttributeError' in r.text: + result = 'Bad Request\nThe provided parameters were\n\talgo_id:{}\n\tversion:{}\n'.format(params['algo_id'],params['version']) + self.finish({"status_code": 400, "result": result, "ins": [], "old":params}) + else: + self.finish({"status_code": 500, "result": r.reason, "ins": [], "old":params}) + else: + self.finish({"status_code": 400, "result": "Bad Request", "ins": [], "old":params}) class DefaultValuesHandler(IPythonHandler): - # inputs: code_path - # outputs: repository_url, algo_name, version, run_command, docker_url, environment_name - def get(self): - # ================================== - # Part 1: Get Notebook Information Processed in UI - # ================================== - fields = getFields('defaultValues') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - params[f] = '' - - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Extract Required Register Parameters - # ================================== - # full path provided by ts from PageConfig - proj_path = os.path.expanduser(params['code_path']) - proj_path = '/'.join(proj_path.split('/')[:-1]) - os.chdir(proj_path) - - # get git remote url (req) - repo_url = '' - try: - repo_url = subprocess.check_output("git remote get-url origin", shell=True).decode('utf-8').strip() - logger.debug('repo url is {}'.format(repo_url)) - #return error messsage if unable to get required values for registering - except: - self.finish({"status_code": 412, "reason":"Path provided was not a git repository. \n{}".format(proj_path)}) - return - - vals = {} - code_path = params['code_path'] - file_name = code_path.split('/')[-1] - algo_name = file_name.replace('/',':').replace(' ', '_').replace('"','').replace("'",'') - vals['algo_name'] = ('.').join(algo_name.split('.')[:-1]) - - # version is branch name - branch_name = subprocess.check_output("git branch | grep '*' | awk '{print $2}'",shell=True).decode('utf-8').strip() - # logging.debug('branch is {}'.format(branch_name)) - vals['version'] = branch_name - vals['repository_url'] = repo_url - # vals['environment'] = os.environ['ENVIRONMENT'] - vals['environment'] = "ubuntu" - - vals['docker_url'] = '' - try: - vals['docker_url'] = os.environ['DOCKERIMAGE_PATH'] - except: - self.finish({"status_code":400, "reason":"Environment base image could not be found. \nAre you registering from within the Che environment?"}) - return - - vals['run_cmd'] = params['code_path'] - - config_path = proj_path+"/algorithm_config.yaml" - prev_config = os.path.exists(config_path) - if not prev_config: - # read in config template and populate with default values - config = '' - config_template = WORKDIR+"/submit_jobs/register.yaml" - with open(config_template,'r') as infile: - config = infile.read() - config = config.format(**vals) - - # output config yaml - with open(config_path,'w') as outfile: - outfile.write(config) - - logger.debug('vals before reading') - logger.debug(vals) - - settings = {} - # repopulate vals with current config settings - with open(config_path,'r') as stream: - settings = yaml.load(stream) - - logger.debug(settings) - - # outputs: algo_name, version, environment, repository_url, dockerfile_path - self.finish({"status_code": 200, "result": "Got default values.", "default_values":settings, "config_path":config_path, "previous_config":prev_config}) + # inputs: code_path + # outputs: repository_url, algo_name, version, run_command, docker_url, environment_name + def get(self): + # ================================== + # Part 1: Get Notebook Information Processed in UI + # ================================== + fields = getFields('defaultValues') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + params[f] = '' + + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Extract Required Register Parameters + # ================================== + # full path provided by ts from PageConfig + proj_path = os.path.expanduser(params['code_path']) + proj_path = '/'.join(proj_path.split('/')[:-1]) + os.chdir(proj_path) + + # get git remote url (req) + repo_url = '' + try: + repo_url = subprocess.check_output("git remote get-url origin", shell=True).decode('utf-8').strip() + logger.debug('repo url is {}'.format(repo_url)) + #return error messsage if unable to get required values for registering + except: + self.finish({"status_code": 412, "reason":"Path provided was not a git repository. \n{}".format(proj_path)}) + return + + vals = {} + code_path = params['code_path'] + file_name = code_path.split('/')[-1] + algo_name = file_name.replace('/',':').replace(' ', '_').replace('"','').replace("'",'') + vals['algo_name'] = ('.').join(algo_name.split('.')[:-1]) + + # version is branch name + branch_name = subprocess.check_output("git branch | grep '*' | awk '{print $2}'",shell=True).decode('utf-8').strip() + # logging.debug('branch is {}'.format(branch_name)) + vals['version'] = branch_name + vals['repository_url'] = repo_url + # vals['environment'] = os.environ['ENVIRONMENT'] + vals['environment'] = "ubuntu" + + vals['docker_url'] = '' + try: + vals['docker_url'] = os.environ['DOCKERIMAGE_PATH'] + except: + self.finish({"status_code":400, "reason":"Environment base image could not be found. \nAre you registering from within the Che environment?"}) + return + + vals['run_cmd'] = params['code_path'] + + config_path = proj_path+"/algorithm_config.yaml" + prev_config = os.path.exists(config_path) + if not prev_config: + # read in config template and populate with default values + config = '' + config_template = WORKDIR+"/submit_jobs/register.yaml" + with open(config_template,'r') as infile: + config = infile.read() + config = config.format(**vals) + + # output config yaml + with open(config_path,'w') as outfile: + outfile.write(config) + + logger.debug('vals before reading') + logger.debug(vals) + + settings = {} + # repopulate vals with current config settings + with open(config_path,'r') as stream: + settings = yaml.load(stream) + + logger.debug(settings) + + # outputs: algo_name, version, environment, repository_url, dockerfile_path + self.finish({"status_code": 200, "result": "Got default values.", "default_values":settings, "config_path":config_path, "previous_config":prev_config}) class ListJobsHandler(IPythonHandler): - # inputs: username - # outputs: job list, containing job_id, status, algo_id, and inputs - def get(self): - fields = getFields('listJobs') - - params = {} - for f in fields: - try: - arg = self.get_argument(f.lower(), '').strip() - params[f] = arg - except: - arg = '' - - # print(params) - logging.debug('params are') - logging.debug(params) - - # ================================== - # Part 2: Build & Send Request - # ================================== - url = BASE_URL+'/dps/job/{username}/list'.format(**params) - headers = {'Content-Type':'application/xml'} - - if 'proxy-ticket' in params.keys(): - headers['proxy-ticket'] = params.get('proxy-ticket') - - logging.debug('request sent to {}'.format(url)) - logging.debug('headers:') - logging.debug(headers) - - try: - r = requests.get( - url, - headers=headers - ) - - # print(r.status_code) - # print(r.text) - - # ================================== - # Part 3: Check Response - # ================================== - # bad job id will still give 200 - if r.status_code == 200: - jobs = [] - details = {} - table = "" - try: - # parse out JobID from response - resp = json.loads(r.text) - jobs = resp['jobs'] # save joblist - jobs = [parse_job(job) for job in jobs] # parse inputs from string to dict - # logger.debug('parsing jobs list') - # logger.debug(jobs) - jobs = sorted(jobs, key=lambda j: j['timestamp'],reverse=True) # sort list of jobs by timestamp (most recent) - - table += '' - table += '' - table += '' - table += '' - table += '' - table += '' - table += '' - table += '' - table += '' - table += '' - - for job in jobs: - job['detailed'] = detailed_display(job) - table += ''.format(job['job_id'],job['status'],job['algo_id']) - details[job['job_id']] = detailed_display(job) - - table += '' - table += '
Job IdStatusAlgorithm
{}{}{}
' - - - result = '
' - result += '
' - result += table - result += '
' - result += '
' - logging.debug(table) - - # convert jobs list to dict, keyed by id - job_ids = [e['job_id'] for e in jobs] - jobs_dict = {job_ids[i]:jobs[i] for i in range(0,len(job_ids))} - logging.debug(jobs_dict) - - # print("success!") - self.finish({"status_code": r.status_code, "result": result, "table": table, "jobs": jobs_dict, "displays": details}) - except: - table = '
'.join(jobs) - self.finish({"status_code": r.status_code, "result": table, "table": table, "jobs": jobs, "displays": details, "resp": r.text}) - # if no job id provided - elif r.status_code in [404]: - # print('404?') - # if bad job id, show provided parameters - table = 'Exception: \nMessage: {}\nInvalid username provided.\n' - table += '\nThe provided parameters were:\n' - for f in fields: - table += '\t{}: {}\n'.format(f,params[f]) - table += '\n' - self.finish({"status_code": 404, "result": table}) - else: - self.finish({"status_code": r.status_code, "result": r.reason}) - except: - self.finish({"status_code": 400, "result": "Bad Request"}) + # inputs: username + # outputs: job list, containing job_id, status, algo_id, and inputs + def get(self): + fields = getFields('listJobs') + + params = {} + for f in fields: + try: + arg = self.get_argument(f.lower(), '').strip() + params[f] = arg + except: + arg = '' + + # print(params) + logging.debug('params are') + logging.debug(params) + + # ================================== + # Part 2: Build & Send Request + # ================================== + url = BASE_URL+'/dps/job/{username}/list'.format(**params) + headers = {'Content-Type':'application/xml'} + + if 'proxy-ticket' in params.keys(): + headers['proxy-ticket'] = params.get('proxy-ticket') + + logging.debug('request sent to {}'.format(url)) + logging.debug('headers:') + logging.debug(headers) + + try: + r = requests.get( + url, + headers=headers + ) + + # print(r.status_code) + # print(r.text) + + # ================================== + # Part 3: Check Response + # ================================== + # bad job id will still give 200 + if r.status_code == 200: + jobs = [] + details = {} + table = "" + try: + # parse out JobID from response + resp = json.loads(r.text) + jobs = resp['jobs'] # save joblist + + if len(jobs) == 0: + logging.debug('empty job list') + + else: + jobs = [parse_job(job) for job in jobs] # parse inputs from string to dict + # logger.debug('parsing jobs list') + # logger.debug(jobs) + jobs = sorted(jobs, key=lambda j: j['timestamp'],reverse=True) # sort list of jobs by timestamp (most recent) + + table += '' + table += '' + table += '' + table += '' + table += '' + table += '' + table += '' + table += '' + table += '' + table += '' + + if len(jobs) == 0: + table += 'No jobs found for user.' + + else: + for job in jobs: + job['detailed'] = detailed_display(job) + table += ''.format(job['job_id'],job['status'],job['algo_id']) + details[job['job_id']] = detailed_display(job) + + table += '' + table += '
Job IdStatusAlgorithm
{}{}{}
' + + + result = '
' + result += '
' + result += table + result += '
' + result += '
' + logging.debug(table) + + # convert jobs list to dict, keyed by id + job_ids = [e['job_id'] for e in jobs] + jobs_dict = {job_ids[i]:jobs[i] for i in range(0,len(job_ids))} + logging.debug(jobs_dict) + + # print("success!") + self.finish({"status_code": r.status_code, "results": result, "table": table, "jobs": jobs_dict, "displays": details}) + except: + table = '
'.join(jobs) + self.finish({"status_code": r.status_code, "results": table, "table": table, "jobs": jobs, "displays": details, "resp": r.text}) + # if no job id provided + elif r.status_code in [404]: + # print('404?') + # if bad job id, show provided parameters + table = 'Exception: \nMessage: {}\nInvalid username provided.\n' + table += '\nThe provided parameters were:\n' + for f in fields: + table += '\t{}: {}\n'.format(f,params[f]) + table += '\n' + self.finish({"status_code": 404, "results": table}) + else: + self.finish({"status_code": r.status_code, "results": r.reason}) + except: + self.finish({"status_code": 400, "results": "Bad Request"})