def __init__(self, schema, base_path=None, default_policy=None): schema = 'python://' + schema.strip('/') try: parser = ResolvingParser(schema, backend='openapi-spec-validator') except (FileNotFoundError, IsADirectoryError): raise NotFoundError('OpenAPI Schema not found') self._spec = parser.specification self._paths = self._spec.get('paths', []) self._policy = {} if base_path: self._spec['basePath'] = base_path.rstrip('/') self._request_body = {} self._response_body = {} self._request_params = {} self._operation_ids = {} self._routes = [] self._schemas = [] for path in self._paths: route = self.base_path + '/' + path.strip('/') for method in self._paths[path]: op_id = self._paths[path][method].get('operationId') params = self._paths[path][method].get('parameters', []) resps = self._paths[path][method].get('responses', []) if op_id: if op_id not in self._operation_ids: self._operation_ids[op_id] = [] self._request_params[op_id] = {} self._request_body[op_id] = None self._response_body[op_id] = {} for param in params: if param.get('in', '') == 'query': p_name = param.get('name') if p_name: self._request_params[op_id][p_name] = param elif param.get('in', '') == 'body': self._request_body[op_id] = param for resp in resps: self._response_body[op_id][resp] = resps[resp] _route = ( method, route, op_id, default_policy, ) self._routes.append(_route) if op_id not in self._operation_ids: self._operation_ids[op_id] = [] self._operation_ids[op_id].append(route)
def get_zone_slot(self, zone): """Get zone slot. Args: zone (str): Exisiting Zone name. """ try: return self._zone_index[zone] except KeyError: raise NotFoundError("Zone not found '%s'" % zone) from None
def delete_node(self, node_id): """Delete node. Args: node_id (str): Unique Node Identifier. """ try: zone, slot = self._node_index[node_id] except KeyError: raise NotFoundError('Node not found') from None del self._node_index[node_id] self._nodes[slot] = None self._zones[zone][1].remove(slot)
def update_node(self, node_id, zone=None, weight=None, **kwargs): """Update node. Args: node_id (str): Unique Node Identifier. zone (str): Exisiting zone name. weight (float/int): Weight for element. **kwargs: Arbitrary options for nodes. Returns: dict: Node with property value pairs. """ node = self.get_node(node_id, raw=True) if node: if weight: weight = parse_weight(weight) node['weight'] = weight if zone: zone = parse_zone(zone) new_zone_slot = self.get_zone_slot(zone) if new_zone_slot != node['zone']: zone = self.get_zone_slot(zone) slot = self._take_empty_node_slot() old_zone_slot, old_node_slot = self._node_index[node_id] self._zones[old_zone_slot][1][old_node_slot] = None node['zone'] = new_zone_slot node['node_slot'] = slot self._node_index[node_id] = ( zone, slot, ) self._nodes[slot] = node for kwarg in kwargs: node[kwarg] = kwargs[kwarg] return node else: raise NotFoundError("Update node not found '%s'" % node_id)
def proc(self, method, route): try: with Timer() as elapsed: # Request Object. request = g.current_request = Request(method, route) # Response Object. response = Response() # Set Response object for request. request.response = response # Debug output if g.app.debug is True: log.info('Request %s' % request.route + ' Method %s\n' % request.method) # Process the middleware 'pre' method before routing it for middleware in register._middleware_pre: middleware(request, response) # Route Object. resource, method, r_kwargs, target, tag, cache = router.find( request.method, request.route) # Route Kwargs in requests. request.route_kwargs = r_kwargs # Set route tag in requests. request.tag = tag # If route tagged validate with policy if tag is not None: if not request.policy.validate(tag): raise AccessDeniedError("Access Denied by" + " policy '%s'" % tag) # Execute Routed View. try: # Process the middleware 'resource' after routing it for middleware in register._middleware_resource: middleware(request, response) # Run View method. if resource is not None: view = resource(request, response, **r_kwargs) if view is not None: response.write(view) else: raise NotFoundError("Route not found" + " Method '%s'" % request.method + " Route '%s'" % request.route) finally: # Process the middleware 'post' at the end for middleware in register._middleware_post: middleware(request, response) except KeyboardInterrupt: response.write('CTRL-C / KeyboardInterrupt') except Exception as exception: trace = str(traceback.format_exc()) self.handle_error(request, response, exception, trace) # Return response object. finally: # Completed Request log.info('Completed CMD', timer=elapsed())
def __call__(self, *args, **kwargs): """Application Request Interface. A clean request and response object is provided to the interface that is unique this to this thread. It passes any args and kwargs to the interface. Response object is returned. """ try: with Timer() as elapsed: # Request Object. request = g.current_request = Request(*args, **kwargs) request.env['SCRIPT_NAME'] = g.app.config.get( 'application', 'script', fallback=request.env['SCRIPT_NAME']) script_name = request.get_header('X-Script-Name') if script_name: request.env['SCRIPT_NAME'] = script_name # Response Object. response = Response(*args, **kwargs) # Set Response object for request. request.response = response # Debug output if g.app.debug is True: log.info('Request %s' % request.route + ' Method %s\n' % request.method) # Process the middleware 'pre' method before routing it for middleware in register._middleware_pre: middleware(request, response) # Route Object. resource, method, r_kwargs, target, tag, cache = router.find( request.method, request.route) # Route Kwargs in requests. request.route_kwargs = r_kwargs # Set route tag in requests. request.tag = tag # If route tagged validate with policy if tag is not None: if not request.policy.validate(tag, access_denied_raise=True): raise AccessDeniedError("Access Denied by" + " policy '%s'" % tag) # Execute Routed View. try: # Process the middleware 'resource' after routing it for middleware in register._middleware_resource: middleware(request, response) # Run View method. if resource is not None: view = resource(request, response, **r_kwargs) if view is not None: response.body(view) else: raise NotFoundError("Route not found" + " Method '%s'" % request.method + " Route '%s'" % request.route) finally: # Process the middleware 'post' at the end self.post_middleware(request, response, False) # Cache GET Response. # Only cache for GET responses! if cache > 0 and request.method == 'GET': # Get session_id if any for Caching session_id = request.cookies.get(request.host) # NOTE(cfrademan): Instruct to use cache but revalidate on, # stale cache entry. Expire remote cache in same duration # as internal cache. if session_id: response.set_header( "cache-control", "must-revalidate, private, max-age=" + str(cache)) else: response.set_header( "cache-control", "must-revalidate, max-age=" + str(cache)) # Set Vary Header # NOTE(cfrademan): Client should uniquely cache # based these request headers. response.set_header( 'Vary', 'Cookie, Accept-Encoding' + ', Content-Type') # Set Etag # NOTE(cfrademan): Needed Encoding for Different Etag. if isinstance(response._stream, bytes): encoding = request.get_header('Accept-Encoding') response.etag.set(etagger(response._stream, encoding)) # If Etag matches do not return full body use # external/user-agent cache. if (len(request.if_none_match) > 0 and request.if_none_match in response.etag): # Etag matches do not return full body. response.not_modified() # NOTE(cfrademan): Use last_modified as last resort for # external/user-agent cache. elif (request.if_modified_since and response.last_modified and request.if_modified_since <= response.last_modified): # Last-Modified matches do not return full body. response.not_modified() else: response.set_header("cache-control", "no-store, no-cache, max-age=0") # Return response object. return response() except HTTPError as exception: trace = str(traceback.format_exc()) self.handle_error(request, response, exception, trace) self.post_middleware(request, response, True) # Return response object. return response() except Error as exception: trace = str(traceback.format_exc()) self.handle_error(request, response, exception, trace) self.post_middleware(request, response, True) # Return response object. return response() except Exception as exception: trace = str(traceback.format_exc()) self.handle_error(request, response, exception, trace) self.post_middleware(request, response, True) # Return response object. return response() finally: # Completed Request log.info('Completed Request', timer=elapsed())
def __getitem__(self, name): try: return self.named_objects[name] except KeyError: raise NotFoundError("Entry Point '%s' not found" % name) from None