Exemple #1
0
    def _process_query(self, endpoint_name, start):
        try:
            self._add_CORS_header()

            if not self.request.body:
                self.request.body = {}

            # extract request data explicitly for caching purpose
            request_json = self.request.body.decode('utf-8')

            # Sanitize input data
            data = _sanitize_request_data(simplejson.loads(request_json))
        except Exception as e:
            err_msg = format_exception(e, "Invalid Input Data")
            self.error_out(400, err_msg)
            return

        try:
            (po_name,
             all_endpoint_names) = self._get_actual_model(endpoint_name)

            # po_name is None if self.py_handler.ps.query_objects.get(
            # endpoint_name) is None
            if not po_name:
                log_error("UnknownURI", endpoint_name=endpoint_name)
                self.error_out(404,
                               'UnknownURI',
                               info="Endpoint '%s' does not exist" %
                               endpoint_name)
                return

            po_obj = self.py_handler.ps.query_objects.get(po_name)

            if not po_obj:
                log_error("UnknownURI", endpoint_name=po_name)
                self.error_out(404,
                               'UnknownURI',
                               info="Endpoint '%s' does not exist" % po_name)
                return

            if po_name != endpoint_name:
                log_info("Querying actual model", po_name=po_name)

            uid = _get_uuid()

            # record query w/ request ID in query log
            qry = Query(po_name, request_json)
            gls_time = 0
            # send a query to PythonService and return
            (gls_time, result) = self._handle_result(po_name, data, qry, uid)

            # if error occurred, GLS time is None.
            if not gls_time:
                return

        except Exception as e:
            err_msg = format_exception(e, 'process query')
            self.error_out(500, 'Error processing query', info=err_msg)
            return
Exemple #2
0
    def _process_query(self, endpoint_name, start):
        try:
            self._add_CORS_header()

            if not self.request.body:
                self.request.body = {}

            # extract request data explicitly for caching purpose
            request_json = self.request.body.decode('utf-8')

            # Sanitize input data
            data = _sanitize_request_data(simplejson.loads(request_json))
        except Exception as e:
            err_msg = format_exception(e, "Invalid Input Data")
            self.error_out(400, err_msg)
            return

        try:
            (po_name, all_endpoint_names) = self._get_actual_model(endpoint_name)

            ## po_name is None if self.py_handler.ps.query_objects.get(endpoint_name) is None
            if not po_name:
                log_error("UnknownURI", endpoint_name = endpoint_name)
                self.error_out(404, 'UnknownURI', info="Endpoint '%s' does not exist" % endpoint_name)
                return

            po_obj = self.py_handler.ps.query_objects.get(po_name)

            if not po_obj:
                log_error("UnknownURI", endpoint_name = po_name)
                self.error_out(404, 'UnknownURI',info="Endpoint '%s' does not exist" % po_name)
                return

            if po_name != endpoint_name:
                log_info("Querying actual model", po_name = po_name)

            uid = _get_uuid()

            # record query w/ request ID in query log
            qry = Query(po_name, request_json)
            gls_time = 0
            # send a query to PythonService and return
            (gls_time, result) = self._handle_result(po_name, data, qry, uid)

            # if error occurred, GLS time is None.
            if not gls_time:
                return

        except Exception as e:
            err_msg = format_exception(e, 'process query')
            self.error_out(500, 'Error processing query', info = err_msg)
            return
Exemple #3
0
    def query(self, object_uri, params, uid):
        """Execute a QueryObject query"""
        try:
            if not isinstance(params, dict) and not isinstance(params, list):
                return QueryFailed(
                    uri=object_uri,
                    error="Query parameter needs to be a dictionary or a list. Given value is of type %s." % type(params))

            obj_info = self.query_objects.get(object_uri)
            if obj_info:
                pred_obj = obj_info['endpoint_obj']
                version = obj_info['version']

                if not pred_obj:
                    return QueryFailed(uri=object_uri,
                        error= "There is no query object associated to the endpoint: %s" % object_uri)

                if isinstance(params, dict):
                    result = pred_obj.query(**params)
                else:
                    result = pred_obj.query(*params)

                return QuerySuccessful(object_uri, version, result)
            else:
                return UnknownURI(object_uri)
        except Exception as e:
            err_msg = format_exception(e, '/query')
            log_error(err_msg)
            return QueryFailed(uri=object_uri, error=err_msg)
Exemple #4
0
    def query(self, object_uri, params, uid):
        """Execute a QueryObject query"""
        try:
            if not isinstance(params, dict) and not isinstance(params, list):
                return QueryFailed(
                    uri=object_uri,
                    error=
                    "Query parameter needs to be a dictionary or a list. Given value is of type %s."
                    % type(params))

            obj_info = self.query_objects.get(object_uri)
            if obj_info:
                pred_obj = obj_info['endpoint_obj']
                version = obj_info['version']

                if not pred_obj:
                    return QueryFailed(
                        uri=object_uri,
                        error=
                        "There is no query object associated to the endpoint: %s"
                        % object_uri)

                if isinstance(params, dict):
                    result = pred_obj.query(**params)
                else:
                    result = pred_obj.query(*params)

                return QuerySuccessful(object_uri, version, result)
            else:
                return UnknownURI(object_uri)
        except Exception as e:
            err_msg = format_exception(e, '/query')
            log_error(err_msg)
            return QueryFailed(uri=object_uri, error=err_msg)
Exemple #5
0
def init_model_evaluator(settings):
    '''
    This will go through all models that the service currently have and initialize them.
    '''
    try:
        tabpy = settings['tabpy']
        py_handler = settings['py_handler']

        existing_pos = tabpy.get_endpoints()
        
        for (object_name, obj_info) in (existing_pos.items() if sys.version_info > (3,0) else existing_pos.iteritems()):
            object_version = obj_info['version']
            object_type = obj_info['type']
            object_path = get_query_object_path(
                os.environ['TABPY_STATE_PATH'],
                object_name, object_version)

            log_info('Load endpoint: %s, version: %s, type: %s' % \
                                (object_name, object_version, object_type))
            if object_type == 'alias':
                msg = LoadObject(object_name, obj_info['target'], object_version,
                    False, 'alias')
            else:
                local_path = object_path                    
                msg = LoadObject(object_name, local_path, object_version,
                            False, object_type)
            py_handler.manage_request(msg)

    except Exception as e:
        err_msg = format_exception(e, "Exception encounted when initializing evaluator host:%s" % host_to_initialize)
        log_error(err_msg)
Exemple #6
0
def init_model_evaluator(settings):
    '''
    This will go through all models that the service currently have and initialize them.
    '''
    try:
        tabpy = settings['tabpy']
        py_handler = settings['py_handler']

        existing_pos = tabpy.get_endpoints()
        
        for (object_name, obj_info) in (existing_pos.items() if sys.version_info > (3,0) else existing_pos.iteritems()):
            object_version = obj_info['version']
            object_type = obj_info['type']
            object_path = get_query_object_path(
                settings['state_file_path'],
                object_name, object_version)

            log_info('Load endpoint: %s, version: %s, type: %s' % \
                                (object_name, object_version, object_type))
            if object_type == 'alias':
                msg = LoadObject(object_name, obj_info['target'], object_version,
                    False, 'alias')
            else:
                local_path = object_path                    
                msg = LoadObject(object_name, local_path, object_version,
                            False, object_type)
            py_handler.manage_request(msg)

    except Exception as e:
        err_msg = format_exception(e, "Exception encounted when initializing evaluator host:%s" % host_to_initialize)
        log_error(err_msg)
Exemple #7
0
    def put(self, name):
        try:
            if not self.request.body:
                self.error_out(400, "Input body cannot be empty")
                self.finish()
                return
            try:
                request_data = simplejson.loads(self.request.body.decode('utf-8'))
            except:
                self.error_out(400, "Failed to decode input body")
                self.finish()
                return

            # check if endpoint exists
            endpoints = self.tabpy.get_endpoints(name)
            if len(endpoints) == 0:
                self.error_out(404,
                               "endpoint %s does not exist." % name)
                self.finish()
                return

            new_version = int(endpoints[name]['version']) + 1
            log_info('Endpoint info: %s' % request_data)
            err_msg = yield self._add_or_update_endpoint('update', name, new_version, request_data)
            if err_msg:
                self.error_out(400, err_msg)
                self.finish()
            else:
                self.write(self.tabpy.get_endpoints(name))
                self.finish()

        except Exception as e:
            err_msg = format_exception(e, 'update_endpoint')
            self.error_out(500, err_msg)
            self.finish()
Exemple #8
0
    def put(self, name):
        try:
            if not self.request.body:
                self.error_out(400, "Input body cannot be empty")
                self.finish()
                return
            try:
                request_data = simplejson.loads(self.request.body.decode('utf-8'))
            except:
                self.error_out(400, "Failed to decode input body")
                self.finish()
                return

            # check if endpoint exists
            endpoints = self.tabpy.get_endpoints(name)
            if len(endpoints) == 0:
                self.error_out(404,
                               "endpoint %s does not exist." % name)
                self.finish()
                return
            
            new_version = int(endpoints[name]['version']) + 1
            log_info('Endpoint info: %s' % request_data)
            err_msg = yield self._add_or_update_endpoint('update', name, new_version, request_data)
            if err_msg:
                self.error_out(400, err_msg)
                self.finish()
            else:
                self.write(self.tabpy.get_endpoints(name))
                self.finish()

        except Exception as e:
            err_msg = format_exception(e, 'update_endpoint')
            self.error_out(500, err_msg)
            self.finish()
Exemple #9
0
    def post(self):
        try:
            body = simplejson.loads(self.request.body.decode('utf-8'))
            if 'script' not in body:
                self.error_out(400, 'Script is empty.')
                return

            # Transforming user script into a proper function.
            user_code = body['script']
            arguments = None
            arguments_str = ''
            if 'data' in body:
                arguments = body['data']

            if arguments is not None:
                if not isinstance(arguments, dict):
                    self.error_out(400, 'Script parameters need to be provided as a dictionary.')
                    return
                else:
                    arguments_expected = []
                    for i in range(1, len(arguments.keys())+1):
                        arguments_expected.append('_arg'+str(i))
                    if sorted(arguments_expected)==sorted(arguments.keys()):
                        arguments_str = ', ' + ', '.join(arguments.keys())
                    else:
                        self.error_out(400, 'Variables names should follow the format _arg1, _arg2, _argN')
                        return


            function_to_evaluate = 'def _user_script(tabpy' + arguments_str + '):\n'
            for u in user_code.splitlines():
                function_to_evaluate += ' ' + u + '\n'

            log_info("function to evaluate=%s" % function_to_evaluate)


            result = yield self.call_subprocess(function_to_evaluate, arguments)
            if result is None:
                self.error_out(400, 'Error running script. No return value')
            else:
                self.write(simplejson.dumps(result))
                self.finish()

        except Exception as e:
            err_msg = "%s : " % e.__class__.__name__
            err_msg += "%s" % str(e)
            if err_msg!="KeyError : 'response'":
                err_msg = format_exception(e, 'POST /evaluate')
                self.error_out(500, 'Error processing script', info = err_msg)
            else:
                self.error_out(404, 'Error processing script',
                       info="The endpoint you're trying to query did not respond. Please make sure the endpoint exists and the correct set of arguments are provided.")
Exemple #10
0
def on_state_change(settings):
    try:
        tabpy = settings['tabpy']
        py_handler = settings['py_handler']

        log_info("Loading state from state file")
        config = util._get_state_from_file(settings['state_file_path'])
        new_ps_state = TabPyState(config=config)

        (has_changes,
         changes) = _get_latest_service_state(settings, new_ps_state)
        if not has_changes:
            log_info("Nothing changed, return.")
            return

        new_endpoints = new_ps_state.get_endpoints()
        for object_name in changes['endpoints']:
            (object_type, object_version,
             object_path) = changes['endpoints'][object_name]

            if not object_path and not object_version:  # removal
                log_info("Removing object", uri=object_name)

                py_handler.manage_request(DeleteObjects([object_name]))

                cleanup_endpoint_files(object_name, settings['upload_dir'])

            else:
                endpoint_info = new_endpoints[object_name]
                is_update = object_version > 1
                if object_type == 'alias':
                    msg = LoadObject(object_name, endpoint_info['target'],
                                     object_version, is_update, 'alias')
                else:
                    local_path = object_path
                    msg = LoadObject(object_name, local_path, object_version,
                                     is_update, object_type)

                py_handler.manage_request(msg)
                wait_for_endpoint_loaded(py_handler, object_name)

                # cleanup old version of endpoint files
                if object_version > 2:
                    cleanup_endpoint_files(
                        object_name, settings['upload_dir'],
                        [object_version, object_version - 1])

    except Exception as e:
        err_msg = format_exception(e, 'on_state_change')
        log_warning("Error submitting update model request", error=err_msg)
Exemple #11
0
    def post(self):
        try:
            body = simplejson.loads(self.request.body.decode('utf-8'))
            if 'script' not in body:
                self.error_out(400, 'Script is empty.')
                return

            # Transforming user script into a proper function.
            user_code = body['script']
            arguments = None
            arguments_str = ''
            if 'data' in body:
                arguments = body['data']

            if arguments is not None:
                if not isinstance(arguments, dict):
                    self.error_out(
                        400,
                        'Script parameters need to be provided as a dictionary.'
                    )
                    return
                else:
                    arguments_expected = []
                    for i in range(1, len(arguments.keys()) + 1):
                        arguments_expected.append('_arg' + str(i))
                    if sorted(arguments_expected) == sorted(arguments.keys()):
                        arguments_str = ', ' + ', '.join(arguments.keys())
                    else:
                        self.error_out(
                            400,
                            'Variables names should follow the format _arg1, _arg2, _argN'
                        )
                        return

            function_to_evaluate = 'def _user_script(tabpy' + arguments_str + '):\n'
            for u in user_code.splitlines():
                function_to_evaluate += ' ' + u + '\n'

            log_info("function to evaluate=%s" % function_to_evaluate)
            result = yield self.call_subprocess(function_to_evaluate,
                                                arguments)
            if result is None:
                self.error_out(400, 'Error running script. No return value')
            else:
                self.write(simplejson.dumps(result))
                self.finish()

        except Exception as e:
            err_msg = format_exception(e, 'POST /evaluate')
            self.error_out(500, 'Error processing script', info=err_msg)
Exemple #12
0
def on_state_change(settings):
    try:
        tabpy = settings['tabpy']
        py_handler = settings['py_handler']

        log_info("Loading state from state file")
        state_file_path = os.environ['TABPY_STATE_PATH']
        config = util._get_state_from_file(state_file_path)
        new_ps_state = TabPyState(config=config)

        (has_changes, changes) = _get_latest_service_state(settings, new_ps_state)
        if not has_changes:
            log_info("Nothing changed, return.")
            return

        new_endpoints = new_ps_state.get_endpoints()
        for object_name in changes['endpoints']:
            (object_type, object_version, object_path) = changes['endpoints'][object_name]

            if not object_path and not object_version:  # removal
                log_info("Removing object", uri=object_name)

                py_handler.manage_request(DeleteObjects([object_name]))

                cleanup_endpoint_files(object_name)

            else:
                endpoint_info = new_endpoints[object_name]
                is_update = object_version > 1
                if object_type == 'alias':
                    msg = LoadObject(object_name, endpoint_info['target'], object_version,
                                       is_update, 'alias')
                else:
                    local_path = object_path
                    msg = LoadObject(object_name, local_path, object_version,
                                       is_update, object_type)

                py_handler.manage_request(msg)
                wait_for_endpoint_loaded(py_handler, object_name)

                # cleanup old version of endpoint files
                if object_version > 2:
                    cleanup_endpoint_files(object_name, [object_version, object_version - 1])

    except Exception as e:
        err_msg = format_exception(e, 'on_state_change')
        log_warning("Error submitting update model request", error=err_msg)
Exemple #13
0
    def post(self):
        try:
            if not self.request.body:
                self.error_out(400, "Input body cannot be empty")
                self.finish()
                return

            try:
                request_data = simplejson.loads(
                    self.request.body.decode('utf-8'))
            except:
                self.error_out(400, "Failed to decode input body")
                self.finish()
                return

            if 'name' not in request_data:
                self.error_out(400, "name is required to add an endpoint.")
                self.finish()
                return

            name = request_data['name']

            # check if endpoint already exist
            if name in self.tabpy.get_endpoints():
                self.error_out(400, "endpoint %s already exists." % name)
                self.finish()
                return

            err_msg = yield self._add_or_update_endpoint(
                'add', name, 1, request_data)
            if err_msg:
                self.error_out(400, err_msg)
            else:
                self.set_status(201)
                self.write(self.tabpy.get_endpoints(name))
                self.finish()

        except Exception as e:
            err_msg = format_exception(e, '/add_endpoint')
            self.error_out(500, "error adding endpoint", err_msg)
            self.finish()
            return
Exemple #14
0
    def post(self):
        try:
            if not self.request.body:
                self.error_out(400, "Input body cannot be empty")
                self.finish()
                return

            try:
                request_data = simplejson.loads(self.request.body.decode('utf-8'))
            except:
                self.error_out(400, "Failed to decode input body")
                self.finish()
                return

            if 'name' not in request_data:
                self.error_out(400,
                               "name is required to add an endpoint.")
                self.finish()
                return

            name = request_data['name']

            # check if endpoint already exist
            if name in self.tabpy.get_endpoints():
                self.error_out(400, "endpoint %s already exists." % name)
                self.finish()
                return

            err_msg = yield self._add_or_update_endpoint('add', name, 1, request_data)
            if err_msg:
                self.error_out(400, err_msg)
            else:
                self.set_status(201)
                self.write(self.tabpy.get_endpoints(name))
                self.finish()

        except Exception as e:
            err_msg = format_exception(e, '/add_endpoint')
            self.error_out(500, "error adding endpoint", err_msg)
            self.finish()
            return
Exemple #15
0
    def delete(self, name):
        try:
            endpoints = self.tabpy.get_endpoints(name)
            if len(endpoints) == 0:
                self.error_out(404,
                               "endpoint %s does not exist." % name)
                self.finish()
                return

            # update state
            try:
                endpoint_info = self.tabpy.delete_endpoint(name)
            except Exception as e:
                self.error_out(400,
                               "Error when removing endpoint: %s" % e.message)
                self.finish()
                return

            # delete files
            if endpoint_info['type'] != 'alias':
                delete_path = get_query_object_path(self.settings['state_file_path'], name, None)
                try:
                    yield self._delete_po_future(delete_path)
                except Exception as e:
                    self.error_out(400,
                                   "Error while deleting: %s" % e)
                    self.finish()
                    return

            self.set_status(204)
            self.finish()

        except Exception as e:
            err_msg = format_exception(e, 'delete endpoint')
            self.error_out(500, err_msg)
            self.finish()

        on_state_change(self.settings)
Exemple #16
0
    def delete(self, name):
        try:
            endpoints = self.tabpy.get_endpoints(name)
            if len(endpoints) == 0:
                self.error_out(404,
                               "endpoint %s does not exist." % name)
                self.finish()
                return

            # update state
            try:
                endpoint_info = self.tabpy.delete_endpoint(name)
            except Exception as e:
                self.error_out(400,
                               "Error when removing endpoint: %s" % e.message)
                self.finish()
                return

            # delete files
            if endpoint_info['type'] != 'alias':
                delete_path = get_query_object_path(self.settings['state_file_path'], name, None)
                try:
                    yield self._delete_po_future(delete_path)
                except Exception as e:
                    self.error_out(400,
                                   "Error while deleting: %s" % e)
                    self.finish()
                    return

            self.set_status(204)
            self.finish()

        except Exception as e:
            err_msg = format_exception(e, 'delete endpoint')
            self.error_out(500, err_msg)
            self.finish()

        on_state_change(self.settings)