blob: 9aabde5ad7d1e2b9e85e0f8d802804795ac3246c [file] [log] [blame]
Joe Gregorioc204b642010-09-21 12:01:23 -04001#!/usr/bin/env python
2#
Joe Gregorio9c8588a2011-07-01 12:01:36 -04003# Copyright 2011 Google Inc.
Joe Gregorioc204b642010-09-21 12:01:23 -04004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
Joe Gregorio9c8588a2011-07-01 12:01:36 -040017"""Sample application for Python documentation of APIs.
18
19This is running live at http://api-python-client-doc.appspot.com where it
20provides a list of APIs and PyDoc documentation for all the generated API
21surfaces as they appear in the google-api-python-client. In addition it also
22provides a Google Gadget.
23"""
Joe Gregorioc204b642010-09-21 12:01:23 -040024
25__author__ = 'jcgregorio@google.com (Joe Gregorio)'
26
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040027import httplib2
Joe Gregoriod44bb002010-09-21 14:34:44 -040028import inspect
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040029import os
Joe Gregorioc204b642010-09-21 12:01:23 -040030import pydoc
31import re
32
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040033from apiclient.anyjson import simplejson
Joe Gregorio9c8588a2011-07-01 12:01:36 -040034from apiclient import discovery
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040035from google.appengine.api import memcache
Joe Gregorioc204b642010-09-21 12:01:23 -040036from google.appengine.ext import webapp
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040037from google.appengine.ext.webapp import template
Joe Gregorioc204b642010-09-21 12:01:23 -040038from google.appengine.ext.webapp import util
39
Joe Gregoriod44bb002010-09-21 14:34:44 -040040
Joe Gregorioc204b642010-09-21 12:01:23 -040041class MainHandler(webapp.RequestHandler):
Joe Gregorio9c8588a2011-07-01 12:01:36 -040042 """Handles serving the main landing page.
43 """
Joe Gregorioc204b642010-09-21 12:01:23 -040044
45 def get(self):
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040046 http = httplib2.Http(memcache)
Joe Gregorio6a63a762011-05-02 22:36:05 -040047 resp, content = http.request('https://www.googleapis.com/discovery/v1/apis?preferred=true')
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040048 directory = simplejson.loads(content)['items']
Joe Gregorio6a63a762011-05-02 22:36:05 -040049 for item in directory:
50 item['title'] = item.get('title', item.get('description', ''))
Joe Gregorioc5edb3c2011-03-18 10:54:10 -040051 path = os.path.join(os.path.dirname(__file__), 'index.html')
52 self.response.out.write(
53 template.render(
54 path, {'directory': directory,
55 }))
Joe Gregorioc204b642010-09-21 12:01:23 -040056
Joe Gregorio140062f2010-09-21 16:12:41 -040057
Joe Gregorio9c8588a2011-07-01 12:01:36 -040058class GadgetHandler(webapp.RequestHandler):
59 """Handles serving the Google Gadget.
60 """
61
62 def get(self):
63 http = httplib2.Http(memcache)
64 resp, content = http.request('https://www.googleapis.com/discovery/v1/apis?preferred=true')
65 directory = simplejson.loads(content)['items']
66 for item in directory:
67 item['title'] = item.get('title', item.get('description', ''))
68 path = os.path.join(os.path.dirname(__file__), 'gadget.html')
69 self.response.out.write(
70 template.render(
71 path, {'directory': directory,
72 }))
73 self.response.headers.add_header('Content-Type', 'application/xml')
74
75
76def _render(resource):
77 """Use pydoc helpers on an instance to generate the help documentation.
78 """
Joe Gregorioafc45f22011-02-20 16:11:28 -050079 obj, name = pydoc.resolve(type(resource))
80 return pydoc.html.page(
81 pydoc.describe(obj), pydoc.html.document(obj, name))
82
Joe Gregorioc204b642010-09-21 12:01:23 -040083
Joe Gregorio0fb19e12011-02-22 07:53:24 -050084class ResourceHandler(webapp.RequestHandler):
Joe Gregorio9c8588a2011-07-01 12:01:36 -040085 """Handles serving the PyDoc for a given collection.
86 """
Joe Gregorioc204b642010-09-21 12:01:23 -040087
88 def get(self, service_name, version, collection):
Joe Gregorio9c8588a2011-07-01 12:01:36 -040089 resource = discovery.build(service_name, version)
Joe Gregorio20cfcda2010-10-26 11:58:08 -040090 # descend the object path
Joe Gregorio0fb19e12011-02-22 07:53:24 -050091 if collection:
92 path = collection.split('/')
93 if path:
94 for method in path:
95 resource = getattr(resource, method)()
Joe Gregorio9c8588a2011-07-01 12:01:36 -040096 page = _render(resource)
Joe Gregorio20cfcda2010-10-26 11:58:08 -040097
Joe Gregorio0fb19e12011-02-22 07:53:24 -050098 collections = []
99 for name in dir(resource):
100 if not "_" in name and callable(getattr(resource, name)) and hasattr(
101 getattr(resource, name), '__is_resource__'):
102 collections.append(name)
Joe Gregorio20cfcda2010-10-26 11:58:08 -0400103
Joe Gregorio0fb19e12011-02-22 07:53:24 -0500104 if collection is None:
105 collection_path = ''
106 else:
107 collection_path = collection + '/'
108 for name in collections:
109 page = re.sub('strong>(%s)<' % name,
110 r'strong><a href="/%s/%s/%s">\1</a><' % (
111 service_name, version, collection_path + name), page)
Joe Gregorio20cfcda2010-10-26 11:58:08 -0400112
Joe Gregorio0fb19e12011-02-22 07:53:24 -0500113 # TODO(jcgregorio) breadcrumbs
114 # TODO(jcgregorio) sample code?
115 page = re.sub('<p>', r'<a href="/">Home</a><p>', page, 1)
Joe Gregorioc204b642010-09-21 12:01:23 -0400116 self.response.out.write(page)
117
Joe Gregorio140062f2010-09-21 16:12:41 -0400118
Joe Gregorioc204b642010-09-21 12:01:23 -0400119def main():
120 application = webapp.WSGIApplication(
121 [
122 (r'/', MainHandler),
Joe Gregorio9c8588a2011-07-01 12:01:36 -0400123 (r'/_gadget/', GadgetHandler),
Joe Gregorio0fb19e12011-02-22 07:53:24 -0500124 (r'/([^\/]*)/([^\/]*)(?:/(.*))?', ResourceHandler),
Joe Gregorioc204b642010-09-21 12:01:23 -0400125 ],
126 debug=True)
127 util.run_wsgi_app(application)
128
129
130if __name__ == '__main__':
131 main()