From 70d003b0b8c28f3813213868606c1d77484fd776 Mon Sep 17 00:00:00 2001 From: Clemens Rudert Date: Fri, 20 Mar 2020 14:17:41 +0100 Subject: [PATCH 1/5] add openapi 3.0.3 support --- pyramid_georest/__init__.py | 2 + pyramid_georest/lib/openapi.py | 521 +++++++++++++++++++++++++++++++++ pyramid_georest/lib/rest.py | 83 +++++- pyramid_georest/routes.py | 15 +- setup.py | 20 +- 5 files changed, 620 insertions(+), 21 deletions(-) create mode 100644 pyramid_georest/lib/openapi.py diff --git a/pyramid_georest/__init__.py b/pyramid_georest/__init__.py index 312c091..c7a5212 100644 --- a/pyramid_georest/__init__.py +++ b/pyramid_georest/__init__.py @@ -9,6 +9,8 @@ log = logging.getLogger('pyramid_georest') +VERSION = "4.0.0" + def main(global_config, **settings): """ This function returns a Pyramid WSGI application. This is necessary for development of diff --git a/pyramid_georest/lib/openapi.py b/pyramid_georest/lib/openapi.py new file mode 100644 index 0000000..851025f --- /dev/null +++ b/pyramid_georest/lib/openapi.py @@ -0,0 +1,521 @@ +# -*- coding: utf-8 -*- + +VERSION = '3.0.3' + + +class Contact(dict): + + def __init__(self, name=None, url=None, email=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#contactObject + + Args: + name (str or None): see https://spec.openapis.org/oas/v3.0.3 + url (str or None): see https://spec.openapis.org/oas/v3.0.3 + email (str ro None): see https://spec.openapis.org/oas/v3.0.3 + """ + super().__init__() + if name: + self['name'] = name + if url: + self['url'] = url + if email: + self['email'] = email + + +class License(dict): + def __init__(self, name=None, url=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#licenseObject + + Args: + name (str or None): see https://spec.openapis.org/oas/v3.0.3 + url (str or None): see https://spec.openapis.org/oas/v3.0.3 + """ + super().__init__() + if name: + self['name'] = name + if url: + self['url'] = url + + +class Info(dict): + + def __init__(self, title, version, description=None, terms_of_service=None, contact=None, + api_license=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#infoObject + + Args: + title (str): see https://spec.openapis.org/oas/v3.0.3#infoObject + version (str): see https://spec.openapis.org/oas/v3.0.3#infoObject + description (str or None): see https://spec.openapis.org/oas/v3.0.3#infoObject + terms_of_service (str or None): see https://spec.openapis.org/oas/v3.0.3#infoObject + contact (Contact or None): see https://spec.openapis.org/oas/v3.0.3#infoObject + api_license (License or None): see https://spec.openapis.org/oas/v3.0.3#infoObject + """ + super().__init__() + self['title'] = title + self['version'] = version + if description: + self['description'] = description + if terms_of_service: + self['termsOfService'] = terms_of_service + if contact: + self['contact'] = contact + if api_license: + self['license'] = api_license + + +class ServerVariable(dict): + + def __init__(self, key, default, enum=None, description=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#server-variable-object + + Args: + key (str): The key which is used then as key for parent elements. + default (str): see https://spec.openapis.org/oas/v3.0.3#server-variable-object + enum (list of str or None): see https://spec.openapis.org/oas/v3.0.3#server-variable-object + description (str or None): see https://spec.openapis.org/oas/v3.0.3#server-variable-object + """ + super().__init__() + self.key = key + self['default'] = default + if enum: + self['enum'] = enum + if description: + self['description'] = description + + +class Server(dict): + + def __init__(self, url, description=None, variables=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#server-object + + Args: + url (str): see https://spec.openapis.org/oas/v3.0.3#server-object + description (str or None): see https://spec.openapis.org/oas/v3.0.3#server-object + variables (list of ServerVariable or None): see https://spec.openapis.org/oas/v3.0.3#server-object + """ + super().__init__() + self['url'] = url + if description: + self['description'] = description + if variables: + self['variables'] = {} + for variable in variables: + self['variables'][variable.key] = variable + + +class Schema(dict): + pass + + +class Header(dict): + allowed_in_values = ['query', 'header', 'path', 'cookie'] + + def __init__(self, key, name=None, in_location=None, description=None, required=False, deprecated=False, + allow_empty_value=False, style=None, explode=False, allow_reserved=False, schema=None, + example=None, examples=None, content=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#parameter-object + + Args: + key (str): The key which is used then as key for parent elements. + name (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + in_location (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + description (str or None): see + https://spec.openapis.org/oas/v3.0.3#external-documentation-object + required (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + deprecated (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + allow_empty_value (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + style (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + explode (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + allow_reserved (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + schema (Schema or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + example (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + examples (list of Example or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + content (list of MediaType or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + """ + # TODO: implement correct behaviour like it is described in + # https://spec.openapis.org/oas/v3.0.3#parameter-object + super().__init__() + self.key = key + self['name'] = name + if in_location.lower() not in self.allowed_in_values: + raise AttributeError('The passed "in" value {} is not allowed. It has to be one of {}'.format( + in_location, + str(self.allowed_in_values) + )) + self['in'] = in_location + self['required'] = required + self['deprecated'] = deprecated + self['allowEmptyValue'] = allow_empty_value + self['explode'] = explode + self['allowReserved'] = allow_reserved + + if description: + self['description'] = description + if style: + self['style'] = style + if schema: + self['schema'] = schema + if example: + self['example'] = example + if examples: + self['examples'] = {} + for e in examples: + self['examples'][e.key] = e + if content: + self['content'] = {} + for c in content: + self['content'][c.key] = c + + +class Example(dict): + + def __init__(self, key, summary=None, description=None, value=None, external_value=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#example-object + + Args: + key (str): The key which is used then as key for parent elements. + summary (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object + description (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object + value (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object + external_value (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object + """ + super().__init__() + self.key = key + if summary: + self['summary'] = summary + if description: + self['description'] = description + if value: + self['value'] = value + if external_value: + self['externalValue'] = external_value + + +class Encoding(dict): + def __init__(self, key, content_type=None, headers=None, style=None, explode=False, + allow_reserved=False): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#encodingObject + + Args: + key (str): The key which is used then as key for parent elements. + content_type (str or None): see https://spec.openapis.org/oas/v3.0.3#encodingObject + headers (list of Header or None): see https://spec.openapis.org/oas/v3.0.3#encodingObject + style (str or None): see https://spec.openapis.org/oas/v3.0.3#encodingObject + explode (bool): see https://spec.openapis.org/oas/v3.0.3#encodingObject + """ + super().__init__() + self.key = key + self['explode'] = explode + self['allowReserved'] = allow_reserved + if content_type: + self['contentType'] = content_type + if headers: + self['headers'] = {} + for header in headers: + self['headers'][header.key] = header + if style: + self['style'] = style + + +class MediaType(dict): + def __init__(self, key, schema=None, example=None, examples=None, encoding=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#media-type-object + + Args: + key (str): The key which is used then as key for parent elements. + schema (Schema or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object + example (str or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object + examples (list of Example or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object + encoding (list of Encoding or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object + """ + super().__init__() + self.key = key + if schema: + self['schema'] = schema + if example: + self['example'] = example + if examples: + self['examples'] = {} + for e in examples: + self['examples'][e.key] = e + if encoding: + self['encoding'] = {} + for enc in encoding: + self['encoding'][enc.key] = enc + + +class Link(dict): + pass + + +class Response(dict): + def __init__(self, code, description, headers=None, content=None, links=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#response-object + + Args: + code (str): see https://spec.openapis.org/oas/v3.0.3#http-status-codes and + https://spec.openapis.org/oas/v3.0.3#responses-object + description (str): see https://spec.openapis.org/oas/v3.0.3#response-object + headers (list of Header or None): see https://spec.openapis.org/oas/v3.0.3#response-object + content (list of MediaType or None): see https://spec.openapis.org/oas/v3.0.3#response-object + links (list of Link or None): see https://spec.openapis.org/oas/v3.0.3#response-object + """ + super().__init__() + self.code = code + self['description'] = description + if headers: + self['headers'] = {} + for header in headers: + self['headers'][header.key] = header + if content: + self['content'] = {} + for media_type in content: + self['content'][media_type.key] = media_type + if links: + self['links'] = {} + for link in links: + self['links'][link.key] = link + + +class Responses(dict): + def __init__(self, responses, default=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#responses-object + + Args: + responses (list of Response): see https://spec.openapis.org/oas/v3.0.3#responses-object + default (Response or None): see https://spec.openapis.org/oas/v3.0.3#responses-object + """ + super().__init__() + if len(responses) < 1: + raise AttributeError('You need to define at least one response!') + for response in responses: + self[response.code] = response + if default: + self['default'] = default + + +class ExternalDocumentation(dict): + def __init__(self, url, description=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#external-documentation-object + + Args: + url (str): see https://spec.openapis.org/oas/v3.0.3#external-documentation-object + description (str or None): see + https://spec.openapis.org/oas/v3.0.3#external-documentation-object + """ + super().__init__() + self['url'] = url + if description: + self['description'] = description + + +class Parameter(Header): + allowed_in_values = ['query', 'header', 'path', 'cookie'] + + def __init__(self, name, in_location, description=None, required=False, deprecated=False, + allow_empty_value=False, style=None, explode=False, allow_reserved=False, schema=None, + example=None, examples=None, content=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#parameter-object + + Args: + name (str): see https://spec.openapis.org/oas/v3.0.3#parameter-object + in_location (str): see https://spec.openapis.org/oas/v3.0.3#parameter-object + description (str or None): see + https://spec.openapis.org/oas/v3.0.3#external-documentation-object + required (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + deprecated (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + allow_empty_value (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + style (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + explode (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + allow_reserved (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object + schema (Schema or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + example (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + examples (list of Example or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + content (list of MediaType or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + """ + super().__init__('', name, in_location, description=description, required=required, + deprecated=deprecated, allow_empty_value=allow_empty_value, style=style, + explode=explode, allow_reserved=allow_reserved, schema=schema, example=example, + examples=examples, content=content) + + +class RequestBody(dict): + def __init__(self, content, description=None, required=False): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#request-body-object + + Args: + content (list of MediaType): see https://spec.openapis.org/oas/v3.0.3#request-body-object + description (str or None): see https://spec.openapis.org/oas/v3.0.3#request-body-object + required (bool): see https://spec.openapis.org/oas/v3.0.3#request-body-object + """ + super().__init__() + self['required'] = required + self['content'] = {} + for c in content: + self['content'][c.key] = c + if description: + self['description'] = description + + +class Callback(dict): + # TODO: implement like described here: https://spec.openapis.org/oas/v3.0.3#callback-object + pass + + +class SecurityRequirement(dict): + # TODO: implement like described here: http://spec.openapis.org/oas/v3.0.3#security-requirement-object + pass + + +class Operation(dict): + + def __init__(self, responses, tags=None, summary=None, description=None, external_docs=None, + operation_id=None, parameters=None, request_body=None, callbacks=None, deprecated=False, + security=None, servers=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#operation-object + + Args: + responses (Responses) : see https://spec.openapis.org/oas/v3.0.3#operation-object + tags (list of str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + summary (str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + description (str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + external_docs (ExternalDocumentation or None: see + https://spec.openapis.org/oas/v3.0.3#operation-object + operation_id (str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + parameters (list of Parameter or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + request_body (RequestBody or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + callbacks(list of Callback or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + deprecated (bool): see https://spec.openapis.org/oas/v3.0.3#operation-object + security (list of SecurityRequirement or None): see + https://spec.openapis.org/oas/v3.0.3#operation-object + servers (list of Server or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + """ + super().__init__() + self['responses'] = responses + self['deprecated'] = deprecated + if tags: + self['tags'] = tags + if summary: + self['summary'] = summary + if description: + self['description'] = description + if external_docs: + self['externalDocs'] = external_docs + if operation_id: + self['operationId'] = operation_id + if parameters: + self['parameters'] = parameters + if request_body: + self['requestBody'] = request_body + if responses: + self['responses'] = responses + if callbacks: + self['callbacks'] = callbacks + if security: + self['security'] = security + if servers: + self['servers'] = servers + + +class PathItems(dict): + + def __init__(self, ref=None, summary=None, description=None, get=None, put=None, post=None, delete=None, + options=None, head=None, patch=None, trace=None, servers=None, parameters=None): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#path-item-object + + Args: + ref (str or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + summary (str or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + description (str or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + get (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + put (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + post (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + delete (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + options (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + head (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + patch (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + trace (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + servers (list of Server or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + parameters (list of Parameter or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + """ + super().__init__() + if ref: + self['$ref'] = ref + if summary: + self['summary'] = summary + if description: + self['description'] = description + if get: + self['get'] = get + if put: + self['put'] = put + if post: + self['post'] = post + if delete: + self['delete'] = delete + if options: + self['options'] = options + if head: + self['head'] = head + if patch: + self['patch'] = patch + if trace: + self['trace'] = trace + if servers: + self['servers'] = servers + if parameters: + self['parameters'] = parameters + + +class Paths(dict): + + def __init__(self, service_path, path_item): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#paths-object + + Args: + service_path (str): The sub path of the service. It is used as key to store all available + operations below. + path_item (PathItem): see https://spec.openapis.org/oas/v3.0.3#paths-object + """ + super().__init__(path_item) + self.service_path = service_path + + +class OpenApi(dict): + + def __init__(self, info, servers, paths): + """ + Implementation of https://spec.openapis.org/oas/v3.0.3#openapi-object + + Args: + info (Info): see https://spec.openapis.org/oas/v3.0.3#openapi-object + servers (list of Server): see https://spec.openapis.org/oas/v3.0.3#openapi-object + paths (list of Paths): see https://spec.openapis.org/oas/v3.0.3#openapi-object + """ + super().__init__() + self['openapi'] = VERSION + self['info'] = info + self['servers'] = servers + self['paths'] = {} + for path in paths: + self['paths'][path.service_path] = path + + diff --git a/pyramid_georest/lib/rest.py b/pyramid_georest/lib/rest.py index 6f77e55..0b03720 100644 --- a/pyramid_georest/lib/rest.py +++ b/pyramid_georest/lib/rest.py @@ -5,7 +5,10 @@ import transaction from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest from pyramid.renderers import render_to_response +from pyramid_georest import VERSION from pyramid_georest.lib.description import ModelDescription +from pyramid_georest.lib.openapi import Contact, License, OpenApi, Info, Server, Paths, PathItems, Operation, \ + Responses, Response from pyramid_georest.lib.renderer import RenderProxy, AdapterProxy from pyramid_georest.lib.database import Connection from pyramid_georest.routes import create_api_routing, check_route_prefix @@ -772,8 +775,9 @@ def adapter(self, request): class Api(object): - def __init__(self, url, config, name, read_method='GET', read_filter_method='POST', create_method='POST', - update_method='PUT', delete_method='DELETE'): + def __init__(self, url, config, name, title, read_method='GET', read_filter_method='POST', + create_method='POST', update_method='PUT', delete_method='DELETE', description=None, + terms_of_service=None, contact=None, api_license=None, server_description=None): """ A Object which holds the connection to the database and arbitrary numbers of services. It works like a proxy for the request. It decides which service will be finally called by reading @@ -790,20 +794,50 @@ def __init__(self, url, config, name, read_method='GET', read_filter_method='POS name (str): The name which is used internally as an identifier of the api, to make it selectable between other api's. This name must be unique all over the application. If not an error will be thrown on application start up. + title (str): The title of the API. This can be a speaking title in the terms of + spec.openapis.org/oas/v3.0.3 read_method (str): The HTTP method which is used to match the routing to the API. read_filter_method (str): The HTTP method which is used to match the routing to the API. create_method (str): The HTTP method which is used to match the routing to the API. update_method (str): The HTTP method which is used to match the routing to the API. delete_method (str): The HTTP method which is used to match the routing to the API. + description (str or None): The description if API in terms of spec.openapis.org/oas/v3.0.3 + terms_of_service (str or None): The terms of usage. See spec.openapis.org/oas/v3.0.3 + contact (Contact or None): The contact data in terms of spec.openapis.org/oas/v3.0.3 + api_license (License or None): The license which is offered by this API in terms of + spec.openapis.org/oas/v3.0.3 + server_description (str or None): The description which is used for the server. This is a meta + into since at the api point of view there is always only one server supported in the moment. + Please see information about this here http://spec.openapis.org/oas/v3.0.3#server-object Raises: LookupError + AttributeError """ self.read_method = read_method self.read_filter_method = read_filter_method self.create_method = create_method self.update_method = update_method self.delete_method = delete_method + self.version = VERSION + self.title = title + self.description = description + self.terms_of_service = terms_of_service + if not isinstance(contact, Contact) and contact is not None: + raise AttributeError( + 'Wrong type for contact was passed {}. ' + 'Allowed is only pyramid_georest.lib.openapi.Contact or None.'.format(type(contact)) + ) + else: + self.contact = contact + if not isinstance(api_license, License) and contact is not None: + raise AttributeError( + 'Wrong type for license was passed {}. ' + 'Allowed is only pyramid_georest.lib.openapi.License or None.'.format(type(api_license)) + ) + else: + self.license = api_license + self.server_description = server_description connection_already_exists = False connections = config.registry.pyramid_georest_database_connections @@ -921,6 +955,51 @@ def find_service_by_request(self, request): request.registry.pyramid_georest_requested_service = service return service + def open_api(self, request): + """ + The api method to receive the openapi document. + + Args: + request (pyramid.request.Request): The request which comes all the way through the application + from the client. + + Returns: + pyramid.response.Response: An pyramid response object + """ + paths = [] + for service in self.services: + for render_format in service.renderer_proxy._format_to_renderer.keys(): + paths.append(Paths('/{schema_name}/{table_name}/read/{format}'.format( + schema_name=service.name.split(',')[0], + table_name=service.name.split(',')[1], + format=render_format + ), PathItems( + summary='Reads a defined ammount of records from {}.{} table.'.format( + service.name.split(',')[0], + service.name.split(',')[1] + ), + description='JadaJada', + get=Operation( + Responses([ + Response('200', 'Delivers desired records as {}'.format(render_format)), + Response('400', 'In case of errors.') + ]) + ) + ))) + return OpenApi( + Info( + self.title, + self.version, + self.description, + self.terms_of_service, + self.contact, + self.license + ), [ + Server(request.route_path(self.name), description=self.server_description) + ], + paths + ) + def read(self, request): """ The api wide method to receive the read request and passing it to the correct service. At this diff --git a/pyramid_georest/routes.py b/pyramid_georest/routes.py index c4cd58c..70d1c33 100644 --- a/pyramid_georest/routes.py +++ b/pyramid_georest/routes.py @@ -1,4 +1,4 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- def check_route_prefix(route_prefix): @@ -18,6 +18,19 @@ def create_api_routing(config, api): api (pyramid_georest.lib.rest.Api): The Api which the routing is bound to. """ + # delivers multiple records/filtered + config.add_route( + api.name, + '/' + api.pure_name + ) + config.add_view( + api, + route_name=api.name, + attr='open_api', + request_method=api.read_method, + renderer='json' + ) + # delivers multiple records/filtered config.add_route( '{api_name}/read'.format(api_name=api.name), diff --git a/setup.py b/setup.py index 5674ebc..2401d18 100644 --- a/setup.py +++ b/setup.py @@ -1,24 +1,8 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2012 - 2015, GIS-Fachstelle des Amtes für Geoinformation des Kantons Basel-Landschaft -# All rights reserved. -# -# This program is free software and completes the GeoMapFish License for the geoview.bl.ch specific -# parts of the code. You can redistribute it and/or modify it under the terms of the GNU General -# Public License as published by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The above copyright notice and this permission notice shall be included in all copies or substantial -# portions of the Software. import os from setuptools import setup, find_packages - -__author__ = 'Clemens Rudert' -__create_date__ = '30.07.2015' +from pyramid_georest import VERSION here = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(here, 'README.md')) as f: @@ -49,7 +33,7 @@ setup( name='pyramid_georest', - version='4.0.0', + version=VERSION, description='pyramid_georest, extension for pyramid web frame work to provide rest interface for ' 'sql-alchemy mappers', long_description=README + '\n\n' + CHANGES, From 8e816fa073be0e23b8f9154cfe262ec52b8aca85 Mon Sep 17 00:00:00 2001 From: Clemens Rudert Date: Fri, 20 Mar 2020 14:28:07 +0100 Subject: [PATCH 2/5] add configurable version of api --- pyramid_georest/__init__.py | 2 -- pyramid_georest/lib/rest.py | 8 ++++---- setup.py | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/pyramid_georest/__init__.py b/pyramid_georest/__init__.py index c7a5212..312c091 100644 --- a/pyramid_georest/__init__.py +++ b/pyramid_georest/__init__.py @@ -9,8 +9,6 @@ log = logging.getLogger('pyramid_georest') -VERSION = "4.0.0" - def main(global_config, **settings): """ This function returns a Pyramid WSGI application. This is necessary for development of diff --git a/pyramid_georest/lib/rest.py b/pyramid_georest/lib/rest.py index 0b03720..9f54cd7 100644 --- a/pyramid_georest/lib/rest.py +++ b/pyramid_georest/lib/rest.py @@ -5,7 +5,6 @@ import transaction from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest from pyramid.renderers import render_to_response -from pyramid_georest import VERSION from pyramid_georest.lib.description import ModelDescription from pyramid_georest.lib.openapi import Contact, License, OpenApi, Info, Server, Paths, PathItems, Operation, \ Responses, Response @@ -775,7 +774,7 @@ def adapter(self, request): class Api(object): - def __init__(self, url, config, name, title, read_method='GET', read_filter_method='POST', + def __init__(self, url, config, name, title, version, read_method='GET', read_filter_method='POST', create_method='POST', update_method='PUT', delete_method='DELETE', description=None, terms_of_service=None, contact=None, api_license=None, server_description=None): """ @@ -795,7 +794,8 @@ def __init__(self, url, config, name, title, read_method='GET', read_filter_meth between other api's. This name must be unique all over the application. If not an error will be thrown on application start up. title (str): The title of the API. This can be a speaking title in the terms of - spec.openapis.org/oas/v3.0.3 + https://spec.openapis.org/oas/v3.0.3#info-object + version (str): https://spec.openapis.org/oas/v3.0.3#info-object read_method (str): The HTTP method which is used to match the routing to the API. read_filter_method (str): The HTTP method which is used to match the routing to the API. create_method (str): The HTTP method which is used to match the routing to the API. @@ -819,7 +819,7 @@ def __init__(self, url, config, name, title, read_method='GET', read_filter_meth self.create_method = create_method self.update_method = update_method self.delete_method = delete_method - self.version = VERSION + self.version = version self.title = title self.description = description self.terms_of_service = terms_of_service diff --git a/setup.py b/setup.py index 2401d18..10745f5 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,6 @@ import os from setuptools import setup, find_packages -from pyramid_georest import VERSION here = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(here, 'README.md')) as f: @@ -33,7 +32,7 @@ setup( name='pyramid_georest', - version=VERSION, + version="4.0.0", description='pyramid_georest, extension for pyramid web frame work to provide rest interface for ' 'sql-alchemy mappers', long_description=README + '\n\n' + CHANGES, From 5db360d9c379ff3a92ca27737e085260c702628a Mon Sep 17 00:00:00 2001 From: vvmruder Date: Fri, 20 Mar 2020 14:35:33 +0100 Subject: [PATCH 3/5] Update openapi.py --- pyramid_georest/lib/openapi.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyramid_georest/lib/openapi.py b/pyramid_georest/lib/openapi.py index 851025f..d403da0 100644 --- a/pyramid_georest/lib/openapi.py +++ b/pyramid_georest/lib/openapi.py @@ -517,5 +517,3 @@ def __init__(self, info, servers, paths): self['paths'] = {} for path in paths: self['paths'][path.service_path] = path - - From c734e9c56faff029600fa1520c3a616e2153c226 Mon Sep 17 00:00:00 2001 From: Clemens Rudert Date: Fri, 20 Mar 2020 15:41:46 +0100 Subject: [PATCH 4/5] fix bug where dict access was wrong, fix lint issue --- pyramid_georest/lib/rest.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyramid_georest/lib/rest.py b/pyramid_georest/lib/rest.py index 9f54cd7..c47a50b 100644 --- a/pyramid_georest/lib/rest.py +++ b/pyramid_georest/lib/rest.py @@ -6,8 +6,8 @@ from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest from pyramid.renderers import render_to_response from pyramid_georest.lib.description import ModelDescription -from pyramid_georest.lib.openapi import Contact, License, OpenApi, Info, Server, Paths, PathItems, Operation, \ - Responses, Response +from pyramid_georest.lib.openapi import Contact, License, OpenApi, Info, Server, Paths, PathItems, \ + Operation, Responses, Response from pyramid_georest.lib.renderer import RenderProxy, AdapterProxy from pyramid_georest.lib.database import Connection from pyramid_georest.routes import create_api_routing, check_route_prefix @@ -967,11 +967,12 @@ def open_api(self, request): pyramid.response.Response: An pyramid response object """ paths = [] - for service in self.services: + for service_key in self.services.keys(): + service = self.services[service_key] for render_format in service.renderer_proxy._format_to_renderer.keys(): paths.append(Paths('/{schema_name}/{table_name}/read/{format}'.format( - schema_name=service.name.split(',')[0], - table_name=service.name.split(',')[1], + schema_name=service_key.split(',')[0], + table_name=service_key.split(',')[1], format=render_format ), PathItems( summary='Reads a defined ammount of records from {}.{} table.'.format( From 8345945e4a930bb44bc2970c8dbfbc883560c8c3 Mon Sep 17 00:00:00 2001 From: Clemens Rudert Date: Thu, 23 Jul 2020 14:16:29 +0200 Subject: [PATCH 5/5] add openapi implementation --- pyramid_georest/lib/description.py | 16 + pyramid_georest/lib/openapi.py | 317 +++++++++++------- pyramid_georest/lib/openapi3/__init__.py | 82 +++++ .../openapi3/_a_p_i_key_security_scheme.py | 11 + .../_authorization_code_o_auth_flow.py | 11 + pyramid_georest/lib/openapi3/_callback.py | 8 + .../lib/openapi3/_client_credentials_flow.py | 10 + pyramid_georest/lib/openapi3/_components.py | 16 + pyramid_georest/lib/openapi3/_contact.py | 10 + .../lib/openapi3/_discriminator.py | 9 + pyramid_georest/lib/openapi3/_encoding.py | 12 + pyramid_georest/lib/openapi3/_example.py | 11 + .../lib/openapi3/_example_x_o_r_examples.py | 10 + .../lib/openapi3/_external_documentation.py | 9 + .../lib/openapi3/_h_t_t_p_security_scheme.py | 11 + pyramid_georest/lib/openapi3/_header.py | 18 + .../lib/openapi3/_implicit_o_auth_flow.py | 10 + pyramid_georest/lib/openapi3/_info.py | 13 + pyramid_georest/lib/openapi3/_license.py | 9 + pyramid_georest/lib/openapi3/_link.py | 13 + pyramid_georest/lib/openapi3/_media_type.py | 11 + .../lib/openapi3/_o_auth_2_security_scheme.py | 10 + pyramid_georest/lib/openapi3/_o_auth_flows.py | 11 + .../lib/openapi3/_open_api_document.py | 17 + .../_open_id_connect_security_scheme.py | 10 + pyramid_georest/lib/openapi3/_operation.py | 19 ++ pyramid_georest/lib/openapi3/_parameter.py | 20 ++ .../lib/openapi3/_parameter_location.py | 10 + .../lib/openapi3/_password_o_auth_flow.py | 10 + pyramid_georest/lib/openapi3/_path_item.py | 12 + pyramid_georest/lib/openapi3/_paths.py | 8 + pyramid_georest/lib/openapi3/_reference.py | 8 + pyramid_georest/lib/openapi3/_request_body.py | 10 + pyramid_georest/lib/openapi3/_response.py | 11 + pyramid_georest/lib/openapi3/_responses.py | 8 + pyramid_georest/lib/openapi3/_schema.py | 42 +++ .../lib/openapi3/_schema_x_o_r_content.py | 10 + .../lib/openapi3/_security_requirement.py | 8 + .../lib/openapi3/_security_scheme.py | 8 + pyramid_georest/lib/openapi3/_server.py | 10 + .../lib/openapi3/_server_variable.py | 10 + pyramid_georest/lib/openapi3/_tag.py | 10 + pyramid_georest/lib/openapi3/_x_m_l.py | 12 + pyramid_georest/lib/renderer.py | 47 ++- pyramid_georest/lib/rest.py | 25 +- 45 files changed, 826 insertions(+), 137 deletions(-) create mode 100644 pyramid_georest/lib/openapi3/__init__.py create mode 100644 pyramid_georest/lib/openapi3/_a_p_i_key_security_scheme.py create mode 100644 pyramid_georest/lib/openapi3/_authorization_code_o_auth_flow.py create mode 100644 pyramid_georest/lib/openapi3/_callback.py create mode 100644 pyramid_georest/lib/openapi3/_client_credentials_flow.py create mode 100644 pyramid_georest/lib/openapi3/_components.py create mode 100644 pyramid_georest/lib/openapi3/_contact.py create mode 100644 pyramid_georest/lib/openapi3/_discriminator.py create mode 100644 pyramid_georest/lib/openapi3/_encoding.py create mode 100644 pyramid_georest/lib/openapi3/_example.py create mode 100644 pyramid_georest/lib/openapi3/_example_x_o_r_examples.py create mode 100644 pyramid_georest/lib/openapi3/_external_documentation.py create mode 100644 pyramid_georest/lib/openapi3/_h_t_t_p_security_scheme.py create mode 100644 pyramid_georest/lib/openapi3/_header.py create mode 100644 pyramid_georest/lib/openapi3/_implicit_o_auth_flow.py create mode 100644 pyramid_georest/lib/openapi3/_info.py create mode 100644 pyramid_georest/lib/openapi3/_license.py create mode 100644 pyramid_georest/lib/openapi3/_link.py create mode 100644 pyramid_georest/lib/openapi3/_media_type.py create mode 100644 pyramid_georest/lib/openapi3/_o_auth_2_security_scheme.py create mode 100644 pyramid_georest/lib/openapi3/_o_auth_flows.py create mode 100644 pyramid_georest/lib/openapi3/_open_api_document.py create mode 100644 pyramid_georest/lib/openapi3/_open_id_connect_security_scheme.py create mode 100644 pyramid_georest/lib/openapi3/_operation.py create mode 100644 pyramid_georest/lib/openapi3/_parameter.py create mode 100644 pyramid_georest/lib/openapi3/_parameter_location.py create mode 100644 pyramid_georest/lib/openapi3/_password_o_auth_flow.py create mode 100644 pyramid_georest/lib/openapi3/_path_item.py create mode 100644 pyramid_georest/lib/openapi3/_paths.py create mode 100644 pyramid_georest/lib/openapi3/_reference.py create mode 100644 pyramid_georest/lib/openapi3/_request_body.py create mode 100644 pyramid_georest/lib/openapi3/_response.py create mode 100644 pyramid_georest/lib/openapi3/_responses.py create mode 100644 pyramid_georest/lib/openapi3/_schema.py create mode 100644 pyramid_georest/lib/openapi3/_schema_x_o_r_content.py create mode 100644 pyramid_georest/lib/openapi3/_security_requirement.py create mode 100644 pyramid_georest/lib/openapi3/_security_scheme.py create mode 100644 pyramid_georest/lib/openapi3/_server.py create mode 100644 pyramid_georest/lib/openapi3/_server_variable.py create mode 100644 pyramid_georest/lib/openapi3/_tag.py create mode 100644 pyramid_georest/lib/openapi3/_x_m_l.py diff --git a/pyramid_georest/lib/description.py b/pyramid_georest/lib/description.py index da5b2f3..62a53be 100644 --- a/pyramid_georest/lib/description.py +++ b/pyramid_georest/lib/description.py @@ -5,6 +5,8 @@ from yaml import load from pyramid.path import AssetResolver +from pyramid_georest.lib.openapi import Schema + def translate(string_to_translate, dictionary, lang='de'): """ @@ -361,3 +363,17 @@ def is_valid_column(self, column_name): return True else: return False + + def open_api(self): + description = self.as_dict() + schema = { + 'type': 'object', + 'properties': {} + } + required = [] + for column_name in description['columns'].keys(): + if not description['columns'][column_name]['nullable']: + required.append(column_name) + if len(required) > 0: + schema['required'] = required + return Schema(schema) diff --git a/pyramid_georest/lib/openapi.py b/pyramid_georest/lib/openapi.py index d403da0..d2bf653 100644 --- a/pyramid_georest/lib/openapi.py +++ b/pyramid_georest/lib/openapi.py @@ -7,12 +7,13 @@ class Contact(dict): def __init__(self, name=None, url=None, email=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#contactObject + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#contactObject Args: - name (str or None): see https://spec.openapis.org/oas/v3.0.3 - url (str or None): see https://spec.openapis.org/oas/v3.0.3 - email (str ro None): see https://spec.openapis.org/oas/v3.0.3 + name (str or None): see doc link above + url (str or None): see doc link above + email (str ro None): see doc link above """ super().__init__() if name: @@ -26,11 +27,12 @@ def __init__(self, name=None, url=None, email=None): class License(dict): def __init__(self, name=None, url=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#licenseObject + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#licenseObject Args: - name (str or None): see https://spec.openapis.org/oas/v3.0.3 - url (str or None): see https://spec.openapis.org/oas/v3.0.3 + name (str or None): see doc link above + url (str or None): see doc link above """ super().__init__() if name: @@ -44,15 +46,16 @@ class Info(dict): def __init__(self, title, version, description=None, terms_of_service=None, contact=None, api_license=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#infoObject + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#infoObject Args: - title (str): see https://spec.openapis.org/oas/v3.0.3#infoObject - version (str): see https://spec.openapis.org/oas/v3.0.3#infoObject - description (str or None): see https://spec.openapis.org/oas/v3.0.3#infoObject - terms_of_service (str or None): see https://spec.openapis.org/oas/v3.0.3#infoObject - contact (Contact or None): see https://spec.openapis.org/oas/v3.0.3#infoObject - api_license (License or None): see https://spec.openapis.org/oas/v3.0.3#infoObject + title (str): see doc link above + version (str): see doc link above + description (str or None): see doc link above + terms_of_service (str or None): see doc link above + contact (Contact or None): see doc link above + api_license (License or None): see doc link above """ super().__init__() self['title'] = title @@ -71,13 +74,15 @@ class ServerVariable(dict): def __init__(self, key, default, enum=None, description=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#server-variable-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md + #serverVariableObject Args: key (str): The key which is used then as key for parent elements. - default (str): see https://spec.openapis.org/oas/v3.0.3#server-variable-object - enum (list of str or None): see https://spec.openapis.org/oas/v3.0.3#server-variable-object - description (str or None): see https://spec.openapis.org/oas/v3.0.3#server-variable-object + default (str): see doc link above + enum (list of str or None): see doc link above + description (str or None): see doc link above """ super().__init__() self.key = key @@ -92,12 +97,13 @@ class Server(dict): def __init__(self, url, description=None, variables=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#server-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#serverObject Args: - url (str): see https://spec.openapis.org/oas/v3.0.3#server-object - description (str or None): see https://spec.openapis.org/oas/v3.0.3#server-object - variables (list of ServerVariable or None): see https://spec.openapis.org/oas/v3.0.3#server-object + url (str): see doc link above + description (str or None): see doc link above + variables (list of ServerVariable or None): see doc link above """ super().__init__() self['url'] = url @@ -110,7 +116,20 @@ def __init__(self, url, description=None, variables=None): class Schema(dict): - pass + + def __init__(self, definition): + """ + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#schemaObject + We simply offer full dictionary freedom here since the schemaObject almost does. So please rely on the + documentation strongly! + + This definition is added only to have a library internal point of wrapping. + + Args: + definition (dict): The schema definition as a python dict. Please rely to the docs linked above. + """ + super().__init__(definition) class Header(dict): @@ -120,27 +139,27 @@ def __init__(self, key, name=None, in_location=None, description=None, required= allow_empty_value=False, style=None, explode=False, allow_reserved=False, schema=None, example=None, examples=None, content=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#parameter-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#parameterObject Args: key (str): The key which is used then as key for parent elements. - name (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - in_location (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - description (str or None): see - https://spec.openapis.org/oas/v3.0.3#external-documentation-object - required (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - deprecated (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - allow_empty_value (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - style (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - explode (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - allow_reserved (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - schema (Schema or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - example (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - examples (list of Example or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - content (list of MediaType or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + name (str or None): see doc link above + in_location (str or None): see doc link above + description (str or None): see doc link above + required (bool): see doc link above + deprecated (bool): see doc link above + allow_empty_value (bool): see doc link above + style (str or None): see doc link above + explode (bool): see doc link above + allow_reserved (bool): see doc link above + schema (Schema or None): see doc link above + example (str or None): see doc link above + examples (list of Example or None): see doc link above + content (list of MediaType or None): see doc link above """ # TODO: implement correct behaviour like it is described in - # https://spec.openapis.org/oas/v3.0.3#parameter-object + # https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#parameterObject super().__init__() self.key = key self['name'] = name @@ -178,14 +197,15 @@ class Example(dict): def __init__(self, key, summary=None, description=None, value=None, external_value=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#example-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#exampleObject Args: key (str): The key which is used then as key for parent elements. - summary (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object - description (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object - value (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object - external_value (str or None): see https://spec.openapis.org/oas/v3.0.3#example-object + summary (str or None): see doc link above + description (str or None): see doc link above + value (str or None): see doc link above + external_value (str or None): see doc link above """ super().__init__() self.key = key @@ -203,14 +223,15 @@ class Encoding(dict): def __init__(self, key, content_type=None, headers=None, style=None, explode=False, allow_reserved=False): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#encodingObject + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#encodingObject Args: key (str): The key which is used then as key for parent elements. - content_type (str or None): see https://spec.openapis.org/oas/v3.0.3#encodingObject - headers (list of Header or None): see https://spec.openapis.org/oas/v3.0.3#encodingObject - style (str or None): see https://spec.openapis.org/oas/v3.0.3#encodingObject - explode (bool): see https://spec.openapis.org/oas/v3.0.3#encodingObject + content_type (str or None): see doc link above + headers (list of Header or None): see doc link above + style (str or None): see doc link above + explode (bool): see doc link above """ super().__init__() self.key = key @@ -229,14 +250,15 @@ def __init__(self, key, content_type=None, headers=None, style=None, explode=Fal class MediaType(dict): def __init__(self, key, schema=None, example=None, examples=None, encoding=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#media-type-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#mediaTypeObject Args: key (str): The key which is used then as key for parent elements. - schema (Schema or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object - example (str or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object - examples (list of Example or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object - encoding (list of Encoding or None): see https://spec.openapis.org/oas/v3.0.3#media-type-object + schema (Schema or None): see doc link above + example (str or None): see doc link above + examples (list of Example or None): see doc link above + encoding (list of Encoding or None): see doc link above """ super().__init__() self.key = key @@ -261,15 +283,16 @@ class Link(dict): class Response(dict): def __init__(self, code, description, headers=None, content=None, links=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#response-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#responseObject Args: - code (str): see https://spec.openapis.org/oas/v3.0.3#http-status-codes and - https://spec.openapis.org/oas/v3.0.3#responses-object - description (str): see https://spec.openapis.org/oas/v3.0.3#response-object - headers (list of Header or None): see https://spec.openapis.org/oas/v3.0.3#response-object - content (list of MediaType or None): see https://spec.openapis.org/oas/v3.0.3#response-object - links (list of Link or None): see https://spec.openapis.org/oas/v3.0.3#response-object + code (str): see doc link above and + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#httpCodes + description (str): see doc link above + headers (list of Header or None): see doc link above + content (list of MediaType or None): see doc link above + links (list of Link or None): see doc link above """ super().__init__() self.code = code @@ -291,11 +314,12 @@ def __init__(self, code, description, headers=None, content=None, links=None): class Responses(dict): def __init__(self, responses, default=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#responses-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#responsesObject Args: - responses (list of Response): see https://spec.openapis.org/oas/v3.0.3#responses-object - default (Response or None): see https://spec.openapis.org/oas/v3.0.3#responses-object + responses (list of Response): see doc link above + default (Response or None): see doc link above """ super().__init__() if len(responses) < 1: @@ -309,12 +333,13 @@ def __init__(self, responses, default=None): class ExternalDocumentation(dict): def __init__(self, url, description=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#external-documentation-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md + #externalDocumentationObject Args: - url (str): see https://spec.openapis.org/oas/v3.0.3#external-documentation-object - description (str or None): see - https://spec.openapis.org/oas/v3.0.3#external-documentation-object + url (str): see doc link above + description (str or None): see doc link above """ super().__init__() self['url'] = url @@ -329,23 +354,23 @@ def __init__(self, name, in_location, description=None, required=False, deprecat allow_empty_value=False, style=None, explode=False, allow_reserved=False, schema=None, example=None, examples=None, content=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#parameter-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#parameterObject Args: - name (str): see https://spec.openapis.org/oas/v3.0.3#parameter-object - in_location (str): see https://spec.openapis.org/oas/v3.0.3#parameter-object - description (str or None): see - https://spec.openapis.org/oas/v3.0.3#external-documentation-object - required (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - deprecated (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - allow_empty_value (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - style (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - explode (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - allow_reserved (bool): see https://spec.openapis.org/oas/v3.0.3#parameter-object - schema (Schema or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - example (str or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - examples (list of Example or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object - content (list of MediaType or None): see https://spec.openapis.org/oas/v3.0.3#parameter-object + name (str): see doc link above + in_location (str): see doc link above + description (str or None): see doc link above + required (bool): see doc link above + deprecated (bool): see doc link above + allow_empty_value (bool): see doc link above + style (str or None): see doc link above + explode (bool): see doc link above + allow_reserved (bool): see doc link above + schema (Schema or None): see doc link above + example (str or None): see doc link above + examples (list of Example or None): see doc link above + content (list of MediaType or None): see doc link above """ super().__init__('', name, in_location, description=description, required=required, deprecated=deprecated, allow_empty_value=allow_empty_value, style=style, @@ -356,12 +381,13 @@ def __init__(self, name, in_location, description=None, required=False, deprecat class RequestBody(dict): def __init__(self, content, description=None, required=False): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#request-body-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#requestBodyObject Args: - content (list of MediaType): see https://spec.openapis.org/oas/v3.0.3#request-body-object - description (str or None): see https://spec.openapis.org/oas/v3.0.3#request-body-object - required (bool): see https://spec.openapis.org/oas/v3.0.3#request-body-object + content (list of MediaType): see doc link above + description (str or None): see doc link above + required (bool): see doc link above """ super().__init__() self['required'] = required @@ -373,12 +399,14 @@ def __init__(self, content, description=None, required=False): class Callback(dict): - # TODO: implement like described here: https://spec.openapis.org/oas/v3.0.3#callback-object + # TODO: implement like described here: + # https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#callbackObject pass class SecurityRequirement(dict): - # TODO: implement like described here: http://spec.openapis.org/oas/v3.0.3#security-requirement-object + # TODO: implement like described here: + # http://spec.openapis.org/oas/v3.0.3#securityRequirementObject pass @@ -388,23 +416,22 @@ def __init__(self, responses, tags=None, summary=None, description=None, externa operation_id=None, parameters=None, request_body=None, callbacks=None, deprecated=False, security=None, servers=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#operation-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#operationObject Args: - responses (Responses) : see https://spec.openapis.org/oas/v3.0.3#operation-object - tags (list of str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object - summary (str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object - description (str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object - external_docs (ExternalDocumentation or None: see - https://spec.openapis.org/oas/v3.0.3#operation-object - operation_id (str or None): see https://spec.openapis.org/oas/v3.0.3#operation-object - parameters (list of Parameter or None): see https://spec.openapis.org/oas/v3.0.3#operation-object - request_body (RequestBody or None): see https://spec.openapis.org/oas/v3.0.3#operation-object - callbacks(list of Callback or None): see https://spec.openapis.org/oas/v3.0.3#operation-object - deprecated (bool): see https://spec.openapis.org/oas/v3.0.3#operation-object - security (list of SecurityRequirement or None): see - https://spec.openapis.org/oas/v3.0.3#operation-object - servers (list of Server or None): see https://spec.openapis.org/oas/v3.0.3#operation-object + responses (Responses) : see doc link above + tags (list of str or None): see doc link above + summary (str or None): see doc link above + description (str or None): see doc link above + external_docs (ExternalDocumentation or None: see doc link above + operation_id (str or None): see doc link above + parameters (list of Parameter or None): see doc link above + request_body (RequestBody or None): see doc link above + callbacks(list of Callback or None): see doc link above + deprecated (bool): see doc link above + security (list of SecurityRequirement or None): see doc link above + servers (list of Server or None): see doc link above """ super().__init__() self['responses'] = responses @@ -438,22 +465,23 @@ class PathItems(dict): def __init__(self, ref=None, summary=None, description=None, get=None, put=None, post=None, delete=None, options=None, head=None, patch=None, trace=None, servers=None, parameters=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#path-item-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#pathItemObject Args: - ref (str or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - summary (str or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - description (str or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - get (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - put (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - post (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - delete (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - options (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - head (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - patch (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - trace (Operation or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - servers (list of Server or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object - parameters (list of Parameter or None): see https://spec.openapis.org/oas/v3.0.3#path-item-object + ref (str or None): see doc link above + summary (str or None): see doc link above + description (str or None): see doc link above + get (Operation or None): see doc link above + put (Operation or None): see doc link above + post (Operation or None): see doc link above + delete (Operation or None): see doc link above + options (Operation or None): see doc link above + head (Operation or None): see doc link above + patch (Operation or None): see doc link above + trace (Operation or None): see doc link above + servers (list of Server or None): see doc link above + parameters (list of Parameter or None): see doc link above """ super().__init__() if ref: @@ -488,27 +516,58 @@ class Paths(dict): def __init__(self, service_path, path_item): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#paths-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#pathsObject Args: service_path (str): The sub path of the service. It is used as key to store all available operations below. - path_item (PathItem): see https://spec.openapis.org/oas/v3.0.3#paths-object + path_item (PathItem): see doc link above """ super().__init__(path_item) self.service_path = service_path +class Components(dict): + pass + + +class Tag(dict): + + def __init__(self, name, description=None, external_docs=None): + """ + Implemenation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#tagObject + + Args: + name (str): see doc link above + description (str): see doc link above + external_docs (ExternalDocumentation): see doc link above + """ + super().__init__() + self['name'] = name + if description: + self['description'] = description + if external_docs: + self['externalDocs'] = external_docs + + class OpenApi(dict): - def __init__(self, info, servers, paths): + def __init__(self, info, servers, paths, components=None, external_docs=None, security=None, tags=None): """ - Implementation of https://spec.openapis.org/oas/v3.0.3#openapi-object + Implementation of + https://github.com/OAI/OpenAPI-Specification/blob/v3.0.3-dev/versions/3.0.3.md#oasObject Args: - info (Info): see https://spec.openapis.org/oas/v3.0.3#openapi-object - servers (list of Server): see https://spec.openapis.org/oas/v3.0.3#openapi-object - paths (list of Paths): see https://spec.openapis.org/oas/v3.0.3#openapi-object + info (Info): see doc link above + servers (list of Server): see doc link above + paths (list of Paths): see doc link above + components (Components): see doc link above + external_docs (ExternalDocumentation): see doc link above + security (list of SecurityRequirement): see doc link above + tags (list of Tag): see doc link above + """ super().__init__() self['openapi'] = VERSION @@ -517,3 +576,11 @@ def __init__(self, info, servers, paths): self['paths'] = {} for path in paths: self['paths'][path.service_path] = path + if components: + self['components'] = components + if external_docs: + self['externalDocs'] = external_docs + if security: + self['security'] = security + if tags: + self['tags'] = tags diff --git a/pyramid_georest/lib/openapi3/__init__.py b/pyramid_georest/lib/openapi3/__init__.py new file mode 100644 index 0000000..480d904 --- /dev/null +++ b/pyramid_georest/lib/openapi3/__init__.py @@ -0,0 +1,82 @@ +# This file was generated by jschema_to_python version 1.2.3. + +#### OpenApiDocument +from pyramid_georest.lib.openapi3._open_api_document import OpenApiDocument +#### APIKeySecurityScheme +from pyramid_georest.lib.openapi3._a_p_i_key_security_scheme import APIKeySecurityScheme +#### AuthorizationCodeOAuthFlow +from pyramid_georest.lib.openapi3._authorization_code_o_auth_flow import AuthorizationCodeOAuthFlow +#### Callback +from pyramid_georest.lib.openapi3._callback import Callback +#### ClientCredentialsFlow +from pyramid_georest.lib.openapi3._client_credentials_flow import ClientCredentialsFlow +#### Components +from pyramid_georest.lib.openapi3._components import Components +#### Contact +from pyramid_georest.lib.openapi3._contact import Contact +#### Discriminator +from pyramid_georest.lib.openapi3._discriminator import Discriminator +#### Encoding +from pyramid_georest.lib.openapi3._encoding import Encoding +#### Example +from pyramid_georest.lib.openapi3._example import Example +#### ExampleXORExamples +from pyramid_georest.lib.openapi3._example_x_o_r_examples import ExampleXORExamples +#### ExternalDocumentation +from pyramid_georest.lib.openapi3._external_documentation import ExternalDocumentation +#### HTTPSecurityScheme +from pyramid_georest.lib.openapi3._h_t_t_p_security_scheme import HTTPSecurityScheme +#### Header +from pyramid_georest.lib.openapi3._header import Header +#### ImplicitOAuthFlow +from pyramid_georest.lib.openapi3._implicit_o_auth_flow import ImplicitOAuthFlow +#### Info +from pyramid_georest.lib.openapi3._info import Info +#### License +from pyramid_georest.lib.openapi3._license import License +#### Link +from pyramid_georest.lib.openapi3._link import Link +#### MediaType +from pyramid_georest.lib.openapi3._media_type import MediaType +#### OAuth2SecurityScheme +from pyramid_georest.lib.openapi3._o_auth_2_security_scheme import OAuth2SecurityScheme +#### OAuthFlows +from pyramid_georest.lib.openapi3._o_auth_flows import OAuthFlows +#### OpenIdConnectSecurityScheme +from pyramid_georest.lib.openapi3._open_id_connect_security_scheme import OpenIdConnectSecurityScheme +#### Operation +from pyramid_georest.lib.openapi3._operation import Operation +#### Parameter +from pyramid_georest.lib.openapi3._parameter import Parameter +#### ParameterLocation +from pyramid_georest.lib.openapi3._parameter_location import ParameterLocation +#### PasswordOAuthFlow +from pyramid_georest.lib.openapi3._password_o_auth_flow import PasswordOAuthFlow +#### PathItem +from pyramid_georest.lib.openapi3._path_item import PathItem +#### Paths +from pyramid_georest.lib.openapi3._paths import Paths +#### Reference +from pyramid_georest.lib.openapi3._reference import Reference +#### RequestBody +from pyramid_georest.lib.openapi3._request_body import RequestBody +#### Response +from pyramid_georest.lib.openapi3._response import Response +#### Responses +from pyramid_georest.lib.openapi3._responses import Responses +#### Schema +from pyramid_georest.lib.openapi3._schema import Schema +#### SchemaXORContent +from pyramid_georest.lib.openapi3._schema_x_o_r_content import SchemaXORContent +#### SecurityRequirement +from pyramid_georest.lib.openapi3._security_requirement import SecurityRequirement +#### SecurityScheme +from pyramid_georest.lib.openapi3._security_scheme import SecurityScheme +#### Server +from pyramid_georest.lib.openapi3._server import Server +#### ServerVariable +from pyramid_georest.lib.openapi3._server_variable import ServerVariable +#### Tag +from pyramid_georest.lib.openapi3._tag import Tag +#### XML +from pyramid_georest.lib.openapi3._x_m_l import XML diff --git a/pyramid_georest/lib/openapi3/_a_p_i_key_security_scheme.py b/pyramid_georest/lib/openapi3/_a_p_i_key_security_scheme.py new file mode 100644 index 0000000..d4570ff --- /dev/null +++ b/pyramid_georest/lib/openapi3/_a_p_i_key_security_scheme.py @@ -0,0 +1,11 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class APIKeySecurityScheme(object): + in = attr.ib(metadata={"schema_property_name": "in"}) + name = attr.ib(metadata={"schema_property_name": "name"}) + type = attr.ib(metadata={"schema_property_name": "type"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) diff --git a/pyramid_georest/lib/openapi3/_authorization_code_o_auth_flow.py b/pyramid_georest/lib/openapi3/_authorization_code_o_auth_flow.py new file mode 100644 index 0000000..4fd5894 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_authorization_code_o_auth_flow.py @@ -0,0 +1,11 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class AuthorizationCodeOAuthFlow(object): + authorization_url = attr.ib(metadata={"schema_property_name": "authorizationUrl"}) + token_url = attr.ib(metadata={"schema_property_name": "tokenUrl"}) + refresh_url = attr.ib(default=None, metadata={"schema_property_name": "refreshUrl"}) + scopes = attr.ib(default=None, metadata={"schema_property_name": "scopes"}) diff --git a/pyramid_georest/lib/openapi3/_callback.py b/pyramid_georest/lib/openapi3/_callback.py new file mode 100644 index 0000000..91d3a9f --- /dev/null +++ b/pyramid_georest/lib/openapi3/_callback.py @@ -0,0 +1,8 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Callback(object): + pass diff --git a/pyramid_georest/lib/openapi3/_client_credentials_flow.py b/pyramid_georest/lib/openapi3/_client_credentials_flow.py new file mode 100644 index 0000000..5cc681a --- /dev/null +++ b/pyramid_georest/lib/openapi3/_client_credentials_flow.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class ClientCredentialsFlow(object): + token_url = attr.ib(metadata={"schema_property_name": "tokenUrl"}) + refresh_url = attr.ib(default=None, metadata={"schema_property_name": "refreshUrl"}) + scopes = attr.ib(default=None, metadata={"schema_property_name": "scopes"}) diff --git a/pyramid_georest/lib/openapi3/_components.py b/pyramid_georest/lib/openapi3/_components.py new file mode 100644 index 0000000..994d570 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_components.py @@ -0,0 +1,16 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Components(object): + callbacks = attr.ib(default=None, metadata={"schema_property_name": "callbacks"}) + examples = attr.ib(default=None, metadata={"schema_property_name": "examples"}) + headers = attr.ib(default=None, metadata={"schema_property_name": "headers"}) + links = attr.ib(default=None, metadata={"schema_property_name": "links"}) + parameters = attr.ib(default=None, metadata={"schema_property_name": "parameters"}) + request_bodies = attr.ib(default=None, metadata={"schema_property_name": "requestBodies"}) + responses = attr.ib(default=None, metadata={"schema_property_name": "responses"}) + schemas = attr.ib(default=None, metadata={"schema_property_name": "schemas"}) + security_schemes = attr.ib(default=None, metadata={"schema_property_name": "securitySchemes"}) diff --git a/pyramid_georest/lib/openapi3/_contact.py b/pyramid_georest/lib/openapi3/_contact.py new file mode 100644 index 0000000..098596b --- /dev/null +++ b/pyramid_georest/lib/openapi3/_contact.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Contact(object): + email = attr.ib(default=None, metadata={"schema_property_name": "email"}) + name = attr.ib(default=None, metadata={"schema_property_name": "name"}) + url = attr.ib(default=None, metadata={"schema_property_name": "url"}) diff --git a/pyramid_georest/lib/openapi3/_discriminator.py b/pyramid_georest/lib/openapi3/_discriminator.py new file mode 100644 index 0000000..0d0f4b9 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_discriminator.py @@ -0,0 +1,9 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Discriminator(object): + property_name = attr.ib(metadata={"schema_property_name": "propertyName"}) + mapping = attr.ib(default=None, metadata={"schema_property_name": "mapping"}) diff --git a/pyramid_georest/lib/openapi3/_encoding.py b/pyramid_georest/lib/openapi3/_encoding.py new file mode 100644 index 0000000..ea0a524 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_encoding.py @@ -0,0 +1,12 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Encoding(object): + allow_reserved = attr.ib(default=None, metadata={"schema_property_name": "allowReserved"}) + content_type = attr.ib(default=None, metadata={"schema_property_name": "contentType"}) + explode = attr.ib(default=None, metadata={"schema_property_name": "explode"}) + headers = attr.ib(default=None, metadata={"schema_property_name": "headers"}) + style = attr.ib(default=None, metadata={"schema_property_name": "style"}) diff --git a/pyramid_georest/lib/openapi3/_example.py b/pyramid_georest/lib/openapi3/_example.py new file mode 100644 index 0000000..c2fc9d3 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_example.py @@ -0,0 +1,11 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Example(object): + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + external_value = attr.ib(default=None, metadata={"schema_property_name": "externalValue"}) + summary = attr.ib(default=None, metadata={"schema_property_name": "summary"}) + value = attr.ib(default=None, metadata={"schema_property_name": "value"}) diff --git a/pyramid_georest/lib/openapi3/_example_x_o_r_examples.py b/pyramid_georest/lib/openapi3/_example_x_o_r_examples.py new file mode 100644 index 0000000..a3cbb9f --- /dev/null +++ b/pyramid_georest/lib/openapi3/_example_x_o_r_examples.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class ExampleXORExamples(object): + """Example and examples are mutually exclusive""" + + pass diff --git a/pyramid_georest/lib/openapi3/_external_documentation.py b/pyramid_georest/lib/openapi3/_external_documentation.py new file mode 100644 index 0000000..35ee06f --- /dev/null +++ b/pyramid_georest/lib/openapi3/_external_documentation.py @@ -0,0 +1,9 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class ExternalDocumentation(object): + url = attr.ib(metadata={"schema_property_name": "url"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) diff --git a/pyramid_georest/lib/openapi3/_h_t_t_p_security_scheme.py b/pyramid_georest/lib/openapi3/_h_t_t_p_security_scheme.py new file mode 100644 index 0000000..e466c2d --- /dev/null +++ b/pyramid_georest/lib/openapi3/_h_t_t_p_security_scheme.py @@ -0,0 +1,11 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class HTTPSecurityScheme(object): + scheme = attr.ib(metadata={"schema_property_name": "scheme"}) + type = attr.ib(metadata={"schema_property_name": "type"}) + bearer_format = attr.ib(default=None, metadata={"schema_property_name": "bearerFormat"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) diff --git a/pyramid_georest/lib/openapi3/_header.py b/pyramid_georest/lib/openapi3/_header.py new file mode 100644 index 0000000..76b786a --- /dev/null +++ b/pyramid_georest/lib/openapi3/_header.py @@ -0,0 +1,18 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Header(object): + allow_empty_value = attr.ib(default=None, metadata={"schema_property_name": "allowEmptyValue"}) + allow_reserved = attr.ib(default=None, metadata={"schema_property_name": "allowReserved"}) + content = attr.ib(default=None, metadata={"schema_property_name": "content"}) + deprecated = attr.ib(default=None, metadata={"schema_property_name": "deprecated"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + example = attr.ib(default=None, metadata={"schema_property_name": "example"}) + examples = attr.ib(default=None, metadata={"schema_property_name": "examples"}) + explode = attr.ib(default=None, metadata={"schema_property_name": "explode"}) + required = attr.ib(default=None, metadata={"schema_property_name": "required"}) + schema = attr.ib(default=None, metadata={"schema_property_name": "schema"}) + style = attr.ib(default="simple", metadata={"schema_property_name": "style"}) diff --git a/pyramid_georest/lib/openapi3/_implicit_o_auth_flow.py b/pyramid_georest/lib/openapi3/_implicit_o_auth_flow.py new file mode 100644 index 0000000..43b452b --- /dev/null +++ b/pyramid_georest/lib/openapi3/_implicit_o_auth_flow.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class ImplicitOAuthFlow(object): + authorization_url = attr.ib(metadata={"schema_property_name": "authorizationUrl"}) + scopes = attr.ib(metadata={"schema_property_name": "scopes"}) + refresh_url = attr.ib(default=None, metadata={"schema_property_name": "refreshUrl"}) diff --git a/pyramid_georest/lib/openapi3/_info.py b/pyramid_georest/lib/openapi3/_info.py new file mode 100644 index 0000000..3139853 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_info.py @@ -0,0 +1,13 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Info(object): + title = attr.ib(metadata={"schema_property_name": "title"}) + version = attr.ib(metadata={"schema_property_name": "version"}) + contact = attr.ib(default=None, metadata={"schema_property_name": "contact"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + license = attr.ib(default=None, metadata={"schema_property_name": "license"}) + terms_of_service = attr.ib(default=None, metadata={"schema_property_name": "termsOfService"}) diff --git a/pyramid_georest/lib/openapi3/_license.py b/pyramid_georest/lib/openapi3/_license.py new file mode 100644 index 0000000..6da3734 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_license.py @@ -0,0 +1,9 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class License(object): + name = attr.ib(metadata={"schema_property_name": "name"}) + url = attr.ib(default=None, metadata={"schema_property_name": "url"}) diff --git a/pyramid_georest/lib/openapi3/_link.py b/pyramid_georest/lib/openapi3/_link.py new file mode 100644 index 0000000..f9db9a7 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_link.py @@ -0,0 +1,13 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Link(object): + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + operation_id = attr.ib(default=None, metadata={"schema_property_name": "operationId"}) + operation_ref = attr.ib(default=None, metadata={"schema_property_name": "operationRef"}) + parameters = attr.ib(default=None, metadata={"schema_property_name": "parameters"}) + request_body = attr.ib(default=None, metadata={"schema_property_name": "requestBody"}) + server = attr.ib(default=None, metadata={"schema_property_name": "server"}) diff --git a/pyramid_georest/lib/openapi3/_media_type.py b/pyramid_georest/lib/openapi3/_media_type.py new file mode 100644 index 0000000..23478e8 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_media_type.py @@ -0,0 +1,11 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class MediaType(object): + encoding = attr.ib(default=None, metadata={"schema_property_name": "encoding"}) + example = attr.ib(default=None, metadata={"schema_property_name": "example"}) + examples = attr.ib(default=None, metadata={"schema_property_name": "examples"}) + schema = attr.ib(default=None, metadata={"schema_property_name": "schema"}) diff --git a/pyramid_georest/lib/openapi3/_o_auth_2_security_scheme.py b/pyramid_georest/lib/openapi3/_o_auth_2_security_scheme.py new file mode 100644 index 0000000..a1477e4 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_o_auth_2_security_scheme.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class OAuth2SecurityScheme(object): + flows = attr.ib(metadata={"schema_property_name": "flows"}) + type = attr.ib(metadata={"schema_property_name": "type"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) diff --git a/pyramid_georest/lib/openapi3/_o_auth_flows.py b/pyramid_georest/lib/openapi3/_o_auth_flows.py new file mode 100644 index 0000000..fc889b9 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_o_auth_flows.py @@ -0,0 +1,11 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class OAuthFlows(object): + authorization_code = attr.ib(default=None, metadata={"schema_property_name": "authorizationCode"}) + client_credentials = attr.ib(default=None, metadata={"schema_property_name": "clientCredentials"}) + implicit = attr.ib(default=None, metadata={"schema_property_name": "implicit"}) + password = attr.ib(default=None, metadata={"schema_property_name": "password"}) diff --git a/pyramid_georest/lib/openapi3/_open_api_document.py b/pyramid_georest/lib/openapi3/_open_api_document.py new file mode 100644 index 0000000..927d9e4 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_open_api_document.py @@ -0,0 +1,17 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class OpenApiDocument(object): + """Validation schema for OpenAPI Specification 3.0.X.""" + + info = attr.ib(metadata={"schema_property_name": "info"}) + openapi = attr.ib(metadata={"schema_property_name": "openapi"}) + paths = attr.ib(metadata={"schema_property_name": "paths"}) + components = attr.ib(default=None, metadata={"schema_property_name": "components"}) + external_docs = attr.ib(default=None, metadata={"schema_property_name": "externalDocs"}) + security = attr.ib(default=None, metadata={"schema_property_name": "security"}) + servers = attr.ib(default=None, metadata={"schema_property_name": "servers"}) + tags = attr.ib(default=None, metadata={"schema_property_name": "tags"}) diff --git a/pyramid_georest/lib/openapi3/_open_id_connect_security_scheme.py b/pyramid_georest/lib/openapi3/_open_id_connect_security_scheme.py new file mode 100644 index 0000000..65bc207 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_open_id_connect_security_scheme.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class OpenIdConnectSecurityScheme(object): + open_id_connect_url = attr.ib(metadata={"schema_property_name": "openIdConnectUrl"}) + type = attr.ib(metadata={"schema_property_name": "type"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) diff --git a/pyramid_georest/lib/openapi3/_operation.py b/pyramid_georest/lib/openapi3/_operation.py new file mode 100644 index 0000000..ecca8df --- /dev/null +++ b/pyramid_georest/lib/openapi3/_operation.py @@ -0,0 +1,19 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Operation(object): + responses = attr.ib(metadata={"schema_property_name": "responses"}) + callbacks = attr.ib(default=None, metadata={"schema_property_name": "callbacks"}) + deprecated = attr.ib(default=None, metadata={"schema_property_name": "deprecated"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + external_docs = attr.ib(default=None, metadata={"schema_property_name": "externalDocs"}) + operation_id = attr.ib(default=None, metadata={"schema_property_name": "operationId"}) + parameters = attr.ib(default=None, metadata={"schema_property_name": "parameters"}) + request_body = attr.ib(default=None, metadata={"schema_property_name": "requestBody"}) + security = attr.ib(default=None, metadata={"schema_property_name": "security"}) + servers = attr.ib(default=None, metadata={"schema_property_name": "servers"}) + summary = attr.ib(default=None, metadata={"schema_property_name": "summary"}) + tags = attr.ib(default=None, metadata={"schema_property_name": "tags"}) diff --git a/pyramid_georest/lib/openapi3/_parameter.py b/pyramid_georest/lib/openapi3/_parameter.py new file mode 100644 index 0000000..f3dc2da --- /dev/null +++ b/pyramid_georest/lib/openapi3/_parameter.py @@ -0,0 +1,20 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Parameter(object): + in = attr.ib(metadata={"schema_property_name": "in"}) + name = attr.ib(metadata={"schema_property_name": "name"}) + allow_empty_value = attr.ib(default=None, metadata={"schema_property_name": "allowEmptyValue"}) + allow_reserved = attr.ib(default=None, metadata={"schema_property_name": "allowReserved"}) + content = attr.ib(default=None, metadata={"schema_property_name": "content"}) + deprecated = attr.ib(default=None, metadata={"schema_property_name": "deprecated"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + example = attr.ib(default=None, metadata={"schema_property_name": "example"}) + examples = attr.ib(default=None, metadata={"schema_property_name": "examples"}) + explode = attr.ib(default=None, metadata={"schema_property_name": "explode"}) + required = attr.ib(default=None, metadata={"schema_property_name": "required"}) + schema = attr.ib(default=None, metadata={"schema_property_name": "schema"}) + style = attr.ib(default=None, metadata={"schema_property_name": "style"}) diff --git a/pyramid_georest/lib/openapi3/_parameter_location.py b/pyramid_georest/lib/openapi3/_parameter_location.py new file mode 100644 index 0000000..52eb8bd --- /dev/null +++ b/pyramid_georest/lib/openapi3/_parameter_location.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class ParameterLocation(object): + """Parameter location""" + + pass diff --git a/pyramid_georest/lib/openapi3/_password_o_auth_flow.py b/pyramid_georest/lib/openapi3/_password_o_auth_flow.py new file mode 100644 index 0000000..878d390 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_password_o_auth_flow.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class PasswordOAuthFlow(object): + token_url = attr.ib(metadata={"schema_property_name": "tokenUrl"}) + refresh_url = attr.ib(default=None, metadata={"schema_property_name": "refreshUrl"}) + scopes = attr.ib(default=None, metadata={"schema_property_name": "scopes"}) diff --git a/pyramid_georest/lib/openapi3/_path_item.py b/pyramid_georest/lib/openapi3/_path_item.py new file mode 100644 index 0000000..045ce9c --- /dev/null +++ b/pyramid_georest/lib/openapi3/_path_item.py @@ -0,0 +1,12 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class PathItem(object): + $ref = attr.ib(default=None, metadata={"schema_property_name": "$ref"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + parameters = attr.ib(default=None, metadata={"schema_property_name": "parameters"}) + servers = attr.ib(default=None, metadata={"schema_property_name": "servers"}) + summary = attr.ib(default=None, metadata={"schema_property_name": "summary"}) diff --git a/pyramid_georest/lib/openapi3/_paths.py b/pyramid_georest/lib/openapi3/_paths.py new file mode 100644 index 0000000..d5d010e --- /dev/null +++ b/pyramid_georest/lib/openapi3/_paths.py @@ -0,0 +1,8 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Paths(object): + pass diff --git a/pyramid_georest/lib/openapi3/_reference.py b/pyramid_georest/lib/openapi3/_reference.py new file mode 100644 index 0000000..27c0844 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_reference.py @@ -0,0 +1,8 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Reference(object): + pass diff --git a/pyramid_georest/lib/openapi3/_request_body.py b/pyramid_georest/lib/openapi3/_request_body.py new file mode 100644 index 0000000..1f5dc8e --- /dev/null +++ b/pyramid_georest/lib/openapi3/_request_body.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class RequestBody(object): + content = attr.ib(metadata={"schema_property_name": "content"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + required = attr.ib(default=None, metadata={"schema_property_name": "required"}) diff --git a/pyramid_georest/lib/openapi3/_response.py b/pyramid_georest/lib/openapi3/_response.py new file mode 100644 index 0000000..b62b83b --- /dev/null +++ b/pyramid_georest/lib/openapi3/_response.py @@ -0,0 +1,11 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Response(object): + description = attr.ib(metadata={"schema_property_name": "description"}) + content = attr.ib(default=None, metadata={"schema_property_name": "content"}) + headers = attr.ib(default=None, metadata={"schema_property_name": "headers"}) + links = attr.ib(default=None, metadata={"schema_property_name": "links"}) diff --git a/pyramid_georest/lib/openapi3/_responses.py b/pyramid_georest/lib/openapi3/_responses.py new file mode 100644 index 0000000..701da3a --- /dev/null +++ b/pyramid_georest/lib/openapi3/_responses.py @@ -0,0 +1,8 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Responses(object): + default = attr.ib(default=None, metadata={"schema_property_name": "default"}) diff --git a/pyramid_georest/lib/openapi3/_schema.py b/pyramid_georest/lib/openapi3/_schema.py new file mode 100644 index 0000000..c5f792a --- /dev/null +++ b/pyramid_georest/lib/openapi3/_schema.py @@ -0,0 +1,42 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Schema(object): + additional_properties = attr.ib(default=True, metadata={"schema_property_name": "additionalProperties"}) + all_of = attr.ib(default=None, metadata={"schema_property_name": "allOf"}) + any_of = attr.ib(default=None, metadata={"schema_property_name": "anyOf"}) + default = attr.ib(default=None, metadata={"schema_property_name": "default"}) + deprecated = attr.ib(default=None, metadata={"schema_property_name": "deprecated"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + discriminator = attr.ib(default=None, metadata={"schema_property_name": "discriminator"}) + enum = attr.ib(default=None, metadata={"schema_property_name": "enum"}) + example = attr.ib(default=None, metadata={"schema_property_name": "example"}) + exclusive_maximum = attr.ib(default=None, metadata={"schema_property_name": "exclusiveMaximum"}) + exclusive_minimum = attr.ib(default=None, metadata={"schema_property_name": "exclusiveMinimum"}) + external_docs = attr.ib(default=None, metadata={"schema_property_name": "externalDocs"}) + format = attr.ib(default=None, metadata={"schema_property_name": "format"}) + items = attr.ib(default=None, metadata={"schema_property_name": "items"}) + max_items = attr.ib(default=None, metadata={"schema_property_name": "maxItems"}) + max_length = attr.ib(default=None, metadata={"schema_property_name": "maxLength"}) + max_properties = attr.ib(default=None, metadata={"schema_property_name": "maxProperties"}) + maximum = attr.ib(default=None, metadata={"schema_property_name": "maximum"}) + min_items = attr.ib(default=None, metadata={"schema_property_name": "minItems"}) + min_length = attr.ib(default=None, metadata={"schema_property_name": "minLength"}) + min_properties = attr.ib(default=None, metadata={"schema_property_name": "minProperties"}) + minimum = attr.ib(default=None, metadata={"schema_property_name": "minimum"}) + multiple_of = attr.ib(default=None, metadata={"schema_property_name": "multipleOf"}) + not = attr.ib(default=None, metadata={"schema_property_name": "not"}) + nullable = attr.ib(default=None, metadata={"schema_property_name": "nullable"}) + one_of = attr.ib(default=None, metadata={"schema_property_name": "oneOf"}) + pattern = attr.ib(default=None, metadata={"schema_property_name": "pattern"}) + properties = attr.ib(default=None, metadata={"schema_property_name": "properties"}) + read_only = attr.ib(default=None, metadata={"schema_property_name": "readOnly"}) + required = attr.ib(default=None, metadata={"schema_property_name": "required"}) + title = attr.ib(default=None, metadata={"schema_property_name": "title"}) + type = attr.ib(default=None, metadata={"schema_property_name": "type"}) + unique_items = attr.ib(default=None, metadata={"schema_property_name": "uniqueItems"}) + write_only = attr.ib(default=None, metadata={"schema_property_name": "writeOnly"}) + xml = attr.ib(default=None, metadata={"schema_property_name": "xml"}) diff --git a/pyramid_georest/lib/openapi3/_schema_x_o_r_content.py b/pyramid_georest/lib/openapi3/_schema_x_o_r_content.py new file mode 100644 index 0000000..fefec92 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_schema_x_o_r_content.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class SchemaXORContent(object): + """Schema and content are mutually exclusive, at least one is required""" + + pass diff --git a/pyramid_georest/lib/openapi3/_security_requirement.py b/pyramid_georest/lib/openapi3/_security_requirement.py new file mode 100644 index 0000000..ab64a3e --- /dev/null +++ b/pyramid_georest/lib/openapi3/_security_requirement.py @@ -0,0 +1,8 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class SecurityRequirement(object): + pass diff --git a/pyramid_georest/lib/openapi3/_security_scheme.py b/pyramid_georest/lib/openapi3/_security_scheme.py new file mode 100644 index 0000000..9c86473 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_security_scheme.py @@ -0,0 +1,8 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class SecurityScheme(object): + pass diff --git a/pyramid_georest/lib/openapi3/_server.py b/pyramid_georest/lib/openapi3/_server.py new file mode 100644 index 0000000..eaa1dbf --- /dev/null +++ b/pyramid_georest/lib/openapi3/_server.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Server(object): + url = attr.ib(metadata={"schema_property_name": "url"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + variables = attr.ib(default=None, metadata={"schema_property_name": "variables"}) diff --git a/pyramid_georest/lib/openapi3/_server_variable.py b/pyramid_georest/lib/openapi3/_server_variable.py new file mode 100644 index 0000000..5c88678 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_server_variable.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class ServerVariable(object): + default = attr.ib(metadata={"schema_property_name": "default"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + enum = attr.ib(default=None, metadata={"schema_property_name": "enum"}) diff --git a/pyramid_georest/lib/openapi3/_tag.py b/pyramid_georest/lib/openapi3/_tag.py new file mode 100644 index 0000000..1d9277a --- /dev/null +++ b/pyramid_georest/lib/openapi3/_tag.py @@ -0,0 +1,10 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class Tag(object): + name = attr.ib(metadata={"schema_property_name": "name"}) + description = attr.ib(default=None, metadata={"schema_property_name": "description"}) + external_docs = attr.ib(default=None, metadata={"schema_property_name": "externalDocs"}) diff --git a/pyramid_georest/lib/openapi3/_x_m_l.py b/pyramid_georest/lib/openapi3/_x_m_l.py new file mode 100644 index 0000000..04e07a9 --- /dev/null +++ b/pyramid_georest/lib/openapi3/_x_m_l.py @@ -0,0 +1,12 @@ +# This file was generated by jschema_to_python version 1.2.3. + +import attr + + +@attr.s +class XML(object): + attribute = attr.ib(default=None, metadata={"schema_property_name": "attribute"}) + name = attr.ib(default=None, metadata={"schema_property_name": "name"}) + namespace = attr.ib(default=None, metadata={"schema_property_name": "namespace"}) + prefix = attr.ib(default=None, metadata={"schema_property_name": "prefix"}) + wrapped = attr.ib(default=None, metadata={"schema_property_name": "wrapped"}) diff --git a/pyramid_georest/lib/renderer.py b/pyramid_georest/lib/renderer.py index abdb84c..e72fe05 100644 --- a/pyramid_georest/lib/renderer.py +++ b/pyramid_georest/lib/renderer.py @@ -8,10 +8,12 @@ from geoalchemy2 import WKBElement from geoalchemy2.shape import to_shape from pyramid.httpexceptions import HTTPNotFound, HTTPServerError -from pyramid.renderers import JSON, render_to_response +from pyramid.renderers import JSON, render_to_response, RendererHelper +from pyramid.path import caller_package from sqlalchemy.ext.associationproxy import _AssociationList +from pyramid_georest.lib.openapi import MediaType log = logging.getLogger('pyramid_georest') @@ -47,6 +49,34 @@ def __init__(self): 'geojson': 'geo_restful_geo_json' } + def open_api(self, request, model_description): + """ + Delivers information about renderers. This is used to provide openapi description. + + Args: + request (pyramid.request.Request): The request which comes all the way through the application + from the client + model_description (pyramid_georest.lib.description.ModelDescription): The description object of + the data set which will be rendered. + + Returns: + list of pyramid_georest.lib.openapi.MediaType: A list of all available media types delivered by + this API. + """ + media_types = [] + try: + registry = request.registry + except AttributeError: + registry = None + for format_key in self._format_to_renderer.keys(): + helper = RendererHelper( + name=self._format_to_renderer[format_key], + package=caller_package(), + registry=registry + ) + renderer = helper.get_renderer() + media_types.append(MediaType(renderer.content_type, )) + def render(self, request, result, model_description): """ Execute the rendering process by matching the requested format to the mapped renderer. If no @@ -201,6 +231,7 @@ class RestfulJson(JSON): them to json. It is important to use the Base which is provided by this package. Because this class delivers additional methods. """ + content_type = 'application/json' def __init__(self, info): """ Constructor: info will be an object having the @@ -224,18 +255,10 @@ def __call__(self, results, system): request = system['request'] # here the results will be serialized!!!! - val = self.to_str(results) - - callback = request.GET.get('callback') - if callback is None: - ct = 'application/json' - body = val - else: - ct = 'application/javascript' - body = '%s(%s);' % (callback, val) + body = self.to_str(results) response = request.response if response.content_type == response.default_content_type: - response.content_type = ct + response.content_type = self.content_type return body def to_str(self, results): @@ -346,6 +369,7 @@ class RestfulGeoJson(RestfulJson): renders them to json. It is important to use the Base which is provided by this package. Because this class delivers additional methods. """ + content_type = 'application/json' def __init__(self, info): """ Constructor: info will be an object having the @@ -487,6 +511,7 @@ class RestfulXML(RestfulJson): them to xml. It is important to use the Base which is provided by this package. Because this class delivers additional methods. """ + content_type = 'application/xml' def __init__(self, info): """ Constructor: info will be an object having the diff --git a/pyramid_georest/lib/rest.py b/pyramid_georest/lib/rest.py index c47a50b..a605437 100644 --- a/pyramid_georest/lib/rest.py +++ b/pyramid_georest/lib/rest.py @@ -16,6 +16,7 @@ from sqlalchemy.orm.exc import MultipleResultsFound from geoalchemy2 import WKTElement from shapely.geometry import asShape +from pyramid_georest.lib.openapi3 import OpenApiDocument log = logging.getLogger('pyramid_georest') @@ -771,6 +772,28 @@ def adapter(self, request): return self.model_description + def open_api(self): + paths = [] + for render_format in self.renderer_proxy._format_to_renderer.keys(): + paths.append(Paths('/{schema_name}/{table_name}/read/{format}'.format( + schema_name=self.model_description.schema_name, + table_name=self.model_description.table_name, + format=render_format + ), PathItems( + summary='Reads a defined ammount of records from {}.{} table.'.format( + self.model_description.schema_name, + self.model_description.table_name + ), + description='JadaJada', + get=Operation( + Responses([ + Response('200', 'Delivers desired records as {}'.format(render_format)), + Response('400', 'In case of errors.') + ]) + ) + ))) + return paths + class Api(object): @@ -996,7 +1019,7 @@ def open_api(self, request): self.contact, self.license ), [ - Server(request.route_path(self.name), description=self.server_description) + Server(request.route_url(self.name), description=self.server_description) ], paths )