def post(self): print('experiment:58',request.data) post_parser = exp_parser.copy() post_parser.add_argument('app_id', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() utils.debug_print(args_data) app_id = args_data['app_id'] print app_id # Create and set exp_uid exp_uid = '%030x' % random.randrange(16**30) # Args from dict to json type args_json = json.dumps(args_data) print('experiment:69') # Execute initExp through the broker response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'initExp', json.dumps(args_data)) if not didSucceed: return attach_meta({}, meta_error['InitExpError'], backend_error=message), 400 return attach_meta({'exp_uid':exp_uid}, meta_success), 200
def post(self): post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('args', type=dict, required=False) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data['exp_uid'] # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Standardized participant_uid if 'participant_uid' in args_data['args'].keys(): args_data['args']['participant_uid'] = exp_uid+"_" + \ str(args_data['args']['participant_uid']) render_widget = args_data['args'].get('widget',False) # Execute getQuery response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"getQuery", json.dumps(args_data)) response_dict = json.loads(response_json) if not didSucceed: return attach_meta({},meta_error['QueryGenerationError'], backend_error=message) if render_widget: TEMPLATES_DIRECTORY = 'apps/{}/widgets'.format(resource_manager.get_app_id(exp_uid)) env = Environment(loader=FileSystemLoader(TEMPLATES_DIRECTORY)) template=env.get_template("getQuery_widget.html") return {'html':template.render(query=response_dict), 'args':response_dict}, 200, {'Access-Control-Allow-Origin':'*', 'Content-Type':'application/json'} return attach_meta(response_dict,meta_success), 200
def processAnswer(self,args): """ Generates a processAnswer widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/TupleBanditsPureExploration Input: ::\n (dict) args """ exp_uid = args["exp_uid"] app_id = resource_manager.get_app_id(exp_uid) try: target_reward = args['args']['target_reward'] except: return {'message':('Failed to specify all arguments ' 'or misformed arguments'), 'code':400, 'status':'FAIL', 'base_error':('[target_reward]. Missing required parameter' 'in the JSON body or the post body' 'or the query string')}, 400 # Set the index winner. args['args']['target_reward'] = target_reward # Args from dict to json type args_json = json.dumps(args['args']) # Execute processAnswer response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'processAnswer', args_json) return { 'html':'success'}
def getQuery(self, args): """ Generates a getQuery widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/PoolBasedTripletMDS Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ # Use the backend_api to query for a getQuery widget exp_uid = args["exp_uid"] app_id = args["app_id"] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = exp_uid + "_" + args['args'][ 'participant_uid'] args_json = json.dumps(args["args"]) response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, "getQuery", args_json) response_dict = json.loads(response_json) for target_index in response_dict["target_indices"]: target_index['target'] = targetmapper.get_target_data( exp_uid, target_index["index"]) # parse out left and right targets accordingly query = {} for target in response_dict["target_indices"]: query[target['label']] = target['target'] template = env.get_template("getQuery_widget.html") return {'html': template.render(query=query), 'args': response_dict}
def post(self): post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data["exp_uid"] args_data['args']['response_time'] = float(args_data['args']['response_time']) # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Parse out a target_winner. If the argument doesn't exist, return a meta dictionary error. args_json = json.dumps(args_data) # Execute processAnswer response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'processAnswer', args_json) if didSucceed: return attach_meta(eval(response_json), meta_success), 200 else: print "Failed to processAnswer", message return attach_meta({},custom_errors['ReportAnswerError'], backend_error=message)
def reportAnswer(self,args): """ Generates a reportAnswer widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/PoolBasedTripletMDS Input: ::\n (dict) args """ exp_uid = args["exp_uid"] app_id = resource_manager.get_app_id(exp_uid) try: target_winner = args['args']['target_winner'] except: return {'message':"Failed to specify all arguments or misformed arguments", 'code':400, 'status':'FAIL', 'base_error':'[target_winner]. Missing required parameter in the JSON body or the post body or the query string'}, 400 index_winner = int(targetmapper.get_index_given_targetID(exp_uid, target_winner)) # Set the index winner. args['args']["index_winner"] = index_winner # Args from dict to json type args_json = json.dumps(args["args"]) # Execute reportAnswer response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"reportAnswer",args_json) return { 'html':"success"}
def processAnswer(self,args): """ Generates a processAnswer widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/TupleBanditsPureExploration Input: ::\n (dict) args """ exp_uid = args["exp_uid"] app_id = resource_manager.get_app_id(exp_uid) try: target_winner = args['args']['target_winner'] except: return {'message':('Failed to specify all arguments ' 'or misformed arguments'), 'code':400, 'status':'FAIL', 'base_error':('[target_winner]. Missing required parameter' 'in the JSON body or the post body' 'or the query string')}, 400 target_reward = int(target_winner) # Set the index winner. args['args']['target_reward'] = target_reward # Args from dict to json type args_json = json.dumps(args['args']) # Execute processAnswer response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'processAnswer', args_json) return { 'html':'success'}
def getQuery(self, args): """ Generates a getQuery widget. Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ exp_uid = args['exp_uid'] app_id = args['app_id'] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = '{}_{}'.format(exp_uid, args['args']['participant_uid']) args_json = json.dumps(args['args']) response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'getQuery', args_json) response_dict = eval(response_json) print 'response_dict', response_dict index = response_dict['target_indices'][0]['index'] query = {} query['context'] = response_dict['context'] query['context_type'] = response_dict['context_type'] query['target'] = targetmapper.get_target_data(exp_uid, index) query['labels'] = response_dict['labels'] template = env.get_template('getQuery_widget.html') return {'html': template.render(query = query), 'args': response_dict }
def getStats(self,args): """ Generates a getStats widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/PoolBasedTripletMDS Returns a JSON object with the appropriate stats. Eventually modify to push the whole plot forward. Input: ::\n (dict) args """ exp_uid = args["exp_uid"] app_id = resource_manager.get_app_id(exp_uid) args_json = json.dumps(args["args"]) response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"getStats",args_json) response_dict = json.loads(response_json,parse_float=lambda o:round(float(o),4)) try: for d in response_dict["data"]: try: # If a datapoint (d) has a key, attach a target to that datapoint. if 'index' in d.keys(): try: d["target"] = targetmapper.get_target_data(exp_uid, d["index"]) except: print "failed to get target" except: pass except: # e.g. response_dict does not contain key "data" pass return { 'json':response_dict }
def getStats(self, args): """ Generates a getStats widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/TupleBanditsPureExploration Returns a JSON object with the appropriate stats. Eventually modify to push the whole plot forward. Input: ::\n (dict) args """ exp_uid = args["exp_uid"] app_id = resource_manager.get_app_id(exp_uid) args_json = json.dumps(args["args"]) response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, 'getStats', args_json) response_dict = json.loads(response_json, parse_float=lambda o: round(float(o), 4)) try: for d in response_dict['data']: try: # If a datapoint (d) has a key, attach a target to that datapoint. if 'index' in d.keys(): try: d['target'] = targetmapper.get_target_data( exp_uid, d["index"]) except: print 'failed to get target' except: pass except: # e.g. response_dict does not contain key "data" pass return {'json': response_dict}
def getQuery(self, args): """ Generates a getQuery widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/TupleBanditsPureExploration Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ exp_uid = args["exp_uid"] app_id = args["app_id"] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = exp_uid+"_"+args['args']['participant_uid'] args_json = json.dumps(args["args"]) response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"getQuery",args_json) response_dict = eval(response_json) for target_index in response_dict["target_indices"]: target_index['target'] = targetmapper.get_target_data(exp_uid, target_index["index"]) query = {} targets = [] for target in response_dict["target_indices"]: targets.append(target['target']) query['targets'] = targets # add context to query query['context_type'] = response_dict['context_type'] query['context'] = response_dict['context'] template = env.get_template("getQuery_widget.html") return {'html': template.render(query = query), 'args': response_dict }
def reportAnswer(self, args): """ Generates a reportAnswer widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/TupleBanditsPureExploration Input: ::\n (dict) args """ exp_uid = args["exp_uid"] app_id = resource_manager.get_app_id(exp_uid) try: target_winner = args["args"]["target_winner"] except: return ( { "message": "Failed to specify all arguments or misformed arguments", "code": 400, "status": "FAIL", "base_error": "[target_winner]. Missing required parameter in the JSON body or the post body or the query string", }, 400, ) index_winner = int(targetmapper.get_index_given_targetID(exp_uid, target_winner)) # Set the index winner. args["args"]["index_winner"] = index_winner # Args from dict to json type args_json = json.dumps(args["args"]) # Execute reportAnswer response_json, didSucceed, message = broker.applyAsync(app_id, exp_uid, "reportAnswer", args_json) return {"html": "success"}
def post(self): utils.debug_print('experiment:58',request.data) post_parser = exp_parser.copy() post_parser.add_argument('app_id', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() utils.debug_print(args_data) app_id = args_data['app_id'] utils.debug_print(app_id) # Create and set exp_uid exp_uid = '%030x' % random.randrange(16**30) # Args from dict to json type args_json = json.dumps(args_data) print('experiment:69') # Execute initExp through the broker response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'initExp', json.dumps(args_data)) if not didSucceed: return attach_meta({}, meta_error['InitExpError'], backend_error=message), 400 return attach_meta({'exp_uid':exp_uid}, meta_success), 200
def processAnswer(self,args): """ Generates a processAnswer widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/TupleBanditsPureExploration Input: ::\n (dict) args """ exp_uid = args["exp_uid"] app_id = resource_manager.get_app_id(exp_uid) try: target_winner = args['args']['target_winner'] except: return {'message':"Failed to specify all arguments or misformed arguments", 'code':400, 'status':'FAIL', 'base_error':'[target_winner]. Missing required parameter in the JSON body or the post body or the query string'}, 400 index_winner = int(targetmapper.get_index_given_targetID(exp_uid, target_winner)) # Set the index winner. args['args']["index_winner"] = index_winner # Args from dict to json type args_json = json.dumps(args["args"]) # Execute processAnswer response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"processAnswer",args_json) return { 'html':"success"}
def post(self, exp_uid, function_name): try: post_parser.add_argument('exp_uid', type=str, required=True, help="Experiment ID Required.") post_parser.add_argument('args', type=dict, required=False, help="Experiment args Required.") # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data["exp_uid"] # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) args_json = json.dumps(args_data["args"]) # This allows different apps to define custom functions, # and hit the API with those functions. # TODO: test this feature # implemented by Scott Sievert, 2016-1-26 response_json, didSucceed, message = broker.applyAsync(app_id, exp_uid, function_name, args_json) if not didSucceed: raise Exception(message) response_dict = json.loads(response_json) return attach_meta(response_dict, meta_success), 200 except Exception, error: return attach_meta({}, meta_error['Error'], backend_error=message)
def getQuery(self, args): """ Generates a getQuery widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/PoolBasedTripletMDS Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ # Use the backend_api to query for a getQuery widget exp_uid = args["exp_uid"] app_id = args["app_id"] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = exp_uid+"_"+args['args']['participant_uid'] args_json = json.dumps(args["args"]) response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"getQuery",args_json) response_dict = json.loads(response_json) for target_index in response_dict["target_indices"]: target_index['target'] = targetmapper.get_target_data(exp_uid, target_index["index"]) # parse out left and right targets accordingly query = {} for target in response_dict["target_indices"]: query[target['label']] = target['target'] template = env.get_template("getQuery_widget.html") return {'html': template.render(query = query), 'args': response_dict }
def post(self): """ .. http:post:: /experiment/<exp_uid>/predict Get stats related to an experiment. For a list of potential plot types and parameters see: . **Example request**: .. sourcecode:: http POST /experiment/<exp_uid> HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, app_id: app_id, args: { } } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { } :statuscode 200: prediction successfully accessed :statuscode 400: prediction retrieval error """ post_parser.add_argument('exp_uid', type=str, required=True,help="Experiment ID Required.") post_parser.add_argument('exp_key', type=str, required=True,help="Experiment ID Required.") post_parser.add_argument('args', type=dict, required=True,help="Experiment Args Required.") # Validate args with post_parser args_data = post_parser.parse_args() # Pull exp_uid from parsed args_data exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute getQuery response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"predict",args_json) if didSucceed: return meta_attach(response_json,meta_success), 200 else: return meta_attach({},custom_errors['PredictRetrievalError'], backend_error=message),400
def getQuery(self, args): """ Generates a getQuery widget. Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ exp_uid = args['exp_uid'] app_id = args['app_id'] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = '{}_{}'.format( exp_uid, args['args']['participant_uid']) args_json = json.dumps(args['args']) response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, 'getQuery', args_json) response_dict = eval(response_json) print 'response_dict', response_dict index = response_dict['target_indices'][0]['index'] query = {} query['context'] = response_dict['context'] query['context_type'] = response_dict['context_type'] query['target'] = targetmapper.get_target_data(exp_uid, index) template = env.get_template('getQuery_widget.html') rating_options = [] rating_options.append({ 'target_id': 1, 'primary_description': "No", 'primary_type': 'text', 'alt_description': 1, 'alt_type': 'text', 'target_reward': -1 }) rating_options.append({ 'target_id': 2, 'primary_description': "Yes", 'primary_type': 'text', 'alt_description': 2, 'alt_type': 'text', 'target_reward': 1 }) return { 'html': template.render(query=query, rating_options=rating_options), 'args': response_dict }
def getQuery(self, args): """ Generates a getQuery widget. Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ exp_uid = args['exp_uid'] app_id = args['app_id'] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = '{}_{}'.format(exp_uid, args['args']['participant_uid']) args_json = json.dumps(args['args']) response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'getQuery', args_json) response_dict = eval(response_json) print 'response_dict', response_dict index = response_dict['target_indices'][0]['index'] query = {} query['context'] = response_dict['context'] query['context_type'] = response_dict['context_type'] query['target'] = targetmapper.get_target_data(exp_uid, index) template = env.get_template('getQuery_widget.html') rating_options = [] rating_options.append({'target_id':1, 'primary_description':"No", 'primary_type':'text', 'alt_description':1, 'alt_type':'text', 'target_reward':-1}) rating_options.append({'target_id':2, 'primary_description':"Yes", 'primary_type':'text', 'alt_description':2, 'alt_type':'text', 'target_reward':1}) return {'html': template.render(query = query, rating_options = rating_options), 'args': response_dict }
def getQuery(self, args): """ Generates a getQuery widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/DuelingBanditsPureExploration Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ exp_uid = args["exp_uid"] app_id = args["app_id"] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = '{}_{}'.format(exp_uid, args['args']['participant_uid']) args_json = json.dumps(args['args']) response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'getQuery' ,args_json) response_dict = json.loads(response_json) for target_index in response_dict['target_indices']: target_index['target'] = targetmapper.get_target_data(exp_uid, target_index['index']) # parse out left and right targets accordingly query = {} for target in response_dict['target_indices']: query[target['label']] = target['target'] # add context to query query['context_type'] = response_dict['context_type'] query['context'] = response_dict['context'] template = env.get_template('getQuery_widget.html') return {'html': template.render(query = query), 'args': response_dict }
def post(self): post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('args', type=dict, required=False) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data['exp_uid'] # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Standardized participant_uid if 'participant_uid' in args_data['args'].keys(): args_data['args']['participant_uid'] = exp_uid + "_" + args_data[ 'args']['participant_uid'] render_widget = args_data['args'].get('widget', False) # Execute getQuery response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, "getQuery", json.dumps(args_data)) response_dict = json.loads(response_json) if not didSucceed: return attach_meta({}, meta_error['QueryGenerationError'], backend_error=message) if render_widget: TEMPLATES_DIRECTORY = 'apps/{}/widgets'.format( resource_manager.get_app_id(exp_uid)) env = Environment(loader=FileSystemLoader(TEMPLATES_DIRECTORY)) template = env.get_template("getQuery_widget.html") return { 'html': template.render(query=response_dict), 'args': response_dict }, 200, { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' } return attach_meta(response_dict, meta_success), 200
def getQuery(self, args): """ Generates a getQuery widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/DuelingBanditsPureExploration Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ exp_uid = args["exp_uid"] app_id = args["app_id"] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = '{}_{}'.format( exp_uid, args['args']['participant_uid']) args_json = json.dumps(args['args']) response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, 'getQuery', args_json) response_dict = json.loads(response_json) for target_index in response_dict['target_indices']: target_index['target'] = targetmapper.get_target_data( exp_uid, target_index['index']) # parse out left and right targets accordingly query = {} for target in response_dict['target_indices']: query[target['label']] = target['target'] # add context to query query['context_type'] = response_dict['context_type'] query['context'] = response_dict['context'] template = env.get_template('getQuery_widget.html') return {'html': template.render(query=query), 'args': response_dict}
def getQuery(self, args): """ Generates a getQuery widget. Uses the args format as specified in::\n /next_backend/next/learningLibs/apps/TupleBanditsPureExploration Input: ::\n (dict) args Output: ::\n (str) getQuery widget. """ exp_uid = args["exp_uid"] app_id = args["app_id"] if 'participant_uid' in args['args'].keys(): args['args']['participant_uid'] = exp_uid + "_" + args['args'][ 'participant_uid'] args_json = json.dumps(args["args"]) response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, "getQuery", args_json) response_dict = eval(response_json) for target_index in response_dict["target_indices"]: target_index['target'] = targetmapper.get_target_data( exp_uid, target_index["index"]) query = {} targets = [] for target in response_dict["target_indices"]: targets.append(target['target']) query['targets'] = targets # add context to query query['context_type'] = response_dict['context_type'] query['context'] = response_dict['context'] template = env.get_template("getQuery_widget.html") return {'html': template.render(query=query), 'args': response_dict}
def post(self): """ .. http:post:: /experiment Initialize a new experiment. The args input depend on the application type. **Example request**: .. sourcecode:: http POST /experiment HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, app_id: app_id args : { params: { Application specific params. }, alg_list: [ { "alg_label": "LilUCB", "proportion": 0.3333333333333333, "alg_id": "LilUCB", "test_alg_label": "LilUCB", "params": {} } ], participant_to_algorithm_management: 'one_to_one', algorithm_management_mode: 'pure_exploration' } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json [ exp_uid: exp_uid, app_id: app_id, status: { code: 200, status: OK, } ] :<json args: Dictionary of options that are application dependent. Must include, params, alg_list, participant_to_algorithm_management, algorithm_management_mode. :<json params: Application specific params such as number of arms in multi armed bandit experiments. :<json alg_list: A list of algorithm specifications. :<json participant_to_algorithm_management: Type of participant management. :<json algorithm_management_mode: Type of algorithm management mode. :statuscode 200: experiment successfully created :statuscode 400: experiment was not successfully created """ post_parser = exp_parser.copy() post_parser.add_argument('app_id', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() app_id = args_data['app_id'] # Create and set exp_uid exp_uid = '%030x' % random.randrange(16**30) # Args from dict to json type args_json = json.dumps(args_data['args']) # Execute initExp through the broker response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'initExp', args_json) if not didSucceed: return attach_meta({}, meta_error['InitExpError'], backend_error=message), 400 # Add experiment to experiments bucket didSucceed, message = resource_manager.set_experiment(exp_uid) if not didSucceed: raise DatabaseException("Failed to create experiment in database: %s"%(message)) # Create an experiment key and a perm key exp_key = keychain.create_exp_key(exp_uid) perm_key = keychain.create_perm_key(exp_uid, exp_key) return attach_meta({'exp_uid':exp_uid, 'exp_key':exp_key, 'perm_key':perm_key}, meta_success), 200
def post(self): """ .. http:post:: /experiment/stats Get stats related to an experiment. For a list of potential plot types and parameters see: LINK. **Example request**: .. sourcecode:: http POST /experiment/<exp_uid> HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, args: { stat_id: "compute_duration_detailed_stacked_area_plot", params: { task: "getQuery", alg_label: "lilUCB" } } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { plot_type: 'multi_line_plot' x_label : 'Number of answered triplets' x_min : 1 x_max : maximum number of reported answers for any algorithm y_label : 'Error on hold-out set' y_min : 0. y_max : maximum duration value achieved by any algorithm data :[ t : list of timestamp strings x : integers ranging from 1 to maximum number of elements in y (or t) y : list of durations legend_label : alg_label ] } :statuscode 200: stats successfully accessed :statuscode 400: stats retrieval error """ post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('exp_key', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args_data exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute getStats response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"getStats",args_json) response_dict = json.loads(response_json,parse_float=lambda o:round(float(o),4)) try: for d in response_dict["data"]: try: # If a datapoint (d) has a key, attach a target to that datapoint. if 'index' in d.keys(): try: d["target"] = targetmapper.get_target_data(exp_uid, d["index"]) except: print "failed to get target" except: pass except: # e.g. response_dict does not contain key "data" pass if didSucceed and "data" in response_dict.keys(): return attach_meta(response_dict,meta_success), 201 elif didSucceed and not "data" in response_dict.keys(): return attach_meta({'data':[]},meta_error['StatsEmptyError']), 200 else: return attach_meta({},meta_error['StatsRetrievalError'], backend_error=message), 400
def post(self): """ .. http:post:: /experiment/stats Get stats related to an experiment. For a list of potential plot types and parameters see: LINK. **Example request**: .. sourcecode:: http POST /experiment/<exp_uid> HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, args: { stat_id: "compute_duration_detailed_stacked_area_plot", params: { task: "getQuery", alg_label: "lilUCB" } } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { plot_type: 'multi_line_plot' x_label : 'Number of answered triplets' x_min : 1 x_max : maximum number of reported answers for any algorithm y_label : 'Error on hold-out set' y_min : 0. y_max : maximum duration value achieved by any algorithm data :[ t : list of timestamp strings x : integers ranging from 1 to maximum number of elements in y (or t) y : list of durations legend_label : alg_label ] } :statuscode 200: stats successfully accessed :statuscode 400: stats retrieval error """ post_parser.add_argument("exp_uid", type=str, required=True) post_parser.add_argument("exp_key", type=str, required=True) post_parser.add_argument("args", type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args_data exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute getStats response_json, didSucceed, message = broker.applyAsync(app_id, exp_uid, "getStats", args_json) response_dict = json.loads(response_json, parse_float=lambda o: round(float(o), 4)) try: index_test = response_dict["data"][0]["index"] targetmapping = targetmapper.get_target_mapping(exp_uid) for d in response_dict["data"]: try: index = d["index"] if len(targetmapping) == 0: d["target"] = { "target_id": index, "primary_description": index, "primary_type": "text", "alt_description": index, "alt_type": "text", } else: d["target"] = targetmapping[index] except: pass except: pass if didSucceed and "data" in response_dict.keys(): t = time.time() json_response = json.dumps(attach_meta(response_dict, meta_success)) gzip_buffer = StringIO() gzip_file = gzip.GzipFile(mode="wb", fileobj=gzip_buffer) gzip_file.write(json_response) gzip_file.close() resp = make_response(gzip_buffer.getvalue()) print "time to zip", time.time() - t resp.headers["Content-Encoding"] = "gzip" resp.headers["Content-length"] = len(json.dumps(attach_meta(response_dict, meta_success))) resp.headers["Content-Type"] = "application/json" return resp # return gzip_buffer.getvalue(), 200, {'Content-Encoding': 'gzip', # 'Vary':'Accept-Encoding', # 'Content-Type': 'application/json'} elif didSucceed and not "data" in response_dict.keys(): return attach_meta({"data": []}, meta_error["StatsEmptyError"]), 200 else: return attach_meta({}, meta_error["StatsRetrievalError"], backend_error=message), 400
def post(self): """ .. http:post:: /experiment Initialize a new experiment. The args input depend on the application type. **Example request**: .. sourcecode:: http POST /experiment HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, app_id: app_id args : { params: { Application specific params. }, alg_list: [ { "alg_label": "LilUCB", "proportion": 0.3333333333333333, "alg_id": "LilUCB", "test_alg_label": "LilUCB", "params": {} } ], participant_to_algorithm_management: 'one_to_one', algorithm_management_mode: 'pure_exploration' } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json [ exp_uid: exp_uid, app_id: app_id, status: { code: 200, status: OK, } ] :<json args: Dictionary of options that are application dependent. Must include, params, alg_list, participant_to_algorithm_management, algorithm_management_mode. :<json params: Application specific params such as number of arms in multi armed bandit experiments. :<json alg_list: A list of algorithm specifications. :<json participant_to_algorithm_management: Type of participant management. :<json algorithm_management_mode: Type of algorithm management mode. :statuscode 200: experiment successfully created :statuscode 400: experiment was not successfully created """ post_parser = exp_parser.copy() post_parser.add_argument('app_id', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() app_id = args_data["app_id"] site_id = args_data.get('site_id', None) site_key = args_data.get('site_key', None) if not keychain.verify_site_key(site_id, site_key): return api_util.attach_meta({}, api_util.verification_error), 401 # Create and set exp_uid exp_uid = '%030x' % random.randrange(16**30) # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute initExp through the broker response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, "initExp", args_json) if not didSucceed: return attach_meta({}, meta_error['InitExpError'], backend_error=message), 400 # Add experiment to experiments bucket didSucceed, message = resource_manager.set_experiment(site_id, exp_uid) if not didSucceed: raise DatabaseException( "Failed to create experiment in database: %s" % (message)) # Create an experiment key and a perm key exp_key = keychain.create_exp_key(site_id, site_key, exp_uid) perm_key = keychain.create_perm_key(exp_uid, exp_key) return attach_meta( { 'exp_uid': exp_uid, 'exp_key': exp_key, 'perm_key': perm_key }, meta_success), 200
def post(self): """.. http:post:: /experiment/getQuery Get an experiment query using post. Useful for situations in which a feature vector has to be uploaded. **Example request**: .. sourcecode:: http POST /experiment/getQuery HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, args : { features: } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { exp_uid: exp_uid, status: { code: 200, status: OK, }, target_indices: { index: 1 label: "center" flag: 5 }, alg_uid: , timestamp_query_generated: , participant_uid: } :<json features: Optional feature vector. :>json target_indices: Application specific target indices. :>json alg_uid: :>json timestamp_query_generated: :>json participant_uid: :statuscode 200: Query successfully returned :statuscode 400: Query failed to be generated """ post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('exp_key', type=str, required=True) post_parser.add_argument('args', type=dict, required=False) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Standardized participant_uid if 'participant_uid' in args_data['args'].keys(): args_data['args']['participant_uid'] = exp_uid + "_" + args_data[ 'args']['participant_uid'] # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute getQuery response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, "getQuery", args_json) if not didSucceed: return attach_meta({}, meta_error['QueryGenerationError'], backend_error=message) response_dict = eval(response_json) for target_index in response_dict["target_indices"]: target_index['target'] = targetmapper.get_target_data( exp_uid, target_index["index"]) return attach_meta(response_dict, meta_success), 200
def post(self): # This doc needs to be updated """.. http:post:: /experiment/answer Post the participants answer to a given query. **Example request**: .. sourcecode:: http POST /experiment/answer HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, args : { index_winner: 'left', query_uid: } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { status: { code: 200, status: OK } } :<json features: Optional feature vector. :>json target_indices: Application specific target indices. :>json alg_uid: :>json timestamp_query_generated: :>json participant_uid: :statuscode 200: Answer successfully reported :statuscode 400: Answer failed to be reported """ post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('exp_key', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Parse out a target_winner. If the argument doesn't exist, return a meta dictionary error. try: target_winner = args_data['args']['target_winner'] index_winner = int( targetmapper.get_index_given_targetID(exp_uid, target_winner)) # Set the index winner. args_data['args']["index_winner"] = index_winner except: error_string = ( '[target_winner]. Missing required parameter in the' ' JSON body or the post body or the query string') # return {'message':('Failed to specify all arguments' # 'or misformed arguments'), # 'code':400, # 'status':'FAIL', # 'base_error':error_string}, 400 # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute processAnswer response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, 'processAnswer', args_json) if didSucceed: return attach_meta(eval(response_json), meta_success), 200 else: return attach_meta({}, custom_errors['ReportAnswerError'], backend_error=message)
def post(self): """ .. http:post:: /experiment/stats Get stats related to an experiment. For a list of potential plot types and parameters see: LINK. **Example request**: .. sourcecode:: http POST /experiment/<exp_uid> HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, args: { stat_id: "compute_duration_detailed_stacked_area_plot", params: { task: "getQuery", alg_label: "lilUCB" } } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { plot_type: 'multi_line_plot' x_label : 'Number of answered triplets' x_min : 1 x_max : maximum number of reported answers for any algorithm y_label : 'Error on hold-out set' y_min : 0. y_max : maximum duration value achieved by any algorithm data :[ t : list of timestamp strings x : integers ranging from 1 to maximum number of elements in y (or t) y : list of durations legend_label : alg_label ] } :statuscode 200: stats successfully accessed :statuscode 400: stats retrieval error """ post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('exp_key', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args_data exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute getStats response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, "getStats", args_json) response_dict = json.loads(response_json, parse_float=lambda o: round(float(o), 4)) try: for d in response_dict["data"]: try: # If a datapoint (d) has a key, attach a target to that datapoint. if 'index' in d.keys(): try: d["target"] = targetmapper.get_target_data( exp_uid, d["index"]) except: print "failed to get target" except: pass except: # e.g. response_dict does not contain key "data" pass if didSucceed and "data" in response_dict.keys(): return attach_meta(response_dict, meta_success), 201 elif didSucceed and not "data" in response_dict.keys(): return attach_meta({'data': []}, meta_error['StatsEmptyError']), 200 else: return attach_meta({}, meta_error['StatsRetrievalError'], backend_error=message), 400
def post(self): # This doc needs to be updated """.. http:post:: /experiment/answer Post the participants answer to a given query. **Example request**: .. sourcecode:: http POST /experiment/answer HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, args : { index_winner: 'left', query_uid: } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { status: { code: 200, status: OK } } :<json features: Optional feature vector. :>json target_indices: Application specific target indices. :>json alg_uid: :>json timestamp_query_generated: :>json participant_uid: :statuscode 200: Answer successfully reported :statuscode 400: Answer failed to be reported """ post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('exp_key', type=str, required=True) post_parser.add_argument('args', type=dict, required=True) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Parse out a target_winner. If the argument doesn't exist, return a meta dictionary error. try: target_winner = args_data['args']['target_winner'] index_winner = int(targetmapper.get_index_given_targetID(exp_uid, target_winner)) # Set the index winner. args_data['args']["index_winner"] = index_winner except: error_string = ('[target_winner]. Missing required parameter in the' ' JSON body or the post body or the query string') # return {'message':('Failed to specify all arguments' # 'or misformed arguments'), # 'code':400, # 'status':'FAIL', # 'base_error':error_string}, 400 # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute processAnswer response_json,didSucceed,message = broker.applyAsync(app_id, exp_uid, 'processAnswer', args_json) if didSucceed: return attach_meta(eval(response_json), meta_success), 200 else: return attach_meta({},custom_errors['ReportAnswerError'], backend_error=message)
def post(self): """ .. http:post:: /experiment/<exp_uid>/predict Get stats related to an experiment. For a list of potential plot types and parameters see: . **Example request**: .. sourcecode:: http POST /experiment/<exp_uid> HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, app_id: app_id, args: { } } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { } :statuscode 200: prediction successfully accessed :statuscode 400: prediction retrieval error """ post_parser.add_argument('exp_uid', type=str, required=True, help="Experiment ID Required.") post_parser.add_argument('exp_key', type=str, required=True, help="Experiment ID Required.") post_parser.add_argument('args', type=dict, required=True, help="Experiment Args Required.") # Validate args with post_parser args_data = post_parser.parse_args() # Pull exp_uid from parsed args_data exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_dictionary), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute getQuery response_json, didSucceed, message = broker.applyAsync( app_id, exp_uid, "predict", args_json) if didSucceed: return meta_attach(response_json, meta_success), 200 else: return meta_attach({}, custom_errors['PredictRetrievalError'], backend_error=message), 400
def post(self): """.. http:post:: /experiment/getQuery Get an experiment query using post. Useful for situations in which a feature vector has to be uploaded. **Example request**: .. sourcecode:: http POST /experiment/getQuery HTTP/1.1 Host: next_backend.next.discovery.wisc.edu { exp_uid: exp_uid, args : { features: } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: application/json { exp_uid: exp_uid, status: { code: 200, status: OK, }, target_indices: { index: 1 label: "center" flag: 5 }, alg_uid: , timestamp_query_generated: , participant_uid: } :<json features: Optional feature vector. :>json target_indices: Application specific target indices. :>json alg_uid: :>json timestamp_query_generated: :>json participant_uid: :statuscode 200: Query successfully returned :statuscode 400: Query failed to be generated """ post_parser.add_argument('exp_uid', type=str, required=True) post_parser.add_argument('exp_key', type=str, required=True) post_parser.add_argument('args', type=dict, required=False) # Validate args with post_parser args_data = post_parser.parse_args() # Pull app_id and exp_uid from parsed args exp_uid = args_data["exp_uid"] exp_key = args_data["exp_key"] if not keychain.verify_exp_key(exp_uid, exp_key): return api_util.attach_meta({}, api_util.verification_error), 401 # Fetch app_id data from resource manager app_id = resource_manager.get_app_id(exp_uid) # Standardized participant_uid if 'participant_uid' in args_data['args'].keys(): args_data['args']['participant_uid'] = exp_uid+"_"+args_data['args']['participant_uid'] # Args from dict to json type args_json = json.dumps(args_data["args"]) # Execute getQuery response_json,didSucceed,message = broker.applyAsync(app_id,exp_uid,"getQuery",args_json) if not didSucceed: return attach_meta({},meta_error['QueryGenerationError'], backend_error=message) response_dict = json.loads(response_json) for target_index in response_dict["target_indices"]: target_index['target'] = targetmapper.get_target_data(exp_uid, target_index["index"]) return attach_meta(response_dict,meta_success), 200