def _register_doc(self, api_renderer): root_path = self.prefix or '/' (spf, plugin_name, plugin_url_prefix) = self.spf_reg context = restplus.get_context_from_spf(self.spf_reg) if self._add_specs and self._doc: doc_endpoint_name = '{}_doc'.format(str(self._uid)) def _render_doc(*args, **kwargs): nonlocal self, api_renderer return self.render_doc(*args, api_renderer=api_renderer, **kwargs) render_doc = wraps(self.render_doc)(_render_doc) render_doc.__name__ = doc_endpoint_name r = FutureRoute(render_doc, self._doc, (), {'with_context': True}) spf._register_route_helper(r, spf, restplus, context, plugin_name, plugin_url_prefix) if self._doc != root_path: try: # app_or_blueprint.add_url_rule(self.prefix or '/', 'root', self.render_root) root_endpoint_name = '{}_root'.format(str(self._uid)) def _render_root(*args, **kwargs): nonlocal self return self.render_root(*args, **kwargs) render_root = wraps(self.render_root)(_render_root) render_root.__name__ = root_endpoint_name r = FutureRoute(render_root, root_path, (), {}) spf._register_route_helper(r, spf, restplus, context, plugin_name, plugin_url_prefix) except RouteExists: pass
def _add_new_route(self, reg, uri, handler_f, *args, **kwargs): # A user should never call this directly. # it should be called only by the AssociatedTuple assert reg in self.registrations (spf, p_name, url_prefix) = reg context = self.get_context_from_spf(reg) # This is how we add a new route _after_ the plugin is registered r = FutureRoute(handler_f, uri, args, kwargs) spf._register_route_helper(r, spf, self, context, p_name, url_prefix) return handler_f
def _register_view(self, resource, namespace, *urls, **kwargs): endpoint = kwargs.pop('endpoint', None) or camel_to_dash( resource.__name__) resource_class_args = kwargs.pop('resource_class_args', ()) resource_class_kwargs = kwargs.pop('resource_class_kwargs', {}) (spf, plugin_name, plugin_url_prefix) = self.spf_reg resource.mediatypes = self.mediatypes_method() # Hacky resource.endpoint = endpoint methods = resource.methods if methods is None or len(methods) < 1: methods = ['GET', 'OPTIONS'] else: methods = list(methods) if 'OPTIONS' not in methods: methods.append( 'OPTIONS') # Always add options, so CORS will work properly resource_func = self.output( resource.as_view_named(endpoint, self, *resource_class_args, **resource_class_kwargs)) for decorator in chain(namespace.decorators, self.decorators): resource_func = decorator(resource_func) context = restplus.get_context_from_spf(self.spf_reg) for url in urls: # If this Api has a blueprint if self.blueprint: # And this Api has been setup if self.blueprint_setup: # Set the rule to a string directly, as the blueprint is already # set up. self.blueprint_setup.add_url_rule(url, view_func=resource_func, methods=methods, **kwargs) continue else: # Set the rule to a function that expects the blueprint prefix # to construct the final url. Allows deferment of url finalization # in the case that the associated Blueprint has not yet been # registered to an application, so we can wait for the registration # prefix rule = partial(self._complete_url, url) else: # If we've got no Blueprint, just build a url with no prefix rule = self._complete_url(url, '') # Add the url to the application or blueprint r = FutureRoute(resource_func, rule, (), { 'methods': methods, 'with_context': True }) spf._register_route_helper(r, spf, restplus, context, plugin_name, plugin_url_prefix)