diff options
Diffstat (limited to 'describe.py')
-rwxr-xr-x | describe.py | 403 |
1 files changed, 216 insertions, 187 deletions
diff --git a/describe.py b/describe.py index 636eb5dee..e36db534d 100755 --- a/describe.py +++ b/describe.py @@ -22,7 +22,7 @@ the generated API surface itself. """ from __future__ import print_function -__author__ = 'jcgregorio@google.com (Joe Gregorio)' +__author__ = "jcgregorio@google.com (Joe Gregorio)" from collections import OrderedDict import argparse @@ -130,30 +130,40 @@ METHOD_LINK = """<p class="toc_element"> <code><a href="#$name">$name($params)</a></code></p> <p class="firstline">$firstline</p>""" -BASE = 'docs/dyn' +BASE = "docs/dyn" -DIRECTORY_URI = 'https://www.googleapis.com/discovery/v1/apis' +DIRECTORY_URI = "https://www.googleapis.com/discovery/v1/apis" parser = argparse.ArgumentParser(description=__doc__) -parser.add_argument('--discovery_uri_template', default=DISCOVERY_URI, - help='URI Template for discovery.') +parser.add_argument( + "--discovery_uri_template", + default=DISCOVERY_URI, + help="URI Template for discovery.", +) -parser.add_argument('--discovery_uri', default='', - help=('URI of discovery document. If supplied then only ' - 'this API will be documented.')) +parser.add_argument( + "--discovery_uri", + default="", + help=( + "URI of discovery document. If supplied then only " + "this API will be documented." + ), +) -parser.add_argument('--directory_uri', default=DIRECTORY_URI, - help=('URI of directory document. Unused if --discovery_uri' - ' is supplied.')) - -parser.add_argument('--dest', default=BASE, - help='Directory name to write documents into.') +parser.add_argument( + "--directory_uri", + default=DIRECTORY_URI, + help=("URI of directory document. Unused if --discovery_uri" " is supplied."), +) +parser.add_argument( + "--dest", default=BASE, help="Directory name to write documents into." +) def safe_version(version): - """Create a safe version of the verion string. + """Create a safe version of the verion string. Needed so that we can distinguish between versions and sub-collections in URIs. I.e. we don't want @@ -166,11 +176,11 @@ def safe_version(version): The string with '.' replaced with '_'. """ - return version.replace('.', '_') + return version.replace(".", "_") def unsafe_version(version): - """Undoes what safe_version() does. + """Undoes what safe_version() does. See safe_version() for the details. @@ -181,11 +191,11 @@ def unsafe_version(version): The string with '_' replaced with '.'. """ - return version.replace('_', '.') + return version.replace("_", ".") def method_params(doc): - """Document the parameters of a method. + """Document the parameters of a method. Args: doc: string, The method's docstring. @@ -193,54 +203,57 @@ def method_params(doc): Returns: The method signature as a string. """ - doclines = doc.splitlines() - if 'Args:' in doclines: - begin = doclines.index('Args:') - if 'Returns:' in doclines[begin+1:]: - end = doclines.index('Returns:', begin) - args = doclines[begin+1: end] + doclines = doc.splitlines() + if "Args:" in doclines: + begin = doclines.index("Args:") + if "Returns:" in doclines[begin + 1 :]: + end = doclines.index("Returns:", begin) + args = doclines[begin + 1 : end] + else: + args = doclines[begin + 1 :] + + parameters = [] + pname = None + desc = "" + + def add_param(pname, desc): + if pname is None: + return + if "(required)" not in desc: + pname = pname + "=None" + parameters.append(pname) + + for line in args: + m = re.search("^\s+([a-zA-Z0-9_]+): (.*)", line) + if m is None: + desc += line + continue + add_param(pname, desc) + pname = m.group(1) + desc = m.group(2) + add_param(pname, desc) + parameters = ", ".join(parameters) else: - args = doclines[begin+1:] - - parameters = [] - pname = None - desc = '' - def add_param(pname, desc): - if pname is None: - return - if '(required)' not in desc: - pname = pname + '=None' - parameters.append(pname) - for line in args: - m = re.search('^\s+([a-zA-Z0-9_]+): (.*)', line) - if m is None: - desc += line - continue - add_param(pname, desc) - pname = m.group(1) - desc = m.group(2) - add_param(pname, desc) - parameters = ', '.join(parameters) - else: - parameters = '' - return parameters + parameters = "" + return parameters def method(name, doc): - """Documents an individual method. + """Documents an individual method. Args: name: string, Name of the method. doc: string, The methods docstring. """ - params = method_params(doc) - return string.Template(METHOD_TEMPLATE).substitute( - name=name, params=params, doc=doc) + params = method_params(doc) + return string.Template(METHOD_TEMPLATE).substitute( + name=name, params=params, doc=doc + ) def breadcrumbs(path, root_discovery): - """Create the breadcrumb trail to this page of documentation. + """Create the breadcrumb trail to this page of documentation. Args: path: string, Dot separated name of the resource. @@ -249,28 +262,28 @@ def breadcrumbs(path, root_discovery): Returns: HTML with links to each of the parent resources of this resource. """ - parts = path.split('.') + parts = path.split(".") - crumbs = [] - accumulated = [] + crumbs = [] + accumulated = [] - for i, p in enumerate(parts): - prefix = '.'.join(accumulated) - # The first time through prefix will be [], so we avoid adding in a - # superfluous '.' to prefix. - if prefix: - prefix += '.' - display = p - if i == 0: - display = root_discovery.get('title', display) - crumbs.append('<a href="%s.html">%s</a>' % (prefix + p, display)) - accumulated.append(p) + for i, p in enumerate(parts): + prefix = ".".join(accumulated) + # The first time through prefix will be [], so we avoid adding in a + # superfluous '.' to prefix. + if prefix: + prefix += "." + display = p + if i == 0: + display = root_discovery.get("title", display) + crumbs.append('<a href="%s.html">%s</a>' % (prefix + p, display)) + accumulated.append(p) - return ' . '.join(crumbs) + return " . ".join(crumbs) def document_collection(resource, path, root_discovery, discovery, css=CSS): - """Document a single collection in an API. + """Document a single collection in an API. Args: resource: Collection or service being documented. @@ -280,148 +293,164 @@ def document_collection(resource, path, root_discovery, discovery, css=CSS): describes the resource. css: string, The CSS to include in the generated file. """ - collections = [] - methods = [] - resource_name = path.split('.')[-2] - html = [ - '<html><body>', - css, - '<h1>%s</h1>' % breadcrumbs(path[:-1], root_discovery), - '<h2>Instance Methods</h2>' - ] - - # Which methods are for collections. - for name in dir(resource): - if not name.startswith('_') and callable(getattr(resource, name)): - if hasattr(getattr(resource, name), '__is_resource__'): - collections.append(name) - else: - methods.append(name) - - - # TOC - if collections: - for name in collections: - if not name.startswith('_') and callable(getattr(resource, name)): - href = path + name + '.html' - html.append(string.Template(COLLECTION_LINK).substitute( - href=href, name=name)) - - if methods: - for name in methods: - if not name.startswith('_') and callable(getattr(resource, name)): - doc = getattr(resource, name).__doc__ - params = method_params(doc) - firstline = doc.splitlines()[0] - html.append(string.Template(METHOD_LINK).substitute( - name=name, params=params, firstline=firstline)) - - if methods: - html.append('<h3>Method Details</h3>') - for name in methods: - dname = name.rsplit('_')[0] - html.append(method(name, getattr(resource, name).__doc__)) - - html.append('</body></html>') - - return '\n'.join(html) + collections = [] + methods = [] + resource_name = path.split(".")[-2] + html = [ + "<html><body>", + css, + "<h1>%s</h1>" % breadcrumbs(path[:-1], root_discovery), + "<h2>Instance Methods</h2>", + ] + + # Which methods are for collections. + for name in dir(resource): + if not name.startswith("_") and callable(getattr(resource, name)): + if hasattr(getattr(resource, name), "__is_resource__"): + collections.append(name) + else: + methods.append(name) + + # TOC + if collections: + for name in collections: + if not name.startswith("_") and callable(getattr(resource, name)): + href = path + name + ".html" + html.append( + string.Template(COLLECTION_LINK).substitute(href=href, name=name) + ) + + if methods: + for name in methods: + if not name.startswith("_") and callable(getattr(resource, name)): + doc = getattr(resource, name).__doc__ + params = method_params(doc) + firstline = doc.splitlines()[0] + html.append( + string.Template(METHOD_LINK).substitute( + name=name, params=params, firstline=firstline + ) + ) + + if methods: + html.append("<h3>Method Details</h3>") + for name in methods: + dname = name.rsplit("_")[0] + html.append(method(name, getattr(resource, name).__doc__)) + + html.append("</body></html>") + + return "\n".join(html) def document_collection_recursive(resource, path, root_discovery, discovery): - html = document_collection(resource, path, root_discovery, discovery) + html = document_collection(resource, path, root_discovery, discovery) + + f = open(os.path.join(FLAGS.dest, path + "html"), "w") + f.write(html.encode("utf-8")) + f.close() + + for name in dir(resource): + if ( + not name.startswith("_") + and callable(getattr(resource, name)) + and hasattr(getattr(resource, name), "__is_resource__") + and discovery != {} + ): + dname = name.rsplit("_")[0] + collection = getattr(resource, name)() + document_collection_recursive( + collection, + path + name + ".", + root_discovery, + discovery["resources"].get(dname, {}), + ) - f = open(os.path.join(FLAGS.dest, path + 'html'), 'w') - f.write(html.encode('utf-8')) - f.close() - - for name in dir(resource): - if (not name.startswith('_') - and callable(getattr(resource, name)) - and hasattr(getattr(resource, name), '__is_resource__') - and discovery != {}): - dname = name.rsplit('_')[0] - collection = getattr(resource, name)() - document_collection_recursive(collection, path + name + '.', root_discovery, - discovery['resources'].get(dname, {})) def document_api(name, version): - """Document the given API. + """Document the given API. Args: name: string, Name of the API. version: string, Version of the API. """ - try: - service = build(name, version) - except UnknownApiNameOrVersion as e: - print('Warning: {} {} found but could not be built.'.format(name, version)) - return + try: + service = build(name, version) + except UnknownApiNameOrVersion as e: + print("Warning: {} {} found but could not be built.".format(name, version)) + return - http = build_http() - response, content = http.request( - uritemplate.expand( - FLAGS.discovery_uri_template, { - 'api': name, - 'apiVersion': version}) - ) - discovery = json.loads(content) + http = build_http() + response, content = http.request( + uritemplate.expand( + FLAGS.discovery_uri_template, {"api": name, "apiVersion": version} + ) + ) + discovery = json.loads(content) - version = safe_version(version) + version = safe_version(version) - document_collection_recursive( - service, '%s_%s.' % (name, version), discovery, discovery) + document_collection_recursive( + service, "%s_%s." % (name, version), discovery, discovery + ) def document_api_from_discovery_document(uri): - """Document the given API. + """Document the given API. Args: uri: string, URI of discovery document. """ - http = build_http() - response, content = http.request(FLAGS.discovery_uri) - discovery = json.loads(content) - - service = build_from_document(discovery) + http = build_http() + response, content = http.request(FLAGS.discovery_uri) + discovery = json.loads(content) - name = discovery['version'] - version = safe_version(discovery['version']) + service = build_from_document(discovery) - document_collection_recursive( - service, '%s_%s.' % (name, version), discovery, discovery) + name = discovery["version"] + version = safe_version(discovery["version"]) + document_collection_recursive( + service, "%s_%s." % (name, version), discovery, discovery + ) -if __name__ == '__main__': - FLAGS = parser.parse_args(sys.argv[1:]) - if FLAGS.discovery_uri: - document_api_from_discovery_document(FLAGS.discovery_uri) - else: - api_directory = collections.defaultdict(list) - http = build_http() - resp, content = http.request( - FLAGS.directory_uri, - headers={'X-User-IP': '0.0.0.0'}) - if resp.status == 200: - directory = json.loads(content)['items'] - for api in directory: - document_api(api['name'], api['version']) - api_directory[api['name']].append(api['version']) - - # sort by api name and version number - for api in api_directory: - api_directory[api] = sorted(api_directory[api]) - api_directory = OrderedDict(sorted(api_directory.items(), key = lambda x: x[0])) - - markdown = [] - for api, versions in api_directory.items(): - markdown.append('## %s' % api) - for version in versions: - markdown.append('* [%s](http://googleapis.github.io/google-api-python-client/docs/dyn/%s_%s.html)' % (version, api, version)) - markdown.append('\n') - - with open('docs/dyn/index.md', 'w') as f: - f.write('\n'.join(markdown).encode('utf-8')) +if __name__ == "__main__": + FLAGS = parser.parse_args(sys.argv[1:]) + if FLAGS.discovery_uri: + document_api_from_discovery_document(FLAGS.discovery_uri) else: - sys.exit("Failed to load the discovery document.") + api_directory = collections.defaultdict(list) + http = build_http() + resp, content = http.request( + FLAGS.directory_uri, headers={"X-User-IP": "0.0.0.0"} + ) + if resp.status == 200: + directory = json.loads(content)["items"] + for api in directory: + document_api(api["name"], api["version"]) + api_directory[api["name"]].append(api["version"]) + + # sort by api name and version number + for api in api_directory: + api_directory[api] = sorted(api_directory[api]) + api_directory = OrderedDict( + sorted(api_directory.items(), key=lambda x: x[0]) + ) + + markdown = [] + for api, versions in api_directory.items(): + markdown.append("## %s" % api) + for version in versions: + markdown.append( + "* [%s](http://googleapis.github.io/google-api-python-client/docs/dyn/%s_%s.html)" + % (version, api, version) + ) + markdown.append("\n") + + with open("docs/dyn/index.md", "w") as f: + f.write("\n".join(markdown).encode("utf-8")) + + else: + sys.exit("Failed to load the discovery document.") |