def init_alg(self, exp_uid, algorithm, alg_args): butler = Butler(self.app_id, exp_uid, self.myApp.TargetManager, self.butler.db, self.butler.ell, algorithm['alg_label'], algorithm['alg_id']) alg = utils.get_app_alg(self.app_id, algorithm['alg_id']) if 'args' in self.algs_reference_dict['initExp']: alg_args = verifier.verify( alg_args, self.algs_reference_dict['initExp']['args']) # I got rid of a timeit function here; it wasn't handling the # argument unpacking correctly? --Scott, 2016-3-7 # TODO: put dt back in and change log_entry to relfect that alg_response = alg.initExp(butler, **alg_args) alg_response = verifier.verify( {'rets': alg_response}, {'rets': self.algs_reference_dict['initExp']['rets']}) log_entry = { 'exp_uid': exp_uid, 'alg_label': algorithm['alg_label'], 'task': 'initExp', 'duration': -1, 'timestamp': utils.datetimeNow() } self.butler.log('ALG-DURATION', log_entry)
def run_alg(self, butler, alg_label, alg, func_name, alg_args): if 'args' in self.algs_reference_dict[func_name]: alg_args = verifier.verify(alg_args, self.algs_reference_dict[func_name]['args']) alg_response, dt = utils.timeit(getattr(alg, func_name))(butler, **alg_args) alg_response = verifier.verify({'rets':alg_response}, {'rets':self.algs_reference_dict[func_name]['rets']}) log_entry_durations = {'exp_uid':self.exp_uid, 'alg_label':alg_label, 'task':func_name, 'duration':dt} log_entry_durations.update(butler.algorithms.getDurations()) self.log_entry_durations = log_entry_durations return alg_response['rets']
def run_alg(self, butler, alg_label, alg, func_name, alg_args): if 'args' in self.algs_reference_dict[func_name]: alg_args = verifier.verify(alg_args, self.algs_reference_dict[func_name]['args']) alg_response, dt = utils.timeit(getattr(alg, func_name))(butler, **alg_args) alg_response = verifier.verify({'rets':alg_response}, {'rets':self.algs_reference_dict[func_name]['rets']}) log_entry_durations = {'exp_uid':self.exp_uid, 'alg_label':alg_label, 'task':func_name, 'duration':dt} log_entry_durations.update(butler.algorithms.getDurations()) self.log_entry_durations = log_entry_durations return alg_response['rets']
def init_alg(self, exp_uid, algorithm, alg_args): butler = Butler(self.app_id, exp_uid, self.myApp.TargetManager, self.butler.db, self.butler.ell, algorithm['alg_label'], algorithm['alg_id']) alg = utils.get_app_alg(self.app_id, algorithm['alg_id']) if 'args' in self.algs_reference_dict['initExp']: alg_args = verifier.verify(alg_args, self.algs_reference_dict['initExp']['args']) # I got rid of a timeit function here; it wasn't handling the # argument unpacking correctly? --Scott, 2016-3-7 # TODO: put dt back in and change log_entry to relfect that alg_response = alg.initExp(butler, **alg_args) alg_response = verifier.verify({'rets':alg_response}, {'rets':self.algs_reference_dict['initExp']['rets']}) log_entry = {'exp_uid':exp_uid, 'alg_label':algorithm['alg_label'], 'task':'initExp', 'duration':-1, 'timestamp':utils.datetimeNow()} self.butler.log('ALG-DURATION', log_entry)
def getModel(self, exp_uid, args_json): try: args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['getModel']['args']) alg_label = args_dict['args']['alg_label'] args = self.butler.experiment.get(key='args') for algorithm in args['alg_list']: if alg_label == algorithm['alg_label']: alg_id = algorithm['alg_id'] myapp_response = self.call_app_fn(alg_label, alg_id, 'getModel', args_dict) myapp_response['exp_uid'] = exp_uid myapp_response['alg_label'] = alg_label # Log the response of the getModel in ALG-EVALUATION if args_dict['args']['logging']: alg_log_entry = {'exp_uid': exp_uid, 'alg_label':alg_label, 'task': 'getModel', 'timestamp': str(utils.datetimeNow())} alg_log_entry.update(myapp_response) self.butler.log('ALG-EVALUATION', alg_log_entry) return json.dumps({'args': myapp_response, 'meta': {'log_entry_durations':self.log_entry_durations, 'timestamp': str(utils.datetimeNow())}}), True, '' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("getModel Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'getModel','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) return Exception(error)
def processAnswer(self, exp_uid, args_json): try: args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['processAnswer']['args']) # Update timing info in query query = self.butler.queries.get(uid=args_dict['args']['query_uid']) timestamp_answer_received = args_dict['args'].get('timestamp_answer_received', None) delta_datetime = utils.str2datetime(timestamp_answer_received) - \ utils.str2datetime(query['timestamp_query_generated']) round_trip_time = delta_datetime.total_seconds() response_time = float(args_dict['args'].get('response_time',0.)) query_update = self.call_app_fn(query['alg_label'], query['alg_id'], 'processAnswer', args_dict) query_update.update({'response_time':response_time, 'network_delay':round_trip_time - response_time, 'timestamp_answer_received': timestamp_answer_received }) self.butler.queries.set_many(uid=args_dict['args']['query_uid'],key_value_dict=query_update) return json.dumps({'args': {}, 'meta': {'log_entry_durations':self.log_entry_durations}}), True, '' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("processAnswer Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'processAnswer','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) raise Exception(error)
def getModel(self, exp_uid, args_json): try: args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['getModel']['args']) alg_label = args_dict['args']['alg_label'] args = self.butler.experiment.get(key='args') for algorithm in args['alg_list']: if alg_label == algorithm['alg_label']: alg_id = algorithm['alg_id'] myapp_response = self.call_app_fn(alg_label, alg_id, 'getModel', args_dict) myapp_response['exp_uid'] = exp_uid myapp_response['alg_label'] = alg_label # Log the response of the getModel in ALG-EVALUATION if args_dict['args']['logging']: alg_log_entry = {'exp_uid': exp_uid, 'alg_label':alg_label, 'task': 'getModel', 'timestamp': str(utils.datetimeNow())} alg_log_entry.update(myapp_response) self.butler.log('ALG-EVALUATION', alg_log_entry) return json.dumps({'args': myapp_response, 'meta': {'log_entry_durations':self.log_entry_durations, 'timestamp': str(utils.datetimeNow())}}), True, '' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("getModel Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'getModel','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) return Exception(error)
def processAnswer(self, exp_uid, args_json): try: args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['processAnswer']['args']) # Update timing info in query query = self.butler.queries.get(uid=args_dict['args']['query_uid']) timestamp_answer_received = args_dict['args'].get('timestamp_answer_received', None) delta_datetime = utils.str2datetime(timestamp_answer_received) - \ utils.str2datetime(query['timestamp_query_generated']) round_trip_time = delta_datetime.total_seconds() response_time = float(args_dict['args'].get('response_time',0.)) query_update = self.call_app_fn(query['alg_label'], query['alg_id'], 'processAnswer', args_dict) query_update.update({'response_time':response_time, 'network_delay':round_trip_time - response_time, 'timestamp_answer_received': timestamp_answer_received }) self.butler.queries.set_many(uid=args_dict['args']['query_uid'],key_value_dict=query_update) return json.dumps({'args': {}, 'meta': {'log_entry_durations':self.log_entry_durations}}), True, '' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("processAnswer Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'processAnswer','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) raise Exception(error)
def apply_dashboard(app_id, exp_uid, args_in_json, enqueue_timestamp): enqueue_datetime = next.utils.str2datetime(enqueue_timestamp) dequeue_datetime = next.utils.datetimeNow() delta_datetime = dequeue_datetime - enqueue_datetime time_enqueued = delta_datetime.seconds + delta_datetime.microseconds/1000000. dir, _ = os.path.split(__file__) reference_dict,errs = verifier.load_doc('{}/myApp.yaml'.format(app_id, app_id),"apps/") if len(errs) > 0: raise Exception("App YAML format errors: \n{}".format(str(errs))) args_dict = verifier.verify(args_in_json, reference_dict['getStats']['args']) stat_id = args_dict['args'].get('stat_id','none') stat_args = args_dict['args'] hash_object = hashlib.md5(stat_id+'_'+json.dumps(stat_args['params'])) stat_uid = hash_object.hexdigest() stat_uid += '_' + exp_uid app = App_Wrapper(app_id, exp_uid, db, ell) cached_doc = app.butler.dashboard.get(uid=stat_uid) cached_response = None if (int(stat_args.get('force_recompute',0))==0) and (cached_doc is not None): delta_datetime = (next.utils.datetimeNow() - next.utils.str2datetime(cached_doc['timestamp'])) if delta_datetime.seconds < next.constants.DASHBOARD_STALENESS_IN_SECONDS: cached_response = json.loads(cached_doc['data_dict']) if 'meta' not in cached_response: cached_response['meta']={} cached_response['meta']['cached'] = 1 if delta_datetime.seconds/60<1: cached_response['meta']['last_dashboard_update'] = '<1 minute ago' else: cached_response['meta']['last_dashboard_update'] = str(delta_datetime.seconds/60)+' minutes ago' if cached_response==None: dashboard_string = 'apps.' + app_id + '.dashboard.Dashboard' dashboard_module = __import__(dashboard_string, fromlist=['']) dashboard = getattr(dashboard_module, 'MyAppDashboard') dashboard = dashboard(db, ell) stats_method = getattr(dashboard, stat_id) response,dt = next.utils.timeit(stats_method)(app,app.butler,**args_dict['args']['params']) save_dict = {'exp_uid':app.exp_uid, 'stat_uid':stat_uid, 'timestamp':next.utils.datetime2str(next.utils.datetimeNow()), 'data_dict':json.dumps(response)} app.butler.dashboard.set_many(uid=stat_uid,key_value_dict=save_dict) # update the admin timing with the timing of a getModel if hasattr(app, 'log_entry_durations'): app.log_entry_durations['app_duration'] = dt app.log_entry_durations['duration_enqueued'] = time_enqueued app.butler.ell.log(app.app_id+':ALG-DURATION', app.log_entry_durations) else: response = cached_response if DEBUG_ON: next.utils.debug_print('#### Finished Dashboard %s, time_enqueued=%s, execution_time=%s ####' % (stat_id, time_enqueued, dt), color='white') return json.dumps(response), True, ''
def getQuery(self, exp_uid, args_json): try: args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['getQuery']['args']) experiment_dict = self.butler.experiment.get() alg_list = experiment_dict['args']['alg_list'] participant_to_algorithm_management = experiment_dict['args']['participant_to_algorithm_management'] algorithm_management_settings = experiment_dict['args']['algorithm_management_settings'] # Create the participant dictionary in participants bucket if needed. Also pull out label and id for this algorithm participant_uid = args_dict['args'].get('participant_uid', args_dict['exp_uid']) # Check to see if the first participant has come by and if not, save to db participant_doc = self.butler.participants.get(uid=participant_uid) first_participant_query = participant_doc==None if first_participant_query: participant_doc = {} self.butler.participants.set(uid=participant_uid, value={'exp_uid':exp_uid, 'participant_uid':participant_uid}) if (participant_uid == exp_uid) or (participant_to_algorithm_management == 'one_to_many') or (first_participant_query): if algorithm_management_settings['mode'] == 'fixed_proportions': prop = [prop_item['proportion'] for prop_item in algorithm_management_settings['params']] chosen_alg = numpy.random.choice(alg_list, p=prop) elif algorithm_management_settings['mode'] == 'custom' : chosen_alg = self.myApp.chooseAlg(self.butler, alg_list, args_dict['args']) else: chosen_alg = numpy.random.choice(alg_list) alg_id = chosen_alg['alg_id'] alg_label = chosen_alg['alg_label'] if (first_participant_query) and (participant_to_algorithm_management=='one_to_one'): self.butler.participants.set(uid=participant_uid, key='alg_id',value=alg_id) self.butler.participants.set(uid=participant_uid, key='alg_label',value=alg_label) elif (participant_to_algorithm_management=='one_to_one'): alg_id = participant_doc['alg_id'] alg_label = participant_doc['alg_label'] query_uid = utils.getNewUID() args_dict['args'].update(query_uid=query_uid) query_doc = self.call_app_fn(alg_label, alg_id, 'getQuery', args_dict) query_doc.update({'participant_uid':participant_uid, 'alg_id':alg_id, 'exp_uid':exp_uid, 'alg_label':alg_label, 'timestamp_query_generated':str(utils.datetimeNow()), 'query_uid':query_uid}) self.butler.queries.set(uid=query_uid, value=query_doc) return json.dumps({'args':query_doc,'meta':{'log_entry_durations':self.log_entry_durations}}), True,'' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("getQuery Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'getQuery','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) return '{}', False, str(error)
def initExp(self, exp_uid, args_json): try: self.helper.ensure_indices(self.app_id,self.butler.db, self.butler.ell) args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['initExp']['args']) args_dict['exp_uid'] = exp_uid # to get doc from db args_dict['start_date'] = utils.datetime2str(utils.datetimeNow()) self.butler.admin.set(uid=exp_uid,value={'exp_uid': exp_uid, 'app_id':self.app_id, 'start_date':str(utils.datetimeNow())}) utils.debug_print("ASD "+str(args_dict)) args_dict['args'] = self.init_app(exp_uid, args_dict['args']['alg_list'], args_dict['args']) args_dict['git_hash'] = git_hash self.butler.experiment.set(value=args_dict) return '{}', True, '' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("initExp Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'initExp','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) return '{}', False, str(error)
def initExp(self, exp_uid, args_json): try: self.helper.ensure_indices(self.app_id,self.butler.db, self.butler.ell) args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['initExp']['args']) args_dict['exp_uid'] = exp_uid # to get doc from db args_dict['start_date'] = utils.datetime2str(utils.datetimeNow()) self.butler.admin.set(uid=exp_uid,value={'exp_uid': exp_uid, 'app_id':self.app_id, 'start_date':str(utils.datetimeNow())}) self.butler.experiment.set(value={'exp_uid': exp_uid}) args_dict['args'] = self.init_app(exp_uid, args_dict['args']['alg_list'], args_dict['args']) args_dict['git_hash'] = git_hash self.butler.experiment.set_many(key_value_dict=args_dict) return '{}', True, '' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("initExp Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'initExp','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) return '{}', False, str(error)
def getQuery(self, exp_uid, args_json): try: args_dict = self.helper.convert_json(args_json) args_dict = verifier.verify(args_dict, self.reference_dict['getQuery']['args']) experiment_dict = self.butler.experiment.get() alg_list = experiment_dict['args']['alg_list'] participant_to_algorithm_management = experiment_dict['args']['participant_to_algorithm_management'] algorithm_management_settings = experiment_dict['args']['algorithm_management_settings'] # Create the participant dictionary in participants bucket if needed. Also pull out label and id for this algorithm participant_uid = args_dict['args'].get('participant_uid', args_dict['exp_uid']) # Check to see if the first participant has come by and if not, save to db participant_doc = self.butler.participants.get(uid=participant_uid) first_participant_query = participant_doc==None if first_participant_query: participant_doc = {} self.butler.participants.set(uid=participant_uid, value={'exp_uid':exp_uid, 'participant_uid':participant_uid}) if (participant_uid == exp_uid) or (participant_to_algorithm_management == 'one_to_many') or (first_participant_query): if algorithm_management_settings['mode'] == 'fixed_proportions': labels = [alg['alg_label'] for alg in algorithm_management_settings['params']] prop = [prop_item['proportion'] for prop_item in algorithm_management_settings['params']] # reorder prop and alg_list to have same order new_alg_list = [] broken = False for label in labels: broken = False for alg in alg_list: if label == alg['alg_label']: new_alg_list += [alg] broken = True break if not broken: raise Exception('alg_label not present for both porportions and labels') chosen_alg = numpy.random.choice(new_alg_list, p=prop) elif algorithm_management_settings['mode'] == 'custom' : chosen_alg = self.myApp.chooseAlg(self.butler, alg_list, args_dict['args']) else: chosen_alg = numpy.random.choice(alg_list) alg_id = chosen_alg['alg_id'] alg_label = chosen_alg['alg_label'] if (first_participant_query) and (participant_to_algorithm_management=='one_to_one'): self.butler.participants.set(uid=participant_uid, key='alg_id',value=alg_id) self.butler.participants.set(uid=participant_uid, key='alg_label',value=alg_label) elif (participant_to_algorithm_management=='one_to_one'): alg_id = participant_doc['alg_id'] alg_label = participant_doc['alg_label'] query_uid = utils.getNewUID() args_dict['args'].update(query_uid=query_uid) query_doc = self.call_app_fn(alg_label, alg_id, 'getQuery', args_dict) query_doc.update({'participant_uid':participant_uid, 'alg_id':alg_id, 'exp_uid':exp_uid, 'alg_label':alg_label, 'timestamp_query_generated':str(utils.datetimeNow()), 'query_uid':query_uid}) self.butler.queries.set(uid=query_uid, value=query_doc) return json.dumps({'args':query_doc,'meta':{'log_entry_durations':self.log_entry_durations}}), True,'' except Exception, error: exc_type, exc_value, exc_traceback = sys.exc_info() full_error = str(traceback.format_exc())+'\n'+str(error) utils.debug_print("getQuery Exception: " + full_error, color='red') log_entry = { 'exp_uid':exp_uid,'task':'getQuery','error':full_error,'timestamp':utils.datetimeNow(),'args_json':args_json } self.butler.ell.log( self.app_id+':APP-EXCEPTION', log_entry ) traceback.print_tb(exc_traceback) return '{}', False, str(error)
def apply_dashboard(app_id, exp_uid, args_in_json, enqueue_timestamp): enqueue_datetime = next.utils.str2datetime(enqueue_timestamp) dequeue_datetime = next.utils.datetimeNow() delta_datetime = dequeue_datetime - enqueue_datetime time_enqueued = delta_datetime.seconds + delta_datetime.microseconds / 1000000. dir, _ = os.path.split(__file__) reference_dict, errs = verifier.load_doc( '{}/{}.yaml'.format(app_id, app_id), "apps/") if len(errs) > 0: raise Exception("App YAML format errors: \n{}".format(str(errs))) args_dict = verifier.verify(args_in_json, reference_dict['getStats']['args']) stat_id = args_dict['args'].get('stat_id', 'none') stat_args = args_dict['args'] hash_object = hashlib.md5(stat_id + '_' + json.dumps(stat_args['params'])) stat_uid = hash_object.hexdigest() app = App_Wrapper(app_id, exp_uid, db, ell) cached_doc = app.butler.dashboard.get(uid=stat_uid) cached_response = None if (int(stat_args.get('force_recompute', 0)) == 0) and (cached_doc is not None): delta_datetime = (next.utils.datetimeNow() - next.utils.str2datetime(cached_doc['timestamp'])) if delta_datetime.seconds < next.constants.DASHBOARD_STALENESS_IN_SECONDS: cached_response = json.loads(cached_doc['data_dict']) if 'meta' not in cached_response: cached_response['meta'] = {} cached_response['meta']['cached'] = 1 if delta_datetime.seconds / 60 < 1: cached_response['meta'][ 'last_dashboard_update'] = '<1 minute ago' else: cached_response['meta']['last_dashboard_update'] = str( delta_datetime.seconds / 60) + ' minutes ago' if cached_response == None: dashboard_string = 'apps.' + app_id + '.dashboard.Dashboard' dashboard_module = __import__(dashboard_string, fromlist=['']) dashboard = getattr(dashboard_module, app_id + 'Dashboard') dashboard = dashboard(db, ell) stats_method = getattr(dashboard, stat_id) response, dt = next.utils.timeit(stats_method)( app, app.butler, **args_dict['args']['params']) save_dict = { 'exp_uid': app.exp_uid, 'stat_uid': stat_uid, 'timestamp': next.utils.datetime2str(next.utils.datetimeNow()), 'data_dict': json.dumps(response) } app.butler.dashboard.set_many(uid=stat_uid, key_value_dict=save_dict) # update the admin timing with the timing of a getModel if hasattr(app, 'log_entry_durations'): app.log_entry_durations['app_duration'] = dt app.log_entry_durations['duration_enqueued'] = time_enqueued app.butler.ell.log(app.app_id + ':ALG-DURATION', app.log_entry_durations) else: response = cached_response if DEBUG_ON: next.utils.debug_print( '#### Finished Dashboard %s, time_enqueued=%s, execution_time=%s ####' % (stat_id, time_enqueued, dt), color='white') return json.dumps(response), True, ''