示例#1
0
    def post(self):
        """ Add a user to StreamingBandit.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/user                                            |
        | {"username" : USERNAME, "password" : PASSWORD}                     |
        +--------------------------------------------------------------------+

        .. note:: The parameters for the POST calls have to be posted in the \
                    body as a JSON object.

        :param string username: The preferred username.
        :param string password: The preferred password.
        :returns: JSON indicating success.
        :raises 400: If user with username already exists.
        """
        if self.valid_admin():
            data = tornado.escape.json_decode(self.request.body)
            users = Users()
            username = data["username"]
            password = data["password"]
            user_id = users.create_user(username, password)
            if user_id is False:
                raise ExceptionHandler(reason="User already exists.",
                                       status_code=400)
            else:
                self.write(json.dumps({'status': 'success'}))
        else:
            raise ExceptionHandler(reason="You are not an admin.",
                                   status_code=401)
示例#2
0
    def get(self, exp_id):
        """ Retrieve a specific experiment running on this server
        
        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp/EXP_ID                                      |
        +--------------------------------------------------------------------+

        :requires: A secure cookie obtained by logging in.
        :param int exp_id: Experiment ID for the experiment that is to be retrieved.
        :returns: A JSON containing all the info for the expriment.
        :raises 401: 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):
                db = Database()
                response = db.get_one_experiment(exp_id)
                self.write(json.dumps(response))
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#3
0
    def delete(self, exp_id):
        """ Delete an experiment

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp/EXP_ID                                      |
        +--------------------------------------------------------------------+
        
        :requires: A secure cookie obtained by logging in.
        :param int exp_id: The ID of the experiment to be deleted.
        :returns: A JSON showing the deleted experiment.
        :raises 401: 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):
                db = Database()
                mongo_db = MongoLog()
                response = db.delete_experiment(exp_id)
                mongo_db.log_deleted_experiment(response)
                self.write(json.dumps(response['exp_id']))
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#4
0
    def get(self, exp_id):
        """ Get all the (manually) logged data.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/stats/EXP_ID/log?limit=10                       |
        +--------------------------------------------------------------------+

        :requires: A secure cookie, obtained by logging in.
        :param int exp_id: The experiment ID for the logs that are to be retrieved.
        :param int limit (optional): Set an optional limit to the amount of logs returned.
        :returns: A list of JSONs of the logs.
        :raises 401: 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):
                limit = int(self.get_argument("limit", default=0))
                exp = Experiment(exp_id)
                response = exp.get_log_data(limit=limit)
                self.write(json.dumps(response))
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#5
0
    def get(self, exp_id):
        """ Get the current theta.
        
        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/stats/EXP_ID/currenttheta                       |
        +--------------------------------------------------------------------+

        :requires: A secure cookie, obtained by logging in.
        :param int exp_id: The experiment ID for the theta that is to be retrieved.
        :returns: A JSON of the current theta.
        :raises 401: 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):
                exp = Experiment(exp_id)
                response = exp.get_theta()
                self.write(json.dumps(response))
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#6
0
    def get(self, exp_id):
        """ Get a summary, consisting of:
            - The number of get_action calls
            - The date of the last get_action call
            - The number of set_reward calls
            - The date of the last set_reward call

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/stats/EXP_ID/summary                            |
        +--------------------------------------------------------------------+

        :requires: A secure cookie, obtained by logging in.
        :param int exp_id: The experiment ID for the summary that are to be retrieved.
        :returns: A JSON object consisting of the summary.
        :raises 401: 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):
                exp = Experiment(exp_id)
                response = exp.get_summary()
                self.write(json.dumps(response))
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#7
0
    def post(self):
        """ Handler to login and retrieve a secure cookie.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/login                                           |
        | {"username" : USERNAME, "password" : PASSWORD}                     |
        +--------------------------------------------------------------------+

        .. note:: The parameters for the POST calls have to be posted in the \
                    body as a JSON object.

        :param string username: Experiment ID as specified in the url.
        :param string password: The number of simulation draws.
        :raises 401: If wrong username or password.
        """
        # Get config:
        users = Users()

        data = tornado.escape.json_decode(self.request.body)

        # Check:
        username = data["username"]
        password = data["password"]
        user_id = users.get_user_info(username, password)
        if user_id is not None and user_id is not False:
            self.set_secure_cookie("user", str(user_id))
            self.finish()
        else:
            # Add user feedback!
            raise ExceptionHandler(reason="Wrong username or password!",
                                   status_code=401)
示例#8
0
    def get(self, default_id):
        """ Retrieve properties of a default experiment.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp/defaults/DEFAULT_ID                         |
        +--------------------------------------------------------------------+

        :requires: A secure cookie obtained by logging in.
        :param int default_id: The ID of the default experiment.
        :returns: A JSON containing the experiment properties.
        :raises 401: If user is not logged in or if there is no secure cookie available.
        """
        if self.get_secure_cookie("user"):
            folderdata = sorted(
                [f for f in os.listdir("./defaults") if not f.startswith('.')])
            folderdata = dict(enumerate(folderdata))
            data = {}
            data["name"] = folderdata[int(default_id)]
            filenames = [
                "get_context", "get_action", "get_reward", "set_reward"
            ]
            for filename in filenames:
                if os.path.isfile("./defaults/" + data["name"] + "/" +
                                  filename + ".py"):
                    data[filename] = open("./defaults/" + data["name"] + "/" +
                                          filename + ".py").read()
            self.write(data)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#9
0
    def get(self, exp_id):
        """ Reset the theta of an experiment.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp/EXP_ID/resetexperiment?key=KEY              |
        | &theta_key=THETA_KEY&theta_value=THETA_VALUE                       |
        +--------------------------------------------------------------------+

        :requires: A secure cookie obtained by logging in.
        :param int exp_id: The experiment ID.
        :param string key: The key of the experiment.
        :param string theta_key (optional): The key for theta used when setting \
        theta in the setReward and getAction code.
        :param string theta_value (optional): The value for theta used when \
        setting theta in the setReward and getAction code.
        :raises 401: If the theta_key or theta_value does not exist or is not valid.
        :raises 401: 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_secure_cookie("user"):
            if self.validate_user_experiment(exp_id):
                key = self.get_argument("key", default=False)
                theta_key = self.get_argument("theta_key", default=None)
                theta_value = self.get_argument("theta_value", default=None)
                __EXP__ = Experiment(exp_id, key)

                status = __EXP__.delete_theta(key=theta_key, value=theta_value)
                if status >= 1:
                    self.write(json.dumps({'status': 'success'}))
                else:
                    raise ExceptionHandler(
                        reason=
                        "Theta_key or theta_value could not be validated.",
                        status_code=401)
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#10
0
    def get(self):
        """ Retrieve a list of experiments running on this server
        
        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp                                             |
        +--------------------------------------------------------------------+

        :requires: A secure cookie obtained by logging in.
        :returns: A JSON containing exp_id and name pairs.
        :raises 401: If user is not logged in or if there is no secure cookie available.
        """
        user = self.get_current_user()
        if user:
            db = Database()
            response = db.get_all_experiments(int(user))
            self.write(json.dumps(response))
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#11
0
    def get(self):
        """ Get the list with default available experiments.

        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp/defaults                                    |
        +--------------------------------------------------------------------+

        :requires: A secure cookie obtained by logging in.
        :returns: A JSON with the default experiments.
        :raises 401: If user is not logged in or if there is no secure cookie available.
        """
        if self.get_secure_cookie("user"):
            folderdata = os.listdir("./defaults")
            folderdata = [x.replace("_", " ") for x in folderdata]
            folders = dict(enumerate(folderdata))
            self.write(folders)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#12
0
    def get(self, exp_id):  # Documentation needs update to advice_id
        """ Update the parameters and set a reward for a given experiment.

        For parameters, there are two options (next to the mandatory key 
        and exp_id). The first option is supplying all the information manually, 
        meaning that you supply the following parameters:
            -   Context
            -   Action
            -   Reward

        +----------------------------------------------------------------+
        | Example                                                        |
        +================================================================+
        |http://example.com/setreward/EXP_ID?key=KEY&context=CONTEXT     |
        |&action=ACTION&reward=REWARD                                    |
        +----------------------------------------------------------------+

        When you have toggled the Advice ID in the experiment properties (second option), 
        and have received an Advice ID from the getaction call, you only have
        to supply the following parameters:
            -   Advice ID
            -   Reward

        +----------------------------------------------------------------+
        | Example                                                        |
        +================================================================+
        |http://example.com/setreward/EXP_ID?key=KEY                     |
        |&advice_id=ADVICE_ID&reward=REWARD                              |
        +----------------------------------------------------------------+

        :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 for the current update.
        :param JSON action (optional): The action for the current update.
        :param string advice_id (optional): The advice_id for the current \
        full update loop.
        :param JSON reward: The reward for the current update.
        :returns: A JSON indicating success.
        :raises 400: If key is not supplied.
        :raises 401: If the key or exp_id is invalid.
        """
        key = self.get_argument("key", default=False)

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

        __EXP__ = Experiment(exp_id, key)

        if __EXP__.is_valid():
            if self.get_argument("advice_id", default="") == "":
                context = json.loads(self.get_argument("context",
                                                       default="{}"))
                action = json.loads(self.get_argument("action", default="{}"))
            else:
                advice_id = self.get_argument("advice_id", default="")
                log = __EXP__.get_by_advice_id(advice_id)
                if log == False:
                    self.finish("Advice ID does not exist!")
                else:
                    context = log['context']
                    action = log['action']
            reward = json.loads(self.get_argument("reward", default="{}"))
            __EXP__.run_reward_code(context, action, reward)
            __EXP__.log_setreward_data(context, action, reward)

            if self.settings['debug']:
                self.write(
                    json.dumps({
                        'status': 'success',
                        'action': action,
                        'context': context,
                        'reward': reward
                    }))
            else:
                self.write(json.dumps({'status': 'success'}))
        else:
            raise ExceptionHandler(reason="Key or exp_id is invalid.",
                                   status_code=401)
示例#13
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)
示例#14
0
    def post(self):
        """ Create a new experiment
        
        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp                                             |
        |  {"name" : NAME, "get_context" : CODE, "get_action" : CODE,        |
        |   "get_reward" : CODE, "set_reward" : CODE, "advice_id" : True,    |
        |   "hourly_theta" : True, "delta_hours" : DELTA_HOURS,              |
        |   "default_reward" : DEFAULT_REWARD}                               |
        +--------------------------------------------------------------------+

        .. note:: The parameters for the POST calls have to be posted in the \
                    body as a JSON object.

        :requires: A secure cookie obtained by logging in.
        :param string name: Name of the experiment.
        :param string get_context (optional): String of python code for get context code.
        :param string get_action (optional): String of python code for get action code.
        :param string get_reward (optional): String of python code for get reward code.
        :param string set_reward (optional): String of python code for set reward code.
        :param bool hourly_theta: Bool indicating whether the state of Theta should be stored hourly. 
        :param bool advice_id: Bool indicating whether the getadvice and setreward calls should return an advice_id.
        :param int delta_hours: If advice_id is True, supply this to give the number of hours that an advice_id should be stored (between 0 and 99999).
        :param dict default_reward: If advice_id is True, supply this to give the default reward for advice_id's that are over their delta_hours limit.
        :returns: A JSON of the form: 
        .. code-block:: json
    
            { 
                "id" : The assigned experiment id, 
                "name" : The name of the experiment (checked for duplicates), 
                "error" : (Optional) error message 
                "key" : The key for the experiment 
            } 
        :raises 401: If user is not logged in or if there is no secure cookie available.
        """
        user = self.get_current_user()
        if user:
            data = tornado.escape.json_decode(self.request.body)
            exp_obj = {}
            exp_obj["user_id"] = int(user)
            exp_obj["name"] = data["name"]
            if "get_context" in data:
                exp_obj["get_context"] = data["get_context"]
            else:
                exp_obj["get_context"] = ""
            if "get_action" in data:
                exp_obj["get_action"] = data["get_action"]
            else:
                exp_obj["get_action"] = ""
            if "get_reward" in data:
                exp_obj["get_reward"] = data["get_reward"]
            else:
                exp_obj["get_reward"] = ""
            if "set_reward" in data:
                exp_obj["set_reward"] = data["set_reward"]
            else:
                exp_obj["set_reward"] = ""
            exp_obj["hourly_theta"] = data["hourly_theta"]
            exp_obj["advice_id"] = data["advice_id"]
            if exp_obj["advice_id"] in ["true", "True", "y", "yes"]:
                exp_obj["advice_id"] = True
            else:
                exp_obj["advice_id"] = False
            if exp_obj["advice_id"] is True:
                if 0 <= int(data["delta_hours"]) <= 99999:
                    exp_obj["delta_hours"] = data["delta_hours"]
                else:
                    raise ExceptionHandler(
                        reason=
                        "Supplied number for delta hours must be between 0 and 99999.",
                        status_code=400)
                exp_obj["default_reward"] = data["default_reward"]

            exp_obj["key"] = hex(random.getrandbits(42))[2:-1]

            db = Database()
            insertid = db.insert_experiment(exp_obj)

            response = {}
            response["name"] = exp_obj["name"]
            response["id"] = insertid
            response["key"] = exp_obj["key"]
            response["error"] = False
            self.write(json.dumps(response))
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#15
0
    def put(self, exp_id):
        """ Edit an experiment
       
        +--------------------------------------------------------------------+
        | Example                                                            |
        +====================================================================+
        | http://example.com/exp/EXP_ID                                      |
        | {"name" : NAME, "getcontext" : CODE, "getaction" : CODE,           |
        |   "getreward" : CODE, "setreward" : CODE, "advice_id" : True,      |
        |   "hourly_theta" : True, "delta_hours" : DELTA_HOURS,              |
        |   "default_reward" : DEFAULT_REWARD}                               |
        +--------------------------------------------------------------------+

        .. note:: The parameters for the PUT calls have to be posted in the \
                    body as a JSON object.

        :requires: A secure cookie obtained by logging in.
        :param string name: Name of the experiment.
        :param string get_context (optional): String of python code for get context code.
        :param string get_action (optional): String of python code for get action code.
        :param string get_reward (optional): String of python code for get reward code.
        :param string set_reward (optional): String of python code for set reward code.
        :param bool hourly_theta: Bool indicating whether the state of Theta should be stored hourly.
        :param bool advice_id: Bool indicating whether the getAdvice and setReward calls should return an advice_id.
        :param int delta_hours: If advice_id is True, supply this to give the number of hours that an advice_id should be stored.
        :param dict default_reward: If advice_id is True, supply this to give the default reward for advice_id's that are over their delta_hours limit.
        :returns: A JSON indicating success.
        :raises 401: 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.
        """
        user = self.get_current_user()
        if user:
            if self.validate_user_experiment(exp_id):
                data = tornado.escape.json_decode(self.request.body)
                exp_obj = {}
                exp_obj["user_id"] = int(user)
                exp_obj["name"] = data["name"]
                if "get_context" in data:
                    exp_obj["get_context"] = data["get_context"]
                else:
                    exp_obj["get_context"] = ""
                if "get_action" in data:
                    exp_obj["get_action"] = data["get_action"]
                else:
                    exp_obj["get_action"] = ""
                if "get_reward" in data:
                    exp_obj["get_reward"] = data["get_reward"]
                else:
                    exp_obj["get_reward"] = ""
                if "set_reward" in data:
                    exp_obj["set_reward"] = data["set_reward"]
                else:
                    exp_obj["set_reward"] = ""
                exp_obj["hourly_theta"] = data["hourly_theta"]
                exp_obj["advice_id"] = data["advice_id"]
                if exp_obj["advice_id"] in ["true", "True", "y", "yes"]:
                    exp_obj["advice_id"] = True
                else:
                    exp_obj["advice_id"] = False
                if exp_obj["advice_id"] is True:
                    if 0 <= int(data["delta_hours"]) <= 99999:
                        exp_obj["delta_hours"] = data["delta_hours"]
                    else:
                        raise ExceptionHandler(
                            reason=
                            "Supplied number for delta hours must be between 0 and 99999.",
                            status_code=400)
                    exp_obj["default_reward"] = data["default_reward"]

                db = Database()
                response = {}
                response["id"] = db.edit_experiment(exp_obj, exp_id)
                self.write(json.dumps(response))
            else:
                raise ExceptionHandler(
                    reason="Experiment could not be validated.",
                    status_code=401)
        else:
            raise ExceptionHandler(reason="Could not validate user.",
                                   status_code=401)
示例#16
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)