def get(self, exp_id):
     """ Get an action given a context for a specific exp_id
     
     Input arguments:
     exp_id: Experiment ID as specified in the url
     context: string of JSON object which obtains the context. This is assumed to be passed in the query string 
     key: part of the JSON object        
     
     Returns:
     A JSON object containing "action": XX
     Or an object containing "error": ...
     """
     key = self.get_argument("key", default = False)
     
     if not key:
         self.set_status(401)
         self.write("invalid key")
         return
     
     __EXP__ = Experiment(exp_id, key)
     
     if __EXP__.is_valid():
         context = json.loads(self.get_argument("context", default="{}"))    
         response = __EXP__.run_action_code(context)
         
         if self.settings['debug']:
             self.write(json.dumps({'action':response, 'context':context}))
         else:
             self.write(json.dumps({'action':response}))
             
     else:
         self.set_status(401)       # Needs proper error handling
         self.write("invalid key")
         return
Example #2
0
    def get(self, exp_id):
        """ Get an action given a context for a specific exp_id
        
        +----------------------------------------------------------------+
        | Example                                                        |
        +================================================================+
        |http://example.com/1/getAction.json?key=XXXX&context={'age': 25}|
        +----------------------------------------------------------------+
        
        
        :param int exp_id: Experiment ID as specified in the url
        :param JSON context: The context to be evaluated. 
        :param string key: The key corresponding to the experiment.
        
        :returns: A JSON of the form: {"action": XX}
        :raises AuthErorr: 401 Invalid key
        """
        key = self.get_argument("key", default=False)

        if not key:
            self.set_status(401)
            self.write("invalid key")
            return

        __EXP__ = Experiment(exp_id, key)

        if __EXP__.is_valid():
            context = json.loads(self.get_argument("context", default="{}"))
            response = __EXP__.run_action_code(context)

            if self.settings['debug']:
                self.write(json.dumps({
                    'action': response,
                    'context': context
                }))
            else:
                self.write(json.dumps({'action': response}))

        else:
            self.set_status(401)  # Needs proper error handling
            self.write("invalid key")
            return
Example #3
0
 def get(self, exp_id):
     """ Get an action given a context for a specific exp_id
     
     +----------------------------------------------------------------+
     | Example                                                        |
     +================================================================+
     |http://example.com/1/getAction.json?key=XXXX&context={'age': 25}|
     +----------------------------------------------------------------+
     
     
     :param int exp_id: Experiment ID as specified in the url
     :param JSON context: The context to be evaluated. 
     :param string key: The key corresponding to the experiment.
     
     :returns: A JSON of the form: {"action": XX}
     :raises AuthErorr: 401 Invalid key
     """
     key = self.get_argument("key", default = False)
     
     if not key:
         self.set_status(401)
         self.write("invalid key")
         return
     
     __EXP__ = Experiment(exp_id, key)
     
     if __EXP__.is_valid():
         context = json.loads(self.get_argument("context", default="{}"))  
         response = __EXP__.run_action_code(context)
         
         if self.settings['debug']:
             self.write(json.dumps({'action':response, 'context':context}))
         else:
             self.write(json.dumps({'action':response}))
             
     else:
         self.set_status(401)       # Needs proper error handling
         self.write("invalid key")
         return
Example #4
0
    def get(self, exp_id):  # Documentation needs update to advice_id
        """ Get an action given a context for a specific exp_id.
        
        +----------------------------------------------------------------+
        | Example                                                        |
        +================================================================+
        |http://example.com/getaction/EXP_ID?key=KEY&context=CONTEXT     |
        +----------------------------------------------------------------+
        
        :param int exp_id: Experiment ID as specified in the url.
        :param string key: The key corresponding to the experiment.
        :param JSON context (optional): The context to be evaluated. 
        :returns: A JSON that standard only includes action. When debug is toggled, \
        it returns the context as well. When Advice ID is toggled, it will also return \
        an Advice ID that can be used to set the reward later on.
        :raises 400: If the key is not supplied.
        :raises 401: If the key or exp_id is invalid.
        """
        key = self.get_argument("key", default=False)
        context = json.loads(self.get_argument("context", default="{}"))

        if not key:
            raise ExceptionHandler(reason="Key not supplied.", status_code=400)

        __EXP__ = Experiment(exp_id, key)

        if __EXP__.is_valid():
            response = __EXP__.run_action_code(context)

            if __EXP__.properties['advice_id'] == "True":
                advice_id = __EXP__.gen_advice_id(response.copy(),
                                                  context.copy())

            __EXP__.log_getaction_data(context, response)

            if self.settings['debug'] and __EXP__.properties[
                    'advice_id'] == "True":
                self.write(
                    json.dumps(
                        {
                            'action': response,
                            'context': context,
                            'advice_id': advice_id
                        },
                        default=json_util.default))
            elif __EXP__.properties['advice_id'] == "True":
                self.write(
                    json.dumps({
                        'action': response,
                        'advice_id': advice_id
                    },
                               default=json_util.default))
            elif self.settings['debug']:
                self.write(json.dumps({
                    'action': response,
                    'context': context
                }))
            else:
                self.write(json.dumps({'action': response}))
        else:
            raise ExceptionHandler(reason="Key or exp_id is invalid.",
                                   status_code=401)
Example #5
0
    def get(self, exp_id):
        """ Simulate your experiment based on four scripts, which create a closed feedback loop.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        |http://example.com/eval/EXP_ID/simulate?N=1000&log_stats=True       |
        |&verbose=True&seed=10                                               |
        +--------------------------------------------------------------------+

        :requires: A secure cookie, obtained by logging in.
        :param int exp_id: Experiment ID as specified in the url.
        :param int N: The number of simulation draws.
        :param bool log_stats: Flag for logging the results in the database (default is False)
        :param bool verbose: Flag for displaying the results in the returning JSON object (default is True)
        :param int seed (optional): Set numpy seed.
        :returns: A JSON indicating success when verbose flag is False, and a JSON with all the data when verbose flag is True.
        :raises 400: If the experiment does not belong to this user or the exp_id is wrong.
        :raises 401: If user is not logged in or if there is no secure cookie available.
        """
        if self.get_current_user():
            if self.validate_user_experiment(exp_id):

                N = int(self.get_argument("N", default=1000))
                log_stats = self.get_argument("log_stats", default=False)
                verbose = self.get_argument("verbose", default=True)
                seed = self.get_argument("seed", default=None)
                if seed is None:
                    seed = np.random.randint(2**32 - 1, dtype=np.uint32)
                if verbose == "True":
                    verbose = True
                else:
                    verbose = False
                if log_stats == "True":
                    log_stats = True
                else:
                    log_stats = False

                __EXP__ = Experiment(exp_id)

                data = {}

                with self.temp_seed(int(seed)):
                    for i in range(N):
                        # Generate context
                        context = __EXP__.run_context_code()

                        # Get action
                        action = __EXP__.run_action_code(context)

                        # Generate reward
                        reward = __EXP__.run_get_reward_code(context, action)

                        # Set reward
                        __EXP__.run_reward_code(context, action, reward)

                        # Get theta
                        theta = __EXP__.get_theta()

                        # Save stats
                        data[str(i)] = {
                            'context': context.copy(),
                            'action': action.copy(),
                            'reward': reward.copy(),
                            'theta': theta.copy()
                        }

                        context.clear()
                        action.clear()
                        reward.clear()

                if log_stats == True:
                    __EXP__.log_simulation_data(data.copy())
                data_tmp = data.copy()
                data.clear()

                if verbose == True:
                    self.write(
                        json.dumps({
                            'simulate': 'success',
                            'experiment': exp_id,
                            'data': data_tmp
                        }))
                else:
                    self.write(
                        json.dumps({
                            'simulate': 'success',
                            'experiment': exp_id,
                            'theta': theta
                        }))
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
Example #6
0
    def get(self, exp_id):
        """ Simulate your experiment on a simple model
        The model that is drawn from is:

        y = -(x - c)**2 + c2 + rnorm(mu,var)

        Currently there is no context. Make sure that the action of your
        experiment results in:

        {"x" : x}

        This is how the model currently expects your action to be formulated.
        This might become more flexible later on.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        |http://example.com/eval/5/simulate?key=XXX&N=10&c=5&c2=10&mu=0&var=1|
        +--------------------------------------------------------------------+

        :param int exp_id: Experiment ID as specified in the url
        :param string key: The key corresponding to the experiment
        :param int N: The number of simulation draws
        :param int c: The size of the parabola
        :param int c2: The height of the parabola
        :param int mu: The mean of the noise on the model
        :param int var: The variance of the noise on the model
        :param string log_stats: Flag for logging the results in the database
        
        :returns: A JSON of the form: {"simulate":"success"}
        :raises AuthError: 401 Invalid Key

        """

        key = self.get_argument("key", default = False)
        
        # Number of draws
        N = int(self.get_argument("N", default = 1000))

        log_stats = self.get_argument("log_stats", default = True)

        # Parameterset for the simulator
        c = float(self.get_argument("c", default = 5))
        c2 = float(self.get_argument("c2", default = 10))
        mu = float(self.get_argument("mu", default = 0))
        var = float(self.get_argument("var", default = .1))

        if not key:
            self.set_status(401)
            self.write("Key not given")
            return

        __EXP__ = Experiment(exp_id, key)

        rewards = np.array([0])
        reward_over_time = np.array([])
        regret = np.array([0])

        if __EXP__.is_valid():
            for i in range(N):
                # Generate context
                context = {}

                # Get action

                action = __EXP__.run_action_code(context)

                # Generate reward

                y = -(action["x"] - c)**2 + c2 + np.random.normal(mu, var)
                #y = 15 + 8*action["x"] + 10*action["x"]**2 + np.random.normal(mu, var)

                reward = {"y" : y}

                # Set reward
                __EXP__.run_reward_code(context, action, reward)
                
                # Save stats
                rewards = np.append(rewards, y)
                tmp_rot = (rewards[-1] + y) / (i+1)
                reward_over_time = np.append(reward_over_time, tmp_rot)
                regret = np.append(regret, (regret[-1] + (c2 - y)))

                #self.write("n = {}, Regret is: {}, reward = {} <br>".format(i,regret[-1], rewards[-1]))


            # Now save the data together with a timestamp in the logs
            # To read out the Numpy array data out again, use array =
            # pickle.loads(record['feature'])

            # FOR FUTURE, the json_tricks package might be interesting
            if log_stats == True:
                print("Logging data")
                __EXP__.log_data({
                    "type" : "evaluation",
                    "time" : int(time.time()),
                    "experiment" : exp_id,
                    "N" : N,
                    "c" : c,
                    "c2" : c2,
                    "rewards" : Binary(_pickle.dumps(rewards, protocol = 2), subtype = 128),
                    "reward_over_time" : Binary(_pickle.dumps(reward_over_time, protocol = 2), subtype = 128),
                    "regret" : Binary(_pickle.dumps(regret, protocol = 2), subtype = 128)
                    })

                self.write(json.dumps({'simulate':'success','experiment':exp_id}))
        else:
            self.set_status(401)
            self.write("Key is not valid for this experiment")
            return