#!/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. """ from __future__ import print_function __author__ = "jcgregorio@google.com (Joe Gregorio)" from collections import OrderedDict import argparse import collections 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, "