Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Unified Diff: third_party/google_api_python_client/describe.py

Issue 963953003: OAuth2 support in depot_tools (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: restore git_cl Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/google_api_python_client/describe.py
diff --git a/third_party/google_api_python_client/describe.py b/third_party/google_api_python_client/describe.py
new file mode 100755
index 0000000000000000000000000000000000000000..5dcac904c61a559b6e78003d63576bfdb1759b15
--- /dev/null
+++ b/third_party/google_api_python_client/describe.py
@@ -0,0 +1,390 @@
+#!/usr/bin/python
+#
+# Copyright 2014 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Create documentation for generate API surfaces.
+
+Command-line tool that creates documentation for all APIs listed in discovery.
+The documentation is generated from a combination of the discovery document and
+the generated API surface itself.
+"""
+
+__author__ = 'jcgregorio@google.com (Joe Gregorio)'
+
+import argparse
+import json
+import os
+import re
+import string
+import sys
+
+from googleapiclient.discovery import DISCOVERY_URI
+from googleapiclient.discovery import build
+from googleapiclient.discovery import build_from_document
+import httplib2
+import uritemplate
+
+CSS = """<style>
+
+body, h1, h2, h3, div, span, p, pre, a {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-weight: inherit;
+ font-style: inherit;
+ font-size: 100%;
+ font-family: inherit;
+ vertical-align: baseline;
+}
+
+body {
+ font-size: 13px;
+ padding: 1em;
+}
+
+h1 {
+ font-size: 26px;
+ margin-bottom: 1em;
+}
+
+h2 {
+ font-size: 24px;
+ margin-bottom: 1em;
+}
+
+h3 {
+ font-size: 20px;
+ margin-bottom: 1em;
+ margin-top: 1em;
+}
+
+pre, code {
+ line-height: 1.5;
+ font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;
+}
+
+pre {
+ margin-top: 0.5em;
+}
+
+h1, h2, h3, p {
+ font-family: Arial, sans serif;
+}
+
+h1, h2, h3 {
+ border-bottom: solid #CCC 1px;
+}
+
+.toc_element {
+ margin-top: 0.5em;
+}
+
+.firstline {
+ margin-left: 2 em;
+}
+
+.method {
+ margin-top: 1em;
+ border: solid 1px #CCC;
+ padding: 1em;
+ background: #EEE;
+}
+
+.details {
+ font-weight: bold;
+ font-size: 14px;
+}
+
+</style>
+"""
+
+METHOD_TEMPLATE = """<div class="method">
+ <code class="details" id="$name">$name($params)</code>
+ <pre>$doc</pre>
+</div>
+"""
+
+COLLECTION_LINK = """<p class="toc_element">
+ <code><a href="$href">$name()</a></code>
+</p>
+<p class="firstline">Returns the $name Resource.</p>
+"""
+
+METHOD_LINK = """<p class="toc_element">
+ <code><a href="#$name">$name($params)</a></code></p>
+<p class="firstline">$firstline</p>"""
+
+BASE = 'docs/dyn'
+
+DIRECTORY_URI = 'https://www.googleapis.com/discovery/v1/apis?preferred=true'
+
+parser = argparse.ArgumentParser(description=__doc__)
+
+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('--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.
+
+ Needed so that we can distinguish between versions
+ and sub-collections in URIs. I.e. we don't want
+ adsense_v1.1 to refer to the '1' collection in the v1
+ version of the adsense api.
+
+ Args:
+ version: string, The version string.
+ Returns:
+ The string with '.' replaced with '_'.
+ """
+
+ return version.replace('.', '_')
+
+
+def unsafe_version(version):
+ """Undoes what safe_version() does.
+
+ See safe_version() for the details.
+
+
+ Args:
+ version: string, The safe version string.
+ Returns:
+ The string with '_' replaced with '.'.
+ """
+
+ return version.replace('_', '.')
+
+
+def method_params(doc):
+ """Document the parameters of a method.
+
+ Args:
+ doc: string, The method's docstring.
+
+ 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]
+ else:
+ args = doclines[begin+1:]
+
+ parameters = []
+ for line in args:
+ m = re.search('^\s+([a-zA-Z0-9_]+): (.*)', line)
+ if m is None:
+ continue
+ pname = m.group(1)
+ desc = m.group(2)
+ if '(required)' not in desc:
+ pname = pname + '=None'
+ parameters.append(pname)
+ parameters = ', '.join(parameters)
+ else:
+ parameters = ''
+ return parameters
+
+
+def method(name, doc):
+ """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)
+
+
+def breadcrumbs(path, root_discovery):
+ """Create the breadcrumb trail to this page of documentation.
+
+ Args:
+ path: string, Dot separated name of the resource.
+ root_discovery: Deserialized discovery document.
+
+ Returns:
+ HTML with links to each of the parent resources of this resource.
+ """
+ parts = path.split('.')
+
+ 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)
+
+ return ' . '.join(crumbs)
+
+
+def document_collection(resource, path, root_discovery, discovery, css=CSS):
+ """Document a single collection in an API.
+
+ Args:
+ resource: Collection or service being documented.
+ path: string, Dot separated name of the resource.
+ root_discovery: Deserialized discovery document.
+ discovery: Deserialized discovery document, but just the portion that
+ 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)
+
+
+def document_collection_recursive(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__')):
+ 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.
+
+ Args:
+ name: string, Name of the API.
+ version: string, Version of the API.
+ """
+ service = build(name, version)
+ response, content = http.request(
+ uritemplate.expand(
+ FLAGS.discovery_uri_template, {
+ 'api': name,
+ 'apiVersion': version})
+ )
+ discovery = json.loads(content)
+
+ version = safe_version(version)
+
+ document_collection_recursive(
+ service, '%s_%s.' % (name, version), discovery, discovery)
+
+
+def document_api_from_discovery_document(uri):
+ """Document the given API.
+
+ Args:
+ uri: string, URI of discovery document.
+ """
+ http = httplib2.Http()
+ response, content = http.request(FLAGS.discovery_uri)
+ discovery = json.loads(content)
+
+ service = build_from_document(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:
+ http = httplib2.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'])
+ else:
+ sys.exit("Failed to load the discovery document.")
« no previous file with comments | « third_party/google_api_python_client/apiclient/__init__.py ('k') | third_party/google_api_python_client/expandsymlinks.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698