def make_rst(self): app = import_object(self.arguments[0]) for method, path, endpoint in get_routes(app): try: blueprint, endpoint_internal = endpoint.split('.') if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and path == static_url_path + '/(path:filename)'): continue view = app.view_functions[endpoint] docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, unicode): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) for line in http_directive(method, path, docstring): yield line
def makeRst(prefix, section, app, exampleByIdentifier, schema_store): """ Generate the sphinx documentation associated with a L{klein} application. :param bytes prefix: The URL prefix of the URLs in this application. :param unicode section: The section of documentation to generate. :param klein.Klein app: The L{klein} application to introspect. :param exampleByIdentifier: A one-argument callable that accepts an example identifier and returns an HTTP session example. :param dict schema_store: A mapping between schema paths (e.g. ``b/v1/types.json``) and the JSON schema structure. :return: A generator yielding the lines of sphinx representing the generated documentation. """ # Adapted from sphinxcontrib.autohttp.flask for route in sorted(getRoutes(app)): if route.attributes.get("private_api", False): continue data = _introspectRoute(route, exampleByIdentifier, schema_store) if data['section'] != section: continue for method in route.methods: if data['header'] is not None: yield data['header'] yield '-' * len(data['header']) yield '' body = _formatRouteBody(data, schema_store) for line in http_directive(method, prefix + route.path, body): yield line
def make_rst(self): server = TwistedServer() server._setup_klein() app = server._app if self.endpoints: routes = itertools.chain( *[get_routes(app, endpoint) for endpoint in self.endpoints]) else: routes = get_routes(app) # sort by path then method for method, paths, endpoint in sorted(routes, key=operator.itemgetter(1, 0)): if endpoint in self.undoc_endpoints: continue view = app._endpoints[endpoint] docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue if '<HTTPAPI>' not in docstring: continue docstring = self.fix_docstring(docstring) docstring = prepare_docstring(docstring) for line in http_directive(method, paths, docstring): yield line
def makeRst(prefix, app, exampleByIdentifier, schema_store): """ Generate the sphinx documentation associated with a L{klein} application. @param prefix: The URL prefix of the URLs in this application. @type prefix: L{bytes} @param app: The L{klein} application to introspect. @type app: L{klein.Klein} @param exampleByIdentifier: A one-argument callable that accepts an example identifier and returns an HTTP session example. @param dict schema_store: A mapping between schema paths (e.g. ``b/v1/types.json``) and the JSON schema structure. @return: The lines of sphinx representing the generated documentation. @rtype: A generator of L{str}s. """ # Adapted from sphinxcontrib.autohttp.flask for route in sorted(getRoutes(app)): data = _introspectRoute(route, exampleByIdentifier, schema_store) for method in route.methods: body = _formatRouteBody(data, schema_store) for line in http_directive(method, prefix + route.path, body): yield line
def make_rst(self, qref=False): app = import_object(self.arguments[0]) if self.endpoints: routes = itertools.chain(*[ get_routes(app, endpoint, self.order) for endpoint in self.endpoints ]) else: routes = get_routes(app, order=self.order) for method, paths, endpoint in routes: try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and static_url_path + '/(path:filename)' in paths): continue view = app.view_functions[endpoint] if self.modules and view.__module__ not in self.modules: continue if self.undoc_modules and view.__module__ in self.modules: continue docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) if qref == True: for path in paths: row = quickref_directive(method, path, docstring) yield row else: lines = list(http_directive(method, paths, docstring)) self.state.document.settings.env.app.emit( 'autodoc-process-docstring', 'function', None, view, {}, lines) for line in lines: yield line
def make_rst(self, qref=False): app = import_object(self.arguments[0]) if self.endpoints: routes = itertools.chain(*[get_routes(app, endpoint, self.order) for endpoint in self.endpoints]) else: routes = get_routes(app, order=self.order) for method, paths, endpoint in routes: try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and static_url_path + '/(path:filename)' in paths): continue view = app.view_functions[endpoint] if self.modules and view.__module__ not in self.modules: continue if self.undoc_modules and view.__module__ in self.modules: continue docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) if qref == True: for path in paths: row = quickref_directive(method, path, docstring) yield row else: for line in http_directive(method, paths, docstring): yield line
def make_httpdomain_rst(self, mapped_routes): node = nodes.section() node.document = self.state.document result = ViewList() routes = {} for route in mapped_routes: if route['method'] == ANY_KEY: method = 'any' else: method = route['method'] directives = http_directive( method, route['pattern'], route['docs'], ) routes[(method, route['pattern'])] = route for line in directives: result.append(line, '<autopyramid>') nested_parse_with_titles(self.state, result, node) for objnode in node.traverse(addnodes.desc): if objnode.get('domain') != 'http': continue for signode in objnode: if not isinstance(signode, addnodes.desc_signature): continue method = signode.get('method') path = signode.get('path') mapped_route = routes.get((method, path)) if not method or not path or not mapped_route: continue xref_node = self._make_view_source_xref(mapped_route) if not xref_node: continue xref_node += nodes.inline('', '[source]', classes=['viewcode-link']) source_node = addnodes.only(expr='html') source_node += xref_node signode += source_node return node.children
def make_rst(self, qref=False): app = import_object(self.arguments[0]) routes = self.inspect_routes(app) if 'view' in self.groupby: routes = self.groupby_view(routes) for method, paths, view_func, view_doc in routes: docstring = prepare_docstring(view_doc) if qref: for path in paths: row = quickref_directive(method, path, docstring) yield row else: for line in http_directive(method, paths, docstring): yield line
def make_rst(self): app = import_object(self.arguments[0]) if self.endpoints: routes = itertools.chain(*[get_routes(app, endpoint) for endpoint in self.endpoints]) else: routes = get_routes(app) for method, paths, endpoint in routes: if not self.check_regex_validate_path(paths): continue if self.check_regex_cancel_path(paths): continue try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and static_url_path + '/(path:filename)' in paths): continue view = app.view_functions[endpoint] docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) for line in http_directive(method, paths, docstring): yield line
def make_rst(self): app = import_object(self.arguments[0]) for method, path, target in get_routes(app): endpoint = target.name or target.callback.__name__ if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue view = target.callback docstring = view.__doc__ or '' if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) for line in http_directive(method, path, docstring): yield line
def make_rst(self, qref=False): app = import_object(self.arguments[0]) routes = self.inspect_routes(app) if 'view' in self.groupby: routes = self.groupby_view(routes) for method, paths, view_func, view_doc in routes: docstring = prepare_docstring(view_doc) if qref: auto = self.options.get("autoquickref", False) is None blueprint = get_blueprint(app, view_func) for path in paths: row = quickref_directive(method, path, docstring, blueprint, auto=auto) yield row else: for line in http_directive(method, paths, docstring): yield line
def make_rst(self): for name, path, vcallable in r1(): if not path.startswith(self.arguments[0]): continue yield name.capitalize() yield '-' * len(name) yield vcallable.__doc__ or '' for method in ('get', 'post', 'put', 'delete'): implementation = getattr(vcallable, method) if implementation is not_allowed: continue docstring = getattr(vcallable, method).__doc__ or '' # if not docstring and 'include-empty-docstring' not in self.options: # noqa # continue docstring = prepare_docstring(docstring) schema = getattr(implementation, 'schema', None) if schema is not None: docstring += [''] docstring += list(schema_to_docstring(schema)) qs_schema = getattr(implementation, 'qs_schema', None) if qs_schema is not None: docstring += [''] docstring += list(schema_to_docstring(qs_schema, 'query')) reqp = getattr(implementation, 'requires_permission', None) if reqp is not None: docstring = [ 'requires permission: ``{}``'.format(reqp), '' ] + docstring for line in http_directive(method, path, docstring): yield line
def make_rst(self): app = import_object(self.arguments[0]) for method, path, handler in get_routes(app): class_name = handler.__name__ method_name = getattr(handler, method).__name__ endpoint = '.'.join((class_name, method_name)) if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue docstring = getattr(handler, method).__doc__ or '' #if not isinstance(docstring, unicode): # analyzer = ModuleAnalyzer.for_module(view.__module__) # docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) for line in http_directive(method, normalize_path(path), docstring): yield line
def make_httpdomain_rst(self, mapped_routes): node = nodes.section() node.document = self.state.document result = ViewList() for route in mapped_routes: if route['method'] == ANY_KEY: method = 'any' else: method = route['method'] directives = http_directive( method, route['pattern'], route['docs'], ) for line in directives: result.append(line, '<autopyramid>') nested_parse_with_titles(self.state, result, node) return node.children
def make_rst(self): app = import_object(self.arguments[0]) for method, path, endpoint in get_routes(app): try: blueprint, endpoint_internal = endpoint.split('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and path == static_url_path + '/(path:filename)'): continue view = app.view_functions[endpoint] docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not type(docstring) == type(u""): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue docstring = prepare_docstring(docstring) for line in http_directive(method, path, docstring): yield line
def _render_rst(self): # pragma: no cover """Render lines of reStructuredText for items yielded by :meth:`~doctor.docs.base.BaseHarness.iter_annotations`. """ # Create a mapping of headers to annotations. We want to group # all annotations by a header, but they could be in multiple handlers # so we create a map of them here with the heading as the key and # the list of associated annotations as a list. This is so we can # sort them alphabetically to make reading the api docs easier. heading_to_annotations_map = defaultdict(list) for heading, route, handler, annotations in ( self.harness.iter_annotations()): # Set the route and handler as attributes so we can retrieve them # when we loop through them all below. for annotation in annotations: annotation.route = route annotation.handler = handler heading_to_annotations_map[heading].append(annotation) headings = heading_to_annotations_map.keys() headings.sort() previous_heading = None for heading in headings: annotations = heading_to_annotations_map.get(heading) # Sort all the annotations by title. annotations.sort(key=lambda a: a.title) # Only emit a new heading if the resource has changed. This # esnures that documented endpoints for the same resource all # end up under a single heading. if previous_heading != heading: previous_heading = heading yield HEADING_TOKEN + heading for annotation in annotations: route = annotation.route normalized_route = normalize_route(route) handler = annotation.handler # Adds a title for the endpoint. if annotation.title is not None: yield annotation.title yield '#' * len(annotation.title) docstring = get_description_lines( getattr(annotation.logic, '__doc__', None)) if annotation.request_schema: field = '<json' if annotation.http_method in ('DELETE', 'GET'): field = 'query' docstring.extend( get_json_schema_lines(annotation, annotation.request_schema, field=field, route=normalized_route, request=True)) # Document any request headers. defined_headers = self.harness._get_headers( str(route), annotation).keys() defined_headers.sort() for header in defined_headers: definition = self.harness.header_definitions.get( header, '') docstring.append(':reqheader {}: {}'.format( header, definition)) if annotation.response_schema: docstring.extend( get_json_schema_lines(annotation, annotation.response_schema, field='>json', route=normalized_route)) docstring.extend(self._make_example(route, handler, annotation)) for line in http_directive(annotation.http_method, normalized_route, docstring): yield line
def make_rst(self): app = import_object(self.arguments[0]) yield "Services:\n" yield "" for x in self._make_toc(get_routes(app)): yield '- {}'.format(x) yield "" for method, path, endpoint in get_routes(app): try: blueprint, _, endpoint_internal = endpoint.rpartition('.') if self.blueprints and blueprint not in self.blueprints: continue if blueprint in self.undoc_blueprints: continue except ValueError: pass # endpoint is not within a blueprint if self.endpoints and endpoint not in self.endpoints: continue if endpoint in self.undoc_endpoints: continue try: static_url_path = app.static_url_path # Flask 0.7 or higher except AttributeError: static_url_path = app.static_path # Flask 0.6 or under if ('undoc-static' in self.options and endpoint == 'static' and path == static_url_path + '/(path:filename)'): continue view = app.view_functions[endpoint] docstring = view.__doc__ or '' if hasattr(view, 'view_class'): meth_func = getattr(view.view_class, method.lower(), None) if meth_func and meth_func.__doc__: docstring = meth_func.__doc__ if not isinstance(docstring, six.text_type): analyzer = ModuleAnalyzer.for_module(view.__module__) docstring = force_decode(docstring, analyzer.encoding) if not docstring and 'include-empty-docstring' not in self.options: continue #Thanks flask-classy for this :D if len(endpoint.split(":")) == 2: view_cls, view_func = endpoint.split(":") if hasattr(app, 'view_classes') and view_cls in app.view_classes: cls = app.view_classes[view_cls] members = inspect.getmembers(cls,predicate=inspect.ismethod) if hasattr(cls,'args_rules'): rules = cls.args_rules if view_func in rules: for m in members: if m[0] == view_func: docstring += m[1].__doc__.strip() docstring += '\n\n' for a in rules[view_func]: t = str(a.type).replace('type','').replace("'","").replace('<','').replace('>','') params = dict( type=t, name=str(a.name), description=str(a.description), default=str(a.default) ) if a.required: docstring += ' :<json {type} {name}: {description}.\n'.format(**params) else: docstring += ' :<json {type} {name}: *(optional)* {description}. *Default*={default}\n'.format(**params) docstring = prepare_docstring(docstring) for line in http_directive(method, path, docstring): yield line