def _route_for_view(app, operations, view): # iterate through the routes and look for a match to the view function route = None # in the app objet for each path there's a dict with key=method and value=entry # for each operation that we're iterested in see if there's an entry for path in app.routes.keys(): # get the map of method -> entry methods = app.routes[path] # loop through the methodsoperations indicated in the specification for method in methods.keys(): # see if there's a match for the operation if len(operations) == 0 or method.lower() in operations: # there's an entry so see if the view methods match entry = methods[method] if entry.view_function == view: # store the path if this is the first match if route is None: route = path # if the view natches a different path something is wrong elif route != path: raise APISpecError( f"Duplicate route found for method {view}") # make sure we found one if route is None: raise APISpecError(f"No route found for method {view}") # success return route
def path_helper(self, operations, resource, base_path=None, **kwargs): """Path helper that allows passing a Falcon resource instance.""" resource_uri_mapping = self._generate_resource_uri_mapping(self._app) if resource not in resource_uri_mapping: raise APISpecError( "Could not find endpoint for resource {0}".format(resource)) operations.update( yaml_utils.load_operations_from_docstring(resource.__doc__) or {}) path = resource_uri_mapping[resource]["uri"] if base_path is not None: # make sure base_path accept either with or without leading slash # swagger 2 usually come with leading slash but not in openapi 3.x.x base_path = '/' + base_path.strip('/') path = re.sub(base_path, "", path, 1) methods = resource_uri_mapping[resource]["methods"] for method_name, method_handler in methods.items(): docstring_yaml = yaml_utils.load_yaml_from_docstring( method_handler.__doc__) operations[method_name] = docstring_yaml or dict() return path
def resolve_nested_schema(self, schema): """Return the OpenAPI representation of a marshmallow Schema. Adds the schema to the spec if it isn't already present. Typically will return a dictionary with the reference to the schema's path in the spec unless the `schema_name_resolver` returns `None`, in which case the returned dictoinary will contain a JSON Schema Object representation of the schema. :param schema: schema to add to the spec """ schema_instance = resolve_schema_instance(schema) schema_key = make_schema_key(schema_instance) if schema_key not in self.refs: name = self.schema_name_resolver(schema) if not name: try: json_schema = self.schema2jsonschema(schema) except RuntimeError: raise APISpecError( "Name resolver returned None for schema {schema} which is " "part of a chain of circular referencing schemas. Please" " ensure that the schema_name_resolver passed to" " MarshmallowPlugin returns a string for all circular" " referencing schemas.".format(schema=schema) ) if getattr(schema, "many", False): return {"type": "array", "items": json_schema} return json_schema name = get_unique_schema_name(self.spec.components, name) self.spec.components.schema(name, schema=schema) return self.get_ref_dict(schema_instance)
def _route_for_view(app, view): endpoint = None for route in app.routes: if route._context['callback'] == view: endpoint = route break if not endpoint: raise APISpecError('Could not find endpoint for route {0}'.format(view)) return endpoint
def _route_for_view(app, view): endpoint = None for route in app.routes: if route.callback == view: endpoint = route break if not endpoint: raise APISpecError(f"Could not find endpoint for route {view}") return endpoint
def path_helper(self, operations, urlspec, **kwargs): """Path helper that allows passing a Tornado URLSpec or tuple.""" if not isinstance(urlspec, URLSpec): urlspec = URLSpec(*urlspec) for operation in self._operations_from_methods(urlspec.handler_class): operations.update(operation) if not operations: raise APISpecError("Could not find endpoint for urlspec {}".format(urlspec)) params_method = getattr(urlspec.handler_class, list(operations.keys())[0]) operations.update(self._extensions_from_handler(urlspec.handler_class)) return self.tornadopath2openapi(urlspec, params_method)
def path_helper(self, operations, *, view, app, **kwargs): """Path helper that allows passing a chalice view function.""" if not isinstance(app, Chalice): raise APISpecError(f"app must be an instance of Chalice") # parse through the documentation string to see what operations are defined operations.update( yaml_utils.load_operations_from_docstring(view.__doc__)) # find the route for this view function route = self._route_for_view(app, operations, view) # if we didn't throw an exception then the view function handles all operations found in the docs return route
def _rule_for_view(view: str, app: Optional[Flask] = None) -> Rule: if not app: raise APISpecError("No app to find view for") view_funcs = app.view_functions endpoint = None for ept, view_func in view_funcs.items(): if hasattr(view_func, "view_class"): view_func = view_func.view_class if view_func == view: endpoint = ept if not endpoint: raise APISpecError( "Could not find endpoint for view {0}".format(view)) # WARNING: Assume 1 rule per view function for now rule = app.url_map._rules_by_endpoint[endpoint][0] return rule
def _rule_for_view(view): view_funcs = current_app.view_functions endpoint = None for ep, view_func in iteritems(view_funcs): if view_func == view: endpoint = ep if not endpoint: raise APISpecError('Could not find endpoint for view {0}'.format(view)) # WARNING: Assume 1 rule per view function for now rule = current_app.url_map._rules_by_endpoint[endpoint][0] return rule
def _deduce_path(resource, **kwargs): """Find resource path using provided API or path itself""" api = kwargs.get('api', None) if not api: # flask-restful resource url passed return kwargs.get('path') # flask-restful API passed # Require MethodView if not getattr(resource, 'endpoint', None): raise APISpecError('Flask-RESTful resource needed') if api.blueprint: # it is required to have Flask app to be able enumerate routes app = kwargs.get('app') if app: for rule in app.url_map.iter_rules(): if rule.endpoint.endswith('.' + resource.endpoint): break else: raise APISpecError( 'Cannot find blueprint resource {}'.format( resource.endpoint)) else: # Application not initialized yet, fallback to path return kwargs.get('path') else: for rule in api.app.url_map.iter_rules(): if rule.endpoint == resource.endpoint: rule.endpoint.endswith('.' + resource.endpoint) break else: raise APISpecError('Cannot find resource {}'.format( resource.endpoint)) return rule.rule
def _rule_for_view(view, app=None): if app is None: app = current_app view_funcs = app.view_functions endpoint = None for ept, view_func in view_funcs.items(): if view_func == view: endpoint = ept if not endpoint: raise APISpecError(f"Could not find endpoint for view {view}") # WARNING: Assume 1 rule per view function for now rule = app.url_map._rules_by_endpoint[endpoint][0] return rule
def path_from_urlspec(spec, urlspec, operations, **kwargs): """Path helper that allows passing a Tornado URLSpec or tuple.""" if not isinstance(urlspec, URLSpec): urlspec = URLSpec(*urlspec) if operations is None: operations = {} for operation in _operations_from_methods(urlspec.handler_class): operations.update(operation) if not operations: raise APISpecError( 'Could not find endpoint for urlspec {0}'.format(urlspec)) params_method = getattr(urlspec.handler_class, list(operations.keys())[0]) path = tornadopath2swagger(urlspec, params_method) extensions = _extensions_from_handler(urlspec.handler_class) operations.update(extensions) return Path(path=path, operations=operations)
def path_from_route(spec, route, operations, **kwargs): """Path helper that allows passing a webapp2 Route or tuple.""" if not isinstance(route, BaseRoute): route = Route(*route) if operations is None: operations = {} for operation in _operations_from_methods(route.handler): operations.update(operation) if not operations: raise APISpecError( 'Could not find endpoint for route {0}'.format(route)) params_method = getattr(route.handler, list(operations.keys())[0]) path = webapp2_path_to_swagger(route, params_method) extensions = _extensions_from_handler(route.handler) operations.update(extensions) return Path(path=path, operations=operations)
def _rule_for_view(view, app=None): view_funcs = app.view_functions endpoint = None for ept, view_func in view_funcs.items(): if hasattr(view_func, "view_class"): view_func = view_func.view_class if view_func == view: endpoint = ept if not endpoint: raise APISpecError('Could not find endpoint for view {0}'.format(view)) # WARNING: Assume 1 rule per view function for now rule = app.url_map._rules_by_endpoint[endpoint][0] return rule
def path_helper(self, path=None, operations=None, resource=None, **kwargs): resource_uri_mapping = self._generate_resource_uri_mapping() if resource not in resource_uri_mapping: raise APISpecError( "Could not find endpoint for resource {0}".format(resource)) operations = OrderedDict() if not isinstance( operations, OrderedDict) else operations path = resource_uri_mapping[resource] for method in falcon.constants.HTTP_METHODS: http_verb = method.lower() method_name = "on_" + http_verb if hasattr(resource, method_name): _method = getattr(resource, method_name).get_version(str(self.version)) docstring_yaml = self.load_yaml_from_docstring(_method.__doc__) operations[http_verb] = docstring_yaml or dict() return path
def path_helper(self, operations, resource, **kwargs): """Path helper that allows passing a Falcon resource instance.""" resource_uri_mapping = self._generate_resource_uri_mapping(self._app) if resource not in resource_uri_mapping: raise APISpecError("Could not find endpoint for resource {0}".format(resource)) operations.update(utils.load_operations_from_docstring(resource.__doc__) or {}) path = resource_uri_mapping[resource] for method in falcon.constants.HTTP_METHODS: http_verb = method.lower() method_name = "on_" + http_verb if hasattr(resource, method_name): method = getattr(resource, method_name) docstring_yaml = utils.load_yaml_from_docstring(method.__doc__) operations[http_verb] = docstring_yaml or dict() return path
def _route_for_view(current_app, view, path=Path(), operations=set()): view_funcs = current_app.routes for uri, endpoint in iteritems(view_funcs): methods = set() for method, route_entry in iteritems(endpoint): method = method.lower() if route_entry.view_function == view and (not operations or method in operations): if path.path and not path.path == uri: break else: methods.add(method) else: if methods: return uri, methods raise APISpecError( 'Could not find endpoint for view {0} and path {1}'.format( view, getattr(path, 'path', None)))
def path_from_urlspec(spec, route, operations, **kwargs): if not isinstance(route, ResourceRoute): raise Exception('Route is not ResourceRoute instance %s' % type(route)) extensions = extensions_from_handler(route.handler) if operations is None: operations = {} for operation in operations_from_methods(route.handler, extensions): operations.update(operation) if not operations: raise APISpecError( 'Could not find endpoint for route {0}'.format(route)) if isinstance(route.resource, DynamicResource): path = route.get_info()['formatter'] if isinstance(route.resource, PlainResource): path = route.get_info()['path'] return Path(path=path, operations=operations)
def path_helper(self, path=None, operations: dict = None, parameters: list = None, **kwargs): """Path helper that allows passing a Falcon resource instance.""" uri_to_method_map = self._get_uri_falcon_details_mapping() if path not in uri_to_method_map: raise APISpecError(f"Could not find handlers for path='{path}'") falcon_routing_details = uri_to_method_map[path] resource = falcon_routing_details["resource"] operations.update( yaml_utils.load_operations_from_docstring(resource.__doc__) or {}) methods = falcon_routing_details["methods"] for method_name, method_handler in methods.items(): docstring_yaml = yaml_utils.load_yaml_from_docstring( method_handler.__doc__) operations[method_name] = docstring_yaml or dict() return path
def path_helper(self, operations, resource, base_path=None, **kwargs): """Path helper that allows passing a Falcon resource instance.""" resource_uri_mapping = self._generate_resource_uri_mapping(self._app) if resource not in resource_uri_mapping: raise APISpecError("Could not find endpoint for resource {0}".format(resource)) operations.update(yaml_utils.load_operations_from_docstring(resource.__doc__) or {}) path = resource_uri_mapping[resource] if base_path is not None: # make sure base_path accept either with or without leading slash # swagger 2 usually come with leading slash but not in openapi 3.x.x base_path = '/' + base_path.strip('/') path = re.sub(base_path, "", path, 1) for method in falcon.constants.HTTP_METHODS: http_verb = method.lower() method_name = "on_" + http_verb if getattr(resource, method_name, None) is not None: method = getattr(resource, method_name) docstring_yaml = yaml_utils.load_yaml_from_docstring(method.__doc__) operations[http_verb] = docstring_yaml or dict() return path