90 lines
3.2 KiB
Python
90 lines
3.2 KiB
Python
|
|
import json
|
|
import requests
|
|
import urllib
|
|
|
|
|
|
class OpenAPIMethod:
|
|
def __init__(self, url, name, descriptor, catalog):
|
|
self.url = url
|
|
self.__name__ = name
|
|
|
|
assert 'post' in descriptor, 'Only POST methods are supported'
|
|
post_descriptor = descriptor['post']
|
|
|
|
self.__doc__ = post_descriptor['description']
|
|
parameters = post_descriptor.get('parameters', [])
|
|
request_body = post_descriptor.get('requestBody')
|
|
|
|
self.parameters = {p['name']: p for p in parameters}
|
|
assert all(param['in'] == 'query' for param in self.parameters.values()), f'Only query path parameters are supported (path: {url}, descriptor: {json.dumps(descriptor)})'
|
|
|
|
self.body = None
|
|
if request_body:
|
|
assert 'application/json' in request_body['content'], f'Only application/json is supported for request body (path: {url}, descriptor: {json.dumps(descriptor)})'
|
|
|
|
body_name = 'body'
|
|
i = 2
|
|
while body_name in self.parameters:
|
|
body_name = f'body{i}'
|
|
i += 1
|
|
|
|
self.body = dict(
|
|
name=body_name,
|
|
required=request_body['required'],
|
|
schema=request_body['content']['application/json']['schema'],
|
|
)
|
|
|
|
self.parameters_schema = dict(
|
|
type='object',
|
|
properties={
|
|
**({
|
|
self.body['name']: self.body['schema']
|
|
} if self.body else {}),
|
|
**{
|
|
name: param['schema']
|
|
for name, param in self.parameters.items()
|
|
}
|
|
},
|
|
components=catalog.get('components'),
|
|
required=[name for name, param in self.parameters.items() if param['required']] + ([self.body['name']] if self.body and self.body['required'] else [])
|
|
)
|
|
|
|
def __call__(self, **kwargs):
|
|
if self.body:
|
|
body = kwargs.pop(self.body['name'], None)
|
|
if self.body['required']:
|
|
assert body is not None, f'Missing required body parameter: {self.body["name"]}'
|
|
else:
|
|
body = None
|
|
|
|
query_params = {}
|
|
for name, param in self.parameters.items():
|
|
value = kwargs.pop(name, None)
|
|
if param['required']:
|
|
assert value is not None, f'Missing required parameter: {name}'
|
|
|
|
assert param['in'] == 'query', 'Only query parameters are supported'
|
|
query_params[name] = value
|
|
|
|
params = "&".join(f"{name}={urllib.parse.quote(value)}" for name, value in query_params.items())
|
|
url = f'{self.url}?{params}'
|
|
response = requests.post(url, json=body)
|
|
response.raise_for_status()
|
|
response_json = response.json()
|
|
|
|
return response_json
|
|
|
|
|
|
def openapi_methods_from_endpoint(url):
|
|
catalog_url = f'{url}/openapi.json'
|
|
catalog_response = requests.get(catalog_url)
|
|
catalog_response.raise_for_status()
|
|
catalog = catalog_response.json()
|
|
|
|
methods = [
|
|
OpenAPIMethod(url=f'{url}{path}', name=path.replace('/', ' ').strip().replace(' ', '_'), descriptor=descriptor, catalog=catalog)
|
|
for path, descriptor in catalog['paths'].items()
|
|
]
|
|
return methods
|