#!/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 from googleapiclient.discovery import UnknownApiNameOrVersion from googleapiclient.http import build_http import uritemplate CSS = """ """ METHOD_TEMPLATE = """
$name($params)
$doc
Returns the $name Resource.
""" METHOD_LINK = """$firstline
""" BASE = 'docs/dyn' 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', 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 = [] 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 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('%s' % (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 = [ '', css, '