Updating API parameter documentation (refs #1901)
[arvados.git] / doc / gen_api_method_docs.py
1 #! /usr/bin/env python
2
3 # gen_api_method_docs.py
4 #
5 # Generate docs for Arvados methods.
6 #
7 # This script will retrieve the discovery document at
8 # https://localhost:9900/discovery/v1/apis/arvados/v1/rest
9 # and will generate Textile documentation files in the current
10 # directory.
11
12 import argparse
13 import pprint
14 import re
15 import requests
16 import os
17 import sys #debugging
18
19 p = argparse.ArgumentParser(description='Generate Arvados API method documentation.')
20
21 p.add_argument('--host',
22                type=str,
23                default='localhost',
24                help="The hostname or IP address of the API server")
25
26 p.add_argument('--port',
27                type=int,
28                default=9900,
29                help="The port of the API server")
30
31 p.add_argument('--output-dir',
32                type=str,
33                default='.',
34                help="Directory in which to write output files.")
35
36 args = p.parse_args()
37
38 api_url = 'https://{host}:{port}/discovery/v1/apis/arvados/v1/rest'.format(**vars(args))
39
40 r = requests.get(api_url, verify=False)
41 if r.status_code != 200:
42     raise Exception('Bad status code %d: %s' % (r.status_code, r.text))
43
44 if 'application/json' not in r.headers.get('content-type', ''):
45     raise Exception('Unexpected content type: %s: %s' %
46                     (r.headers.get('content-type', ''), r.text))
47
48 api = r.json()
49
50 resource_num = 0
51 for resource in sorted(api[u'resources']):
52     resource_num = resource_num + 1
53     out_fname = os.path.join(args.output_dir, resource + '.textile')
54     if os.path.exists(out_fname):
55         backup_name = out_fname + '.old'
56         try:
57             os.rename(out_fname, backup_name)
58         except OSError as e:
59             print "WARNING: could not back up {1} as {2}: {3}".format(
60                 out_fname, backup_name, e)
61     outf = open(out_fname, 'w')
62     outf.write(
63 """---
64 layout: default
65 navsection: api
66 navmenu: API Methods
67 title: "{resource}"
68 navorder: {resource_num}
69 ---
70
71 h1. {resource}
72
73 Required arguments are displayed in %{{background:#ccffcc}}green%.
74
75 """.format(resource_num=resource_num, resource=resource))
76
77     methods = api['resources'][resource]['methods']
78     for method in sorted(methods.keys()):
79         methodinfo = methods[method]
80         outf.write(
81 """
82 h2. {method}
83
84 {description}
85
86 Arguments:
87
88 table(table table-bordered table-condensed).
89 |_. Argument |_. Type |_. Description |_. Location |_. Example |
90 """.format(
91     method=method, description=methodinfo['description']))
92
93         required = []
94         notrequired = []
95         for param, paraminfo in methodinfo['parameters'].iteritems():
96             paraminfo.setdefault(u'description', '')
97             paraminfo.setdefault(u'location', '')
98             limit = ''
99             if paraminfo.get('minimum', '') or paraminfo.get('maximum', ''):
100                 limit = "range {0}-{1}".format(
101                     paraminfo.get('minimum', ''),
102                     paraminfo.get('maximum', 'unlimited'))
103             if paraminfo.get('default', ''):
104                 if limit:
105                     limit = limit + '; '
106                 limit = limit + 'default %d' % paraminfo['default']
107             if limit:
108                 paraminfo['type'] = '{0} ({1})'.format(
109                     paraminfo['type'], limit)
110
111             row = "|{param}|{type}|{description}|{location}||\n".format(
112                 param=param, **paraminfo)
113             if paraminfo.get('required', False):
114                 required.append(row)
115             else:
116                 notrequired.append(row)
117
118         for row in sorted(required):
119             outf.write("{background:#ccffcc}." + row)
120         for row in sorted(notrequired):
121             outf.write(row)
122
123         # pprint.pprint(methodinfo)
124
125     outf.close()
126     print "wrote ", out_fname
127
128