Files
api_builder/api_builder.py
2018-12-12 15:47:36 +01:00

118 lines
3.2 KiB
Python

import re
import sys
import inflection
import requests
import yaml
with open('prelude.py') as f:
prelude = f.read()
reserved = dir(__builtins__)
def download(url):
res = requests.get(url)
if url.endswith('.json'):
return res.json()
return yaml.parse(res)
def mkname(method, name, params):
singular = inflection.singularize(name)
if method == 'get' and 'id_' not in params:
return 'list_{}'.format(name)
elif method == 'get':
return singular
elif method == 'post':
return 'create_{}'.format(singular)
elif method == 'put' or method == 'PATCH':
return 'update_{}'.format(singular)
elif method == 'delete':
return 'delete_{}'.format(singular)
return name
def mkparam(param, data):
if '$ref' in param:
keys = param['$ref'][2:].split("/")
param = data
for key in keys:
param = param[key]
return param
def mkvarname(name):
name = inflection.underscore(name)
name = name.replace("$", "")
if name in reserved:
name = "{}_".format(name)
return name
def mkkwargs(params):
for param in params:
name = param['name']
if param['required']:
yield mkvarname(name)
for param in params:
name = param['name']
if not param['required']:
yield "{}=None".format(mkvarname(name))
def getparams(params, where):
ps = []
for param in params:
if param['in'] == where:
ps.append(param['name'])
return ps
def mkparams(params, where):
ps = getparams(params, where)
if not ps:
return None
return '{{\n{}\n }}'.format(',\n'.join(' "{}": {}'.format(p, mkvarname(p)) for p in ps))
def pretty_print(name, data):
info = data['info']
r = re.compile('\\/\\{([^\\}]*)\\}')
r2 = re.compile('\\{([^\\}]*)\\}')
print(prelude)
print('class {}(Client):'.format(name))
print(' """{}\n\n {}"""'.format(info['title'], info['description']))
for path, fns in data['paths'].items():
for method, body in fns.items():
method = method.lower()
fmt = r2.sub('{}', path)
paramdef = [mkparam(param, data) for param in body.get('parameters', [])]
name = r.sub('', path).replace("/", "_").replace('-', '_')[1:]
params = [mkvarname(p["name"]) for p in paramdef]
name = mkname(method, name, params)
params = ", {}".format(", ".join(mkkwargs(paramdef))) if params else ''
print(' def {}(self{}):'.format(name, params))
print(' """{}"""'.format(body.get("summary", "")))
print(' data = {}'.format(mkparams(paramdef, 'body')))
print(' params = {}'.format(mkparams(paramdef, 'query')))
tpl = ' return self.{}("{}"{}, data=data, params=params)\n'
args = getparams(paramdef, 'path')
args = '.format({})'.format(', '.join(args)) if args else ''
print(tpl.format(method, fmt, args))
def generate(name, url):
data = download(url)
pretty_print(name, data)
if __name__ == '__main__':
if len(sys.argv) != 3:
print("usage: {} <class-name> <url>".format(sys.argv[0]))
sys.exit(1)
generate(sys.argv[1], sys.argv[2])