def delete(self, name): if self.should_fail_with_not_authorized(): self.fail_with_not_authorized() return self.logger.log( logging.DEBUG, f'Processing DELETE for /endpoints/{name}') try: endpoints = self.tabpy_state.get_endpoints(name) if len(endpoints) == 0: self.error_out(404, f'endpoint {name} does not exist.') self.finish() return # update state try: endpoint_info = self.tabpy_state.delete_endpoint(name) except Exception as e: self.error_out(400, f'Error when removing endpoint: {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, f'Error while deleting: {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, self.tabpy_state, self.python_service, self.logger)
def delete(self, name): if self.should_fail_with_auth_error() != AuthErrorStates.NONE: self.fail_with_auth_error() return self.logger.log(logging.DEBUG, f"Processing DELETE for /endpoints/{name}") try: endpoints = self.tabpy_state.get_endpoints(name) if len(endpoints) == 0: self.error_out(404, f"endpoint {name} does not exist.") self.finish() return # update state try: endpoint_info = self.tabpy_state.delete_endpoint(name) except Exception as e: self.error_out(400, f"Error when removing endpoint: {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, f"Error while deleting: {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, self.tabpy_state, self.python_service, self.logger)
def _add_or_update_endpoint(self, action, name, version, request_data): ''' Add or update an endpoint ''' self.logger.log(logging.DEBUG, f'Adding/updating model {name}...') _name_checker = _compile(r'^[a-zA-Z0-9-_\s]+$') if not isinstance(name, str): msg = 'Endpoint name must be a string' self.logger.log(logging.CRITICAL, msg) raise TypeError(msg) if not _name_checker.match(name): raise gen.Return('endpoint name can only contain: a-z, A-Z, 0-9,' ' underscore, hyphens and spaces.') if self.settings.get('add_or_updating_endpoint'): msg = ('Another endpoint update is already in progress' ', please wait a while and try again') self.logger.log(logging.CRITICAL, msg) raise RuntimeError(msg) request_uuid = random_uuid() self.settings['add_or_updating_endpoint'] = request_uuid try: description = (request_data['description'] if 'description' in request_data else None) if 'docstring' in request_data: docstring = str( bytes(request_data['docstring'], "utf-8").decode('unicode_escape')) else: docstring = None endpoint_type = (request_data['type'] if 'type' in request_data else None) methods = (request_data['methods'] if 'methods' in request_data else []) dependencies = (request_data['dependencies'] if 'dependencies' in request_data else None) target = (request_data['target'] if 'target' in request_data else None) schema = (request_data['schema'] if 'schema' in request_data else None) src_path = (request_data['src_path'] if 'src_path' in request_data else None) target_path = get_query_object_path( self.settings[SettingsParameters.StateFilePath], name, version) self.logger.log(logging.DEBUG, f'Checking source path {src_path}...') _path_checker = _compile(r'^[\\\:a-zA-Z0-9-_~\s/\.\(\)]+$') # copy from staging if src_path: if not isinstance(request_data['src_path'], str): raise gen.Return("src_path must be a string.") if not _path_checker.match(src_path): raise gen.Return( 'Endpoint source path name can only contain: ' 'a-z, A-Z, 0-9, underscore, hyphens and spaces.') yield self._copy_po_future(src_path, target_path) elif endpoint_type != 'alias': raise gen.Return("src_path is required to add/update an " "endpoint.") # alias special logic: if endpoint_type == 'alias': if not target: raise gen.Return('Target is required for alias endpoint.') dependencies = [target] # update local config try: if action == 'add': self.tabpy_state.add_endpoint(name=name, description=description, docstring=docstring, endpoint_type=endpoint_type, methods=methods, dependencies=dependencies, target=target, schema=schema) else: self.tabpy_state.update_endpoint( name=name, description=description, docstring=docstring, endpoint_type=endpoint_type, methods=methods, dependencies=dependencies, target=target, schema=schema, version=version) except Exception as e: raise gen.Return(f'Error when changing TabPy state: {e}') on_state_change(self.settings, self.tabpy_state, self.python_service, self.logger) finally: self.settings['add_or_updating_endpoint'] = None
def _add_or_update_endpoint(self, action, name, version, request_data): """ Add or update an endpoint """ self.logger.log(logging.DEBUG, f"Adding/updating model {name}...") _name_checker = _compile(r"^[a-zA-Z0-9-_\s]+$") if not isinstance(name, str): msg = "Endpoint name must be a string" self.logger.log(logging.CRITICAL, msg) raise TypeError(msg) if not _name_checker.match(name): raise gen.Return("endpoint name can only contain: a-z, A-Z, 0-9," " underscore, hyphens and spaces.") if self.settings.get("add_or_updating_endpoint"): msg = ("Another endpoint update is already in progress" ", please wait a while and try again") self.logger.log(logging.CRITICAL, msg) raise RuntimeError(msg) request_uuid = random_uuid() self.settings["add_or_updating_endpoint"] = request_uuid try: description = (request_data["description"] if "description" in request_data else None) if "docstring" in request_data: docstring = str( bytes(request_data["docstring"], "utf-8").decode("unicode_escape")) else: docstring = None endpoint_type = request_data[ "type"] if "type" in request_data else None methods = request_data[ "methods"] if "methods" in request_data else [] dependencies = (request_data["dependencies"] if "dependencies" in request_data else None) target = request_data[ "target"] if "target" in request_data else None schema = request_data[ "schema"] if "schema" in request_data else None src_path = request_data[ "src_path"] if "src_path" in request_data else None target_path = get_query_object_path( self.settings[SettingsParameters.StateFilePath], name, version) self.logger.log(logging.DEBUG, f"Checking source path {src_path}...") _path_checker = _compile(r"^[\\\:a-zA-Z0-9-_~\s/\.\(\)]+$") # copy from staging if src_path: if not isinstance(request_data["src_path"], str): raise gen.Return("src_path must be a string.") if not _path_checker.match(src_path): raise gen.Return( "Endpoint source path name can only contain: " "a-z, A-Z, 0-9, underscore, hyphens and spaces.") yield self._copy_po_future(src_path, target_path) elif endpoint_type != "alias": raise gen.Return("src_path is required to add/update an " "endpoint.") # alias special logic: if endpoint_type == "alias": if not target: raise gen.Return("Target is required for alias endpoint.") dependencies = [target] # update local config try: if action == "add": self.tabpy_state.add_endpoint( name=name, description=description, docstring=docstring, endpoint_type=endpoint_type, methods=methods, dependencies=dependencies, target=target, schema=schema, ) else: self.tabpy_state.update_endpoint( name=name, description=description, docstring=docstring, endpoint_type=endpoint_type, methods=methods, dependencies=dependencies, target=target, schema=schema, version=version, ) except Exception as e: raise gen.Return(f"Error when changing TabPy state: {e}") on_state_change(self.settings, self.tabpy_state, self.python_service, self.logger) finally: self.settings["add_or_updating_endpoint"] = None