Skip to content

Commit

Permalink
Tools: cleanup generate API script
Browse files Browse the repository at this point in the history
  • Loading branch information
lwesterhof committed Aug 1, 2024
1 parent 000403e commit c2ab3c2
Showing 1 changed file with 51 additions and 51 deletions.
102 changes: 51 additions & 51 deletions tools/api/generate-openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"""
from __future__ import print_function

__copyright__ = 'Copyright (c) 2020-2022, Utrecht University'
__copyright__ = 'Copyright (c) 2020-2024, Utrecht University'
__license__ = 'GPLv3, see LICENSE'

__author__ = ('Chris Smeele')
Expand Down Expand Up @@ -112,57 +112,56 @@ def f(g):

# Note: for the most part, order matters (e.g. ordering of API function list).
# So we use ordered dicts.
O = lambda *xs: OrderedDict(xs)
def oDict(*xs):
return OrderedDict(xs)

title = 'Yoda API'

if core:
title = 'Yoda core API'

if module:
title = 'Yoda {} API'.format(module)

spec = O(('openapi', '3.0.0'),
spec = oDict(('openapi', '3.0.0'),
('info',
O(('description', ruleset_mod.__doc__),
oDict(('description', ruleset_mod.__doc__),
('contact',
O(('email', '[email protected]'))),
oDict(('email', '[email protected]'))),
('version', getattr(ruleset_mod, '__version__', '9999')),
('title', title))),
('servers',
[O(('url', 'https://portal.yoda.test/api'), ('description', 'Local Yoda development server'))]),
('security', [ O(('cookieAuth', [])), O(('basicAuth', [])) ]),
[oDict(('url', 'https://portal.yoda.test/api'), ('description', 'Local Yoda development server'))]),
('security', [ oDict(('cookieAuth', [])), oDict(('basicAuth', [])) ]),
('components',
O(('schemas',
O(('result_error',
O(('type', 'object'),
oDict(('schemas',
oDict(('result_error',
oDict(('type', 'object'),
('properties',
O(('status', O(('type', 'string'), ('description', 'Holds an error ID'))),
('status_info', O(('type', 'string'), ('description', 'Holds a human-readable error description'))),
oDict(('status', oDict(('type', 'string'), ('description', 'Holds an error ID'))),
('status_info', oDict(('type', 'string'), ('description', 'Holds a human-readable error description'))),
('data',
O(('description', 'empty'),
oDict(('description', 'empty'),
('nullable', True),
('type', 'object'))))))))),
('securitySchemes',
O(('cookieAuth',
O(('in', 'cookie'),
oDict(('cookieAuth',
oDict(('in', 'cookie'),
('type', 'apiKey'),
# ('name', 'session'))),
('name', 'yoda_session'))),
('basicAuth', O(('type', 'http'), ('scheme', 'basic'))))),
('basicAuth', oDict(('type', 'http'), ('scheme', 'basic'))))),
('responses',
O(('status_400',
O(('description', 'Bad request'),
oDict(('status_400',
oDict(('description', 'Bad request'),
('content',
O(('application/json',
O(('schema', O(('$ref', '#/components/schemas/result_error'))))))))),
oDict(('application/json',
oDict(('schema', oDict(('$ref', '#/components/schemas/result_error'))))))))),
('status_500',
O(('description', 'Internal error'),
oDict(('description', 'Internal error'),
('content',
O(('application/json',
O(('schema', O(('$ref', '#/components/schemas/result_error'))))))))),
oDict(('application/json',
oDict(('schema', oDict(('$ref', '#/components/schemas/result_error'))))))))),
)))),
('paths', O())
('paths', oDict())
)

def gen_fn_spec(name, fn):
Expand Down Expand Up @@ -192,7 +191,7 @@ def gen_fn_spec(name, fn):
,'dict': 'object'
,'list': 'array'}

paramdocs = O(*[(k, (types[(re.findall(r'^\s*:type\s+' +re.escape(k)+r':\s*(.+?)\s*$', doc, re.M) or ['str'])[-1]],
paramdocs = oDict(*[(k, (types[(re.findall(r'^\s*:type\s+' +re.escape(k)+r':\s*(.+?)\s*$', doc, re.M) or ['str'])[-1]],
(re.findall(r'^\s*:param\s+'+re.escape(k)+r':\s*(.+?)\s*$', doc, re.M) or ['(undocumented)'])[-1],
None if i < len(required) else a_defaults[i-len(required)]))
for i, k in enumerate(required+optional)])
Expand All @@ -205,14 +204,14 @@ def gen_fn_spec(name, fn):
doc = re.sub(r'^\s*[\r\n].*', '', doc, flags=re.M|re.S)

req = list(required)
props = O(*[(name, { 'type': paramdocs[name][0],
props = oDict(*[(name, { 'type': paramdocs[name][0],
'description': paramdocs[name][1],
'default': paramdocs[name][2] })
for name in required+optional])

for name in required+optional:
if props[name]['type'] == 'array':
props[name]['items'] = O()
props[name]['items'] = oDict()

dataspec = {
'type': 'object',
Expand All @@ -221,20 +220,21 @@ def gen_fn_spec(name, fn):
}

# Silly.
if req == []: del dataspec['required']
if req == []:
del dataspec['required']

# Currently, arguments are specified as a JSON string in a a
# multipart/form-data argument. This leads to less-than-ideal presentation
# of (optional) arguments in the Swagger editor.
# It seems to be a good idea to move the toplevel attributes of argument
# data to actual request parameters (e.g. individual form "fields").

return O(
return oDict(
('post',
O(('tags', [mod]),
oDict(('tags', [mod]),
('summary', doc),
('requestBody',
O(('required', True),
oDict(('required', True),
('content',
# How do we encode arguments?
#
Expand All @@ -243,36 +243,36 @@ def gen_fn_spec(name, fn):
# but as a result parameter documentation is unaccessible from swagger,
# and optional parameters are missing completely.
#
# O(('multipart/form-data',
# O(('schema',
# O(('type', 'object'),
# oDict(('multipart/form-data',
# oDict(('schema',
# oDict(('type', 'object'),
# ('properties',
# O(('data', dataspec))))))))))),
# oDict(('data', dataspec))))))))))),
#
# 2) as a JSON request body. Same result as (1)
#
# O(('application/json',
# O(('schema', dataspec))))))),
# oDict(('application/json',
# oDict(('schema', dataspec))))))),
#
# 3) Toplevel parameters as form fields.
# Not in line with the current portal,
# but provides the best documentation value.
#
O(('application/json',
O(('schema', dataspec))))))),
oDict(('application/json',
oDict(('schema', dataspec))))))),
('responses',
O(('200',
O(('description', 'Success'),
oDict(('200',
oDict(('description', 'Success'),
('content',
O(('application/json',
O(('schema',
O(('type', 'object'),
oDict(('application/json',
oDict(('schema',
oDict(('type', 'object'),
('properties',
O(('status', O(('type', 'string'))),
('status_info', O(('type', 'string'), ('nullable', True))),
('data', O(('nullable', True))))))))))))),
('400', O(('$ref', '#/components/responses/status_400'))),
('500', O(('$ref', '#/components/responses/status_500'))))))))
oDict(('status', oDict(('type', 'string'))),
('status_info', oDict(('type', 'string'), ('nullable', True))),
('data', oDict(('nullable', True))))))))))))),
('400', oDict(('$ref', '#/components/responses/status_400'))),
('500', oDict(('$ref', '#/components/responses/status_500'))))))))

for name, fn in api.fns:
if '<lambda>' in name:
Expand Down

0 comments on commit c2ab3c2

Please sign in to comment.