Exemple #1
0
def experiment_dashboard(exp_uid, app_id, exp_key):
    """
    Endpoint that renders the experiment dashboard.

    Inputs: ::\n
    	(string) exp_uid, exp_uid for a current experiment.
    """
    # Not a particularly good way to do this.
    alg_label_list = rm.get_algs_for_exp_uid(exp_uid)

    exp_start_data = rm.get_app_exp_uid_start_date(exp_uid) + ' UTC'
    participant_uids = rm.get_participant_uids(exp_uid)
    num_participants = len(participant_uids)
    last_datetime = None
    num_queries = 0
    for participant_uid in participant_uids:
        queries = rm.get_participant_data(participant_uid, exp_uid)
        num_queries += len(queries)

        this_datetime = utils.str2datetime(
            queries[-1]['timestamp_query_generated'])
        if last_datetime == None or this_datetime > last_datetime:
            last_datetime = this_datetime
    last_activity = utils.datetime2str(last_datetime) + ' UTC'

    # Migrate this code to use keychain
    docs, didSucceed, message = db.getDocsByPattern('next_frontend_base',
                                                    'keys', {
                                                        'object_id': exp_uid,
                                                        'type': 'perm'
                                                    })
    perm_key = docs[0]['_id']
    alg_list = [{
        'alg_label': alg['alg_label'],
        'alg_label_clean': '_'.join(alg['alg_label'].split())
    } for alg in alg_label_list]

    if (constants.NEXT_BACKEND_GLOBAL_HOST
            and constants.NEXT_BACKEND_GLOBAL_PORT):
        host_url = 'http://{}:{}'.format(constants.NEXT_BACKEND_GLOBAL_HOST,
                                         constants.NEXT_BACKEND_GLOBAL_PORT)
    else:
        host_url = ''
    print 'host_url', host_url
    print constants.NEXT_BACKEND_GLOBAL_HOST, constants.NEXT_BACKEND_GLOBAL_PORT
    env = Environment(loader=ChoiceLoader([
        PackageLoader('next.apps.{}'.format(app_id), 'dashboard'),
        PackageLoader('next.dashboard', 'templates')
    ]))
    template = env.get_template('{}.html'.format(app_id))
    return template.render(app_id=app_id,
                           exp_uid=exp_uid,
                           alg_list=alg_list,
                           host_url=host_url,
                           perm_key=perm_key,
                           url_for=url_for,
                           exp_start_data=exp_start_data,
                           num_participants=num_participants,
                           num_queries=num_queries,
                           last_activity=last_activity)
Exemple #2
0
    def refresh_domain_hashes(self):

        # see what workers are out there
        worker_pings = None
        while worker_pings == None:
            try:
                # one could also use app.control.inspect().active_queues()
                worker_pings = app.control.inspect().ping()
            except:
                worker_pings = None
        worker_names = worker_pings.keys()
        domain_names_with_dups = [item.split('@')[1] for item in worker_names]
        domain_names = list(set(domain_names_with_dups))  # remove duplicates!

        timestamp = utils.datetime2str(utils.datetimeNow())
        print "[ %s ] domains with active workers = %s" % (timestamp,
                                                           str(domain_names))

        replicated_domains_hash = []
        for domain in domain_names:
            for i in range(self.num_replicas):
                replicated_domains_hash.append(
                    (domain, self.hash(domain + '_replica_' + str(i)), i))
        replicated_domains_hash = sorted(replicated_domains_hash,
                                         key=lambda x: x[1])

        self.r.set('replicated_domains_hash',
                   json.dumps(replicated_domains_hash))
Exemple #3
0
 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)
Exemple #4
0
 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)
Exemple #5
0
    def refresh_domain_hashes(self):

        # see what workers are out there
        worker_pings = None
        while worker_pings==None:
            try:
                # one could also use app.control.inspect().active_queues()
                worker_pings = app.control.inspect().ping()
            except:
                worker_pings = None
        worker_names = worker_pings.keys()
        domain_names_with_dups = [ item.split('@')[1] for item in worker_names]
        domain_names = list(set(domain_names_with_dups)) # remove duplicates!

        timestamp = utils.datetime2str(utils.datetimeNow())
        print "[ %s ] domains with active workers = %s" % (timestamp,str(domain_names))

        replicated_domains_hash = []
        for domain in domain_names:
            for i in range(self.num_replicas):
                replicated_domains_hash.append((domain, self.hash(domain+'_replica_'+str(i)), i))
        replicated_domains_hash = sorted( replicated_domains_hash, key = lambda x: x[1])  

        self.r.set('replicated_domains_hash',json.dumps(replicated_domains_hash))
  def initExp(self,exp_uid,args_json,db,ell):
    """
    initialize the project and necessary experiments 

    Expected input (in json structure with string keys):
      (int) n: number of arms
      (int) k: number of objects to display
      (float) failure_probability : confidence
      [optional] (list of dicts) alg_list : with fields (Defaults given by Info.get_app_default_alg_list)
            (string) alg_id : valid alg_id for this app_id
            (string) alg_label : unique identifier for algorithm (e.g. may have experiment with repeated alg_id's, but alg_labels must be unqiue, will also be used for plot legends
            [optional] (string) test_alg_label : must be one of the alg_label's in alg_list (Default is self)
      [optional] (dict) algorithm_management_settings : dictionary with fields (string) 'mode' and (dict) 'params'. mode in {'pure_exploration','explore_exploit','fixed_proportions'}. Default is 'fixed_proportions' and allocates uniform probability to each algorithm. If mode=fixed_proportions then params is a dictionary that contains the field 'proportions' which is a list of dictionaries with fields 'alg_label' and 'proportion' for all algorithms in alg_list. All proportions must be positive and sum to 1 over all algs in alg_list 
      [optional] (string) participant_to_algorithm_management : in {'one_to_one','one_to_many'}. Default is 'one_to_many'.
      [optional] (string) instructions
      [optional] (string) debrief
      
    Expected output:
      if error:
        return (JSON) '{}', (bool) False, (str) error_str
      else:
        return (JSON) '{}', (bool) True,''

    Usage:
      initExp_response_json,didSucceed,message = app.initExp(exp_uid,initExp_args_json)

    Example input:
      initExp_args_json = {"participant_to_algorithm_management": "one_to_many", "alg_list": [{"alg_label": "BR_LilUCB", "alg_id": "BR_LilUCB", "params": {}}], "algorithm_management_settings": {"params": {"proportions": [{"alg_label": "BR_LilUCB", "proportion": 1.0}]}, "mode": "fixed_proportions"}, "failure_probability": 0.01, "n": 10}

    Example output:
      initExp_response_json = {}
    """

    try:
      app_id = self.app_id

      # remove any reminants of an experiment if it exists
      didSucceed,message = db.delete_docs_with_filter('experiments_admin',{'exp_uid':exp_uid})
      didSucceed,message = db.delete_docs_with_filter(app_id+':experiments',{'exp_uid':exp_uid})
      didSucceed,message = db.delete_docs_with_filter(app_id+':queries',{'exp_uid':exp_uid})
      didSucceed,message = db.delete_docs_with_filter(app_id+':participants',{'exp_uid':exp_uid})
      didSucceed,message = db.delete_docs_with_filter(app_id+':algorithms',{'exp_uid':exp_uid})
      
      didSucceed,message = ell.delete_logs_with_filter(app_id+':APP-CALL',{'exp_uid':exp_uid})
      didSucceed,message = ell.delete_logs_with_filter(app_id+':APP-RESPONSE',{'exp_uid':exp_uid})
      didSucceed,message = ell.delete_logs_with_filter(app_id+':APP-EXCEPTION',{'exp_uid':exp_uid})
      didSucceed,message = ell.delete_logs_with_filter(app_id+':ALG-DURATION',{'exp_uid':exp_uid})
      didSucceed,message = ell.delete_logs_with_filter(app_id+':ALG-EVALUATION',{'exp_uid':exp_uid})

      # add indexes (only adds them if they do not already exist)
      didSucceed,message = db.ensure_index('experiments_admin',{'exp_uid':1})
      didSucceed,message = db.ensure_index(app_id+':experiments',{'exp_uid':1})
      didSucceed,message = db.ensure_index(app_id+':queries',{'query_uid':1})
      didSucceed,message = db.ensure_index(app_id+':queries',{'exp_uid':1})
      didSucceed,message = db.ensure_index(app_id+':queries',{'alg_uid':1})
      didSucceed,message = db.ensure_index(app_id+':queries',{'participant_uid':1})
      didSucceed,message = db.ensure_index(app_id+':participants',{'participant_uid':1})
      didSucceed,message = db.ensure_index(app_id+':participants',{'exp_uid':1})
      didSucceed,message = db.ensure_index(app_id+':algorithms',{'alg_uid':1})
      didSucceed,message = db.ensure_index(app_id+':algorithms',{'exp_uid':1})

      didSucceed,message = ell.ensure_index(app_id+':APP-CALL',{'exp_uid':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-CALL',{'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-CALL',{'exp_uid':1,'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-CALL',{'exp_uid':1,'task':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-RESPONSE',{'exp_uid':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-RESPONSE',{'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-RESPONSE',{'exp_uid':1,'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-RESPONSE',{'exp_uid':1,'task':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-EXCEPTION',{'exp_uid':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-EXCEPTION',{'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-EXCEPTION',{'exp_uid':1,'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':APP-EXCEPTION',{'exp_uid':1,'task':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-DURATION',{'exp_uid':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-DURATION',{'alg_uid':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-DURATION',{'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-DURATION',{'exp_uid':1,'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-DURATION',{'alg_uid':1,'task':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-EVALUATION',{'exp_uid':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-EVALUATION',{'alg_uid':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-EVALUATION',{'timestamp':1})
      didSucceed,message = ell.ensure_index(app_id+':ALG-EVALUATION',{'exp_uid':1,'timestamp':1})
      

      db.set('experiments_admin',exp_uid,'exp_uid',exp_uid)
      db.set('experiments_admin',exp_uid,'app_id',app_id)
      db.set('experiments_admin',exp_uid,'start_date',utils.datetime2str(utils.datetimeNow()))

      log_entry = { 'exp_uid':exp_uid,'task':'initExp','json':args_json,'timestamp':utils.datetimeNow() } 
      ell.log( app_id+':APP-CALL', log_entry  )

      # convert args_json to args_dict
      try:
        args_dict = json.loads(args_json)
      except:
        error = "%s.initExp input args_json is in improper format" % self.app_id
        return '{}',False,error

      # check for the fields that must be contained in args or error occurs
      necessary_fields = ['n','k','failure_probability']
      for field in necessary_fields:
        try:
          args_dict[field]

        except KeyError:
          error = "%s.initExp input arguments missing field: %s" % (self.app_id,str(field)) 
          return '{}',False,error

      n = args_dict['n']
      k = args_dict['k']
      delta = args_dict['failure_probability']

      if 'alg_list' in args_dict:
        alg_list = args_dict['alg_list']
        supportedAlgs = utils.get_app_supported_algs(self.app_id)
        for algorithm in alg_list:
          if algorithm['alg_id'] not in supportedAlgs:
            error = "%s.initExp unsupported algorithm '%s' in alg_list" % (self.app_id,alg_id)
            return '{}',False,error
      else:
        alg_list = utils.get_app_default_alg_list(self.app_id)

      if 'instructions' not in args_dict:
        instructions = utils.get_app_default_instructions(app_id)
      else:
        instructions = args_dict['instructions']

      if 'debrief' not in args_dict:
        debrief = utils.get_app_default_instructions(app_id)
      else:
        debrief = args_dict['debrief']

      if 'num_tries' not in args_dict:
        num_tries = utils.get_app_default_num_tries(app_id)
      else:
        num_tries = args_dict['num_tries']

      if 'context_type' not in args_dict:
        context_type = 'none'
      else:
        context_type = args_dict['context_type']

      if 'context' not in args_dict:
        context = ''
      else:
        context = args_dict['context']

      # ALGORITHM_MANAGEMENT_MODE FORMATTING CHECK
      if 'algorithm_management_settings' not in args_dict:
        params = {}
        params['proportions'] = []
        for algorithm in alg_list:
          params['proportions'].append(  { 'alg_label': algorithm['alg_label'] , 'proportion':1./len(alg_list)}  )

        algorithm_management_settings = {}
        algorithm_management_settings['mode'] = 'fixed_proportions'
        algorithm_management_settings['params'] = params
      else:
        algorithm_management_settings = args_dict['algorithm_management_settings']

        try:
          mode = algorithm_management_settings['mode']
          params = algorithm_management_settings['params']
        except:
          error = "%s.initExp algorithm_management_settings must be a dictionary with fields 'mode' and 'params'" % (self.app_id)
          return '{}',False,error

        if mode == 'fixed_proportions':
          try:
            algorithm_proportions_list = params['proportions']
          except:
            error = "%s.initExp algorithm_management_settings['params'] must be a dictionary with field 'proportions'" % (self.app_id)
            return '{}',False,error

          # check if alg_labels are properly labeled
          for proportion_item in algorithm_proportions_list:
            proportion = proportion_item['proportion']
            target_alg_label = proportion_item['alg_label']
            target_alg_label_in_alg_list = False
            for algorithm in alg_list:
              if algorithm['alg_label']==target_alg_label:
                target_alg_label_in_alg_list = True
            if not target_alg_label_in_alg_list:
              error = "%s.initExp algorithm_management_settings['params']['proportions'] must be a list of dictionaries, each dictionary containing the fields 'alg_label' and 'proportion'. The 'alg_label' value must be one of the alg_labels in a provided alg_list and 'proportion' must be nonnegative and sum to 1 : '%s' not in provided alg_list" % (self.app_id,target_alg_label)
              return '{}',False,error

        elif mode == 'pure_exploration':
          error = "%s.initExp Sorry, '%s' is not yet supported." % (self.app_id,mode)
          return '{}',False,error
        elif mode == 'explore_exploit':
          error = "%s.initExp Sorry, '%s' is not yet supported." % (self.app_id,mode)
          return '{}',False,error
        else:
          error = "%s.initExp unsupported algorithm_management_mode: '%s'. Must be in {'pure_exploration','explore_exploit','fixed_proportions'}" % (self.app_id,algorithm_management_mode)
          return '{}',False,error

      # ALGORITHM_MANAGEMENT_MODE FORMATTING CHECK
      if 'participant_to_algorithm_management' not in args_dict:
        participant_to_algorithm_management = 'one_to_many'
      else:
        participant_to_algorithm_management = args_dict['participant_to_algorithm_management']
        if participant_to_algorithm_management not in ['one_to_many','one_to_one']:
          error = "%s.initExp unsupported participant_to_algorithm_management: '%s'. Must be in {'one_to_many','one_to_one'}" % (self.app_id,participant_to_algorithm_management)
          return '{}',False,error

      # assign uid to each algorithm and save it
      for algorithm in alg_list:
        alg_uid = utils.getNewUID()
        algorithm['alg_uid'] = alg_uid

        db.set(app_id+':algorithms',alg_uid,'alg_uid',alg_uid)
        db.set(app_id+':algorithms',alg_uid,'exp_uid',exp_uid)

      db.set(app_id+':experiments',exp_uid,'exp_uid',exp_uid)
      db.set(app_id+':experiments',exp_uid,'app_id',app_id)
      db.set(app_id+':experiments',exp_uid,'n',n)
      db.set(app_id+':experiments',exp_uid,'k',k)
      db.set(app_id+':experiments',exp_uid,'failure_probability',delta)
      db.set(app_id+':experiments',exp_uid,'alg_list',alg_list)
      db.set(app_id+':experiments',exp_uid,'algorithm_management_settings',algorithm_management_settings)
      db.set(app_id+':experiments',exp_uid,'participant_to_algorithm_management',participant_to_algorithm_management)
      db.set(app_id+':experiments',exp_uid,'instructions',instructions)
      db.set(app_id+':experiments',exp_uid,'debrief',debrief)
      db.set(app_id+':experiments',exp_uid,'context_type',context_type)
      db.set(app_id+':experiments',exp_uid,'context',context)
      db.set(app_id+':experiments',exp_uid,'num_tries',num_tries)

      # now create intitialize each algorithm
      for algorithm in alg_list:
        alg_id = algorithm['alg_id'] 
        alg_uid = algorithm['alg_uid']

        db.set(app_id+':algorithms',alg_uid,'alg_id',alg_id)
        db.set(app_id+':algorithms',alg_uid,'alg_uid',alg_uid)
        db.set(app_id+':algorithms',alg_uid,'exp_uid',exp_uid)

        # get sandboxed database for the specific app_id,alg_id,exp_uid - closing off the rest of the database to the algorithm
        rc = ResourceClient(app_id,exp_uid,alg_uid,db)

        # get specific algorithm to make calls to 
        alg = utils.get_app_alg(self.app_id,alg_id)

        # call initExp
        didSucceed,dt = utils.timeit(alg.initExp)(resource=rc,n=n,k=k,failure_probability=delta)

        log_entry = { 'exp_uid':exp_uid,'alg_uid':alg_uid,'task':'initExp','duration':dt,'timestamp':utils.datetimeNow() } 
        ell.log( app_id+':ALG-DURATION', log_entry  )

      response_json = '{}'

      log_entry = { 'exp_uid':exp_uid,'task':'initExp','json':response_json,'timestamp':utils.datetimeNow() } 
      ell.log( app_id+':APP-RESPONSE', log_entry  )

      return response_json,True,''

    except Exception, err:
      error = traceback.format_exc()
      log_entry = { 'exp_uid':exp_uid,'task':'initExp','error':error,'timestamp':utils.datetimeNow(),'args_json':args_json } 
      ell.log( app_id+':APP-EXCEPTION', log_entry  )
      return '{}',False,error
Exemple #7
0
    def initExp(self, exp_uid, args_json, db, ell):
        """
    initialize the project and necessary experiments 

    Expected input (in json structure with string keys):
      (int) n: number of arms
      (float) failure_probability : confidence
      [optional] (list of dicts) alg_list : with fields (Defaults given by Info.get_app_default_alg_list)
            (string) alg_id : valid alg_id for this app_id
            (string) alg_label : unique identifier for algorithm (e.g. may have experiment with repeated alg_id's, but alg_labels must be unqiue, will also be used for plot legends
            [optional] (string) test_alg_label : must be one of the alg_label's in alg_list (Default is self)
      [optional] (dict) algorithm_management_settings : dictionary with fields (string) 'mode' and (dict) 'params'. mode in {'pure_exploration','explore_exploit','fixed_proportions'}. Default is 'fixed_proportions' and allocates uniform probability to each algorithm. If mode=fixed_proportions then params is a dictionary that contains the field 'proportions' which is a list of dictionaries with fields 'alg_label' and 'proportion' for all algorithms in alg_list. All proportions must be positive and sum to 1 over all algs in alg_list 
      [optional] (string) participant_to_algorithm_management : in {'one_to_one','one_to_many'}. Default is 'one_to_many'.
      [optional] (string) instructions
      [optional] (string) debrief
      [optional] (int) num_tries
    
    Expected output:
      if error:
        return (JSON) '{}', (bool) False, (str) error_str
      else:
        return (JSON) '{}', (bool) True,''

    Usage:
      initExp_response_json,didSucceed,message = app.initExp(db_API,exp_uid,initExp_args_json)

    Example input:
      initExp_args_json = {"participant_to_algorithm_management": "one_to_many", "alg_list": [{"alg_label": "BR_LilUCB", "alg_id": "BR_LilUCB", "params": {}}], "algorithm_management_settings": {"params": {"proportions": [{"alg_label": "BR_LilUCB", "proportion": 1.0}]}, "mode": "fixed_proportions"}, "failure_probability": 0.01, "n": 10}

    Example output:
      initExp_response_json = {}
    """

        try:
            app_id = self.app_id

            # remove any reminants of an experiment if it exists
            didSucceed, message = db.delete_docs_with_filter(
                'experiments_admin', {'exp_uid': exp_uid})
            didSucceed, message = db.delete_docs_with_filter(
                app_id + ':experiments', {'exp_uid': exp_uid})
            didSucceed, message = db.delete_docs_with_filter(
                app_id + ':queries', {'exp_uid': exp_uid})
            didSucceed, message = db.delete_docs_with_filter(
                app_id + ':participants', {'exp_uid': exp_uid})
            didSucceed, message = db.delete_docs_with_filter(
                app_id + ':algorithms', {'exp_uid': exp_uid})

            didSucceed, message = ell.delete_logs_with_filter(
                app_id + ':APP-CALL', {'exp_uid': exp_uid})
            didSucceed, message = ell.delete_logs_with_filter(
                app_id + ':APP-RESPONSE', {'exp_uid': exp_uid})
            didSucceed, message = ell.delete_logs_with_filter(
                app_id + ':APP-EXCEPTION', {'exp_uid': exp_uid})
            didSucceed, message = ell.delete_logs_with_filter(
                app_id + ':ALG-DURATION', {'exp_uid': exp_uid})
            didSucceed, message = ell.delete_logs_with_filter(
                app_id + ':ALG-EVALUATION', {'exp_uid': exp_uid})

            # add indexes (only adds them if they do not already exist)
            didSucceed, message = db.ensure_index('experiments_admin',
                                                  {'exp_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':experiments',
                                                  {'exp_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':queries',
                                                  {'query_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':queries',
                                                  {'exp_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':queries',
                                                  {'alg_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':queries',
                                                  {'participant_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':participants',
                                                  {'participant_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':participants',
                                                  {'exp_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':algorithms',
                                                  {'alg_uid': 1})
            didSucceed, message = db.ensure_index(app_id + ':algorithms',
                                                  {'exp_uid': 1})

            didSucceed, message = ell.ensure_index(app_id + ':APP-CALL',
                                                   {'exp_uid': 1})
            didSucceed, message = ell.ensure_index(app_id + ':APP-CALL',
                                                   {'timestamp': 1})
            didSucceed, message = ell.ensure_index(app_id + ':APP-CALL', {
                'exp_uid': 1,
                'timestamp': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':APP-CALL', {
                'exp_uid': 1,
                'task': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':APP-RESPONSE',
                                                   {'exp_uid': 1})
            didSucceed, message = ell.ensure_index(app_id + ':APP-RESPONSE',
                                                   {'timestamp': 1})
            didSucceed, message = ell.ensure_index(app_id + ':APP-RESPONSE', {
                'exp_uid': 1,
                'timestamp': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':APP-RESPONSE', {
                'exp_uid': 1,
                'task': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':APP-EXCEPTION',
                                                   {'exp_uid': 1})
            didSucceed, message = ell.ensure_index(app_id + ':APP-EXCEPTION',
                                                   {'timestamp': 1})
            didSucceed, message = ell.ensure_index(app_id + ':APP-EXCEPTION', {
                'exp_uid': 1,
                'timestamp': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':APP-EXCEPTION', {
                'exp_uid': 1,
                'task': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':ALG-DURATION',
                                                   {'exp_uid': 1})
            didSucceed, message = ell.ensure_index(app_id + ':ALG-DURATION',
                                                   {'alg_uid': 1})
            didSucceed, message = ell.ensure_index(app_id + ':ALG-DURATION',
                                                   {'timestamp': 1})
            didSucceed, message = ell.ensure_index(app_id + ':ALG-DURATION', {
                'exp_uid': 1,
                'timestamp': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':ALG-DURATION', {
                'alg_uid': 1,
                'task': 1
            })
            didSucceed, message = ell.ensure_index(app_id + ':ALG-EVALUATION',
                                                   {'exp_uid': 1})
            didSucceed, message = ell.ensure_index(app_id + ':ALG-EVALUATION',
                                                   {'alg_uid': 1})
            didSucceed, message = ell.ensure_index(app_id + ':ALG-EVALUATION',
                                                   {'timestamp': 1})
            didSucceed, message = ell.ensure_index(app_id + ':ALG-EVALUATION',
                                                   {
                                                       'exp_uid': 1,
                                                       'timestamp': 1
                                                   })

            db.set('experiments_admin', exp_uid, 'exp_uid', exp_uid)
            db.set('experiments_admin', exp_uid, 'app_id', app_id)
            db.set('experiments_admin', exp_uid, 'start_date',
                   utils.datetime2str(utils.datetimeNow()))

            log_entry = {
                'exp_uid': exp_uid,
                'task': 'initExp',
                'json': args_json,
                'timestamp': utils.datetimeNow()
            }
            ell.log(app_id + ':APP-CALL', log_entry)

            # convert args_json to args_dict
            try:
                args_dict = json.loads(args_json)
            except:
                error = "%s.initExp input args_json is in improper format" % self.app_id
                return '{}', False, error

            # check for the fields that must be contained in args or error occurs
            necessary_fields = ['n', 'failure_probability']
            for field in necessary_fields:
                try:
                    args_dict[field]

                except KeyError:
                    error = "%s.initExp input arguments missing field: %s" % (
                        self.app_id, str(field))
                    return '{}', False, error

            n = args_dict['n']
            delta = args_dict['failure_probability']

            if 'alg_list' in args_dict:
                alg_list = args_dict['alg_list']
                supportedAlgs = utils.get_app_supported_algs(self.app_id)
                for algorithm in alg_list:
                    if algorithm['alg_id'] not in supportedAlgs:
                        error = "%s.initExp unsupported algorithm '%s' in alg_list" % (
                            self.app_id, alg_id)
                        return '{}', False, error
            else:
                alg_list = utils.get_app_default_alg_list(self.app_id)

            if 'instructions' not in args_dict:
                instructions = utils.get_app_default_instructions(app_id)
            else:
                instructions = args_dict['instructions']

            if 'debrief' not in args_dict:
                debrief = utils.get_app_default_instructions(app_id)
            else:
                debrief = args_dict['debrief']

            if 'num_tries' not in args_dict:
                num_tries = utils.get_app_default_num_tries(app_id)
            else:
                num_tries = args_dict['num_tries']

            if 'context_type' not in args_dict:
                context_type = 'none'
            else:
                context_type = args_dict['context_type']

            if 'context' not in args_dict:
                context = ''
            else:
                context = args_dict['context']

            # ALGORITHM_MANAGEMENT_MODE FORMATTING CHECK
            if 'algorithm_management_settings' not in args_dict:
                params = {}
                params['proportions'] = []
                for algorithm in alg_list:
                    params['proportions'].append({
                        'alg_label':
                        algorithm['alg_label'],
                        'proportion':
                        1. / len(alg_list)
                    })

                algorithm_management_settings = {}
                algorithm_management_settings['mode'] = 'fixed_proportions'
                algorithm_management_settings['params'] = params
            else:
                algorithm_management_settings = args_dict[
                    'algorithm_management_settings']

                try:
                    mode = algorithm_management_settings['mode']
                    params = algorithm_management_settings['params']
                except:
                    error = "%s.initExp algorithm_management_settings must be a dictionary with fields 'mode' and 'params'" % (
                        self.app_id)
                    return '{}', False, error

                if mode == 'fixed_proportions':
                    try:
                        algorithm_proportions_list = params['proportions']
                    except:
                        error = "%s.initExp algorithm_management_settings['params'] must be a dictionary with field 'proportions'" % (
                            self.app_id)
                        return '{}', False, error

                    # check if alg_labels are properly labeled
                    for proportion_item in algorithm_proportions_list:
                        proportion = proportion_item['proportion']
                        target_alg_label = proportion_item['alg_label']
                        target_alg_label_in_alg_list = False
                        for algorithm in alg_list:
                            if algorithm['alg_label'] == target_alg_label:
                                target_alg_label_in_alg_list = True
                        if not target_alg_label_in_alg_list:
                            error = "%s.initExp algorithm_management_settings['params']['proportions'] must be a list of dictionaries, each dictionary containing the fields 'alg_label' and 'proportion'. The 'alg_label' value must be one of the alg_labels in a provided alg_list and 'proportion' must be nonnegative and sum to 1 : '%s' not in provided alg_list" % (
                                self.app_id, target_alg_label)
                            return '{}', False, error

                elif mode == 'pure_exploration':
                    error = "%s.initExp Sorry, '%s' is not yet supported." % (
                        self.app_id, mode)
                    return '{}', False, error
                elif mode == 'explore_exploit':
                    error = "%s.initExp Sorry, '%s' is not yet supported." % (
                        self.app_id, mode)
                    return '{}', False, error
                else:
                    error = "%s.initExp unsupported algorithm_management_mode: '%s'. Must be in {'pure_exploration','explore_exploit','fixed_proportions'}" % (
                        self.app_id, algorithm_management_mode)
                    return '{}', False, error

            # ALGORITHM_MANAGEMENT_MODE FORMATTING CHECK
            if 'participant_to_algorithm_management' not in args_dict:
                participant_to_algorithm_management = 'one_to_many'
            else:
                participant_to_algorithm_management = args_dict[
                    'participant_to_algorithm_management']
                if participant_to_algorithm_management not in [
                        'one_to_many', 'one_to_one'
                ]:
                    error = "%s.initExp unsupported participant_to_algorithm_management: '%s'. Must be in {'one_to_many','one_to_one'}" % (
                        self.app_id, participant_to_algorithm_management)
                    return '{}', False, error

            # assign uid to each algorithm and save it
            for algorithm in alg_list:
                alg_uid = utils.getNewUID()
                algorithm['alg_uid'] = alg_uid

                db.set(app_id + ':algorithms', alg_uid, 'alg_uid', alg_uid)
                db.set(app_id + ':algorithms', alg_uid, 'exp_uid', exp_uid)

            db.set(app_id + ':experiments', exp_uid, 'exp_uid', exp_uid)
            db.set(app_id + ':experiments', exp_uid, 'app_id', app_id)
            db.set(app_id + ':experiments', exp_uid, 'n', n)
            db.set(app_id + ':experiments', exp_uid, 'failure_probability',
                   delta)
            db.set(app_id + ':experiments', exp_uid, 'alg_list', alg_list)
            db.set(app_id + ':experiments', exp_uid,
                   'algorithm_management_settings',
                   algorithm_management_settings)
            db.set(app_id + ':experiments', exp_uid,
                   'participant_to_algorithm_management',
                   participant_to_algorithm_management)
            db.set(app_id + ':experiments', exp_uid, 'instructions',
                   instructions)
            db.set(app_id + ':experiments', exp_uid, 'debrief', debrief)
            db.set(app_id + ':experiments', exp_uid, 'context_type',
                   context_type)
            db.set(app_id + ':experiments', exp_uid, 'context', context)
            db.set(app_id + ':experiments', exp_uid, 'num_tries', num_tries)

            # now create intitialize each algorithm
            for algorithm in alg_list:
                alg_id = algorithm['alg_id']
                alg_uid = algorithm['alg_uid']

                db.set(app_id + ':algorithms', alg_uid, 'alg_id', alg_id)
                db.set(app_id + ':algorithms', alg_uid, 'alg_uid', alg_uid)
                db.set(app_id + ':algorithms', alg_uid, 'exp_uid', exp_uid)

                # get sandboxed database for the specific app_id,alg_id,exp_uid - closing off the rest of the database to the algorithm
                rc = ResourceClient(app_id, exp_uid, alg_uid, db)

                # get specific algorithm to make calls to
                alg = utils.get_app_alg(self.app_id, alg_id)

                # call initExp
                didSucceed, dt = utils.timeit(alg.initExp)(
                    resource=rc, n=n, failure_probability=delta)

                log_entry = {
                    'exp_uid': exp_uid,
                    'alg_uid': alg_uid,
                    'task': 'initExp',
                    'duration': dt,
                    'timestamp': utils.datetimeNow()
                }
                ell.log(app_id + ':ALG-DURATION', log_entry)

            response_json = '{}'

            log_entry = {
                'exp_uid': exp_uid,
                'task': 'initExp',
                'json': response_json,
                'timestamp': utils.datetimeNow()
            }
            ell.log(app_id + ':APP-RESPONSE', log_entry)

            return response_json, True, ''

        except Exception, err:
            error = traceback.format_exc()
            log_entry = {
                'exp_uid': exp_uid,
                'task': 'initExp',
                'error': error,
                'timestamp': utils.datetimeNow(),
                'args_json': args_json
            }
            ell.log(app_id + ':APP-EXCEPTION', log_entry)
            return '{}', False, error
Exemple #8
0
#!/usr/bin/python
import time
import traceback
import next.utils as utils

import next.broker.broker
broker = next.broker.broker.JobBroker()

while (1):

    timestamp = utils.datetime2str(utils.datetimeNow())
    try:
        broker.refresh_domain_hashes()
    except Exception, err:
        error = traceback.format_exc()
        print error

    # wait
    time.sleep(2)