def __call__(self, func): """This is the real decorator. Returns: A wrapped function. The wrapper does input and output validation. """ header_schema = None if self.header_params is not None: header_params = list(self.header_params) if self.request_schema: header_params.append(CONTENT_TYPE) header_schema = to_schema(header_params) path_schema = to_schema(self.path_params, required='all') query_schema = to_schema(self.query_params) self.func = func wrapped = self.wrap_with_validation( self.request_schema, self.response_schema, header_schema, path_schema, query_schema, ) _verify_parameters(self.path, path_schema) self.operation_id = func.__module__ + "." + func.__name__ def _mandatory_parameter_names(*_params): schema: Type[Schema] req = [] for schema in _params: if not schema: continue for name, field in schema().declared_fields.items(): if field.required: req.append(field.attribute or name) return tuple(sorted(req)) params = _mandatory_parameter_names(header_schema, path_schema, query_schema) # Call to see if a Rule can be constructed. Will throw an AttributeError if not possible. _ = self.default_path ENDPOINT_REGISTRY.add_endpoint(self, params) if not self.output_empty and self.response_schema is None: raise ValueError( f"{self.operation_id}: 'response_schema' required when output will be sent." ) if self.output_empty and self.response_schema: raise ValueError( f"{self.operation_id}: If `output_empty` is True, " "'response_schema' may not be used.") self.wrapped = wrapped return self.wrapped
def link_endpoint( module_name: str, rel: LinkRelation, parameters: Dict[str, str], ) -> LinkType: """Link to a specific endpoint by name. Args: module_name: The Python dotted path name, where the endpoint to be linked to, is defined. rel: The endpoint's rel-name. parameters: A dict, mapping parameter names to their desired values. e.g. if the link should have "/foo/{baz}" rendered to "/foo/bar", this mapping should be {'baz': 'bar'}. """ endpoint = ENDPOINT_REGISTRY.lookup(module_name, rel, parameters) return link_rel( href=endpoint["endpoint"].make_url(parameters), rel=endpoint["rel"], method=endpoint["method"], )
def __call__(self, func: WrappedFunc) -> WrappedEndpoint: """This is the real decorator. Returns: A wrapped function. The wrapper does input and output validation. """ self.operation_id = func.__module__ + "." + func.__name__ if self.method in ("get", "delete") and self.request_schema: raise ValueError( f"According to the OpenAPI 3 spec, consumers SHALL ignore request bodies on " f"{self.method.upper()!r}. Please use another request method for the endpont: " f"{self.operation_id} " "See: https://swagger.io/specification/#operation-object") header_schema = None if self.header_params is not None: header_params = list(self.header_params) if self.request_schema: header_params.append(CONTENT_TYPE) header_schema = to_schema(header_params) path_schema = to_schema(self.path_params) query_schema = to_schema(self.query_params) response_schema = to_schema(self.response_schema) request_schema = to_schema(self.request_schema) self.func = func wrapped = self.wrapped = self.wrap_with_validation( request_schema, response_schema, header_schema, path_schema, query_schema, ) _verify_parameters(self.path, path_schema) def _mandatory_parameter_names(*_params): schema: Type[Schema] req = [] for schema in _params: if not schema: continue for name, field in schema().declared_fields.items(): if field.required: req.append(field.attribute or name) return tuple(sorted(req)) params = _mandatory_parameter_names(header_schema, path_schema, query_schema) # Call to see if a Rule can be constructed. Will throw an AttributeError if not possible. _ = self.default_path ENDPOINT_REGISTRY.add_endpoint(self, params) if (self.content_type == "application/json" and not self.output_empty and self.response_schema is None): raise ValueError( f"{self.operation_id}: 'response_schema' required when output will be sent." ) if self.output_empty and self.response_schema: raise ValueError( f"{self.operation_id}: If `output_empty` is True, " "'response_schema' may not be used.") return WrappedEndpoint(self, wrapped)