mirror of
https://github.com/LukeHagar/connexion.git
synced 2025-12-06 12:27:45 +00:00
Jsonify operations that only return json
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
"*pom.xml": ["xml", "pomdesc"],
|
"*pom.xml": ["xml", "pomdesc"],
|
||||||
"*.pp": ["utf8", "nobom", "notabs", "nocr", "notrailingws", "puppet"],
|
"*.pp": ["utf8", "nobom", "notabs", "nocr", "notrailingws", "puppet"],
|
||||||
"*.properties": ["utf8", "nobom", "notabs", "nocr", "notrailingws"],
|
"*.properties": ["utf8", "nobom", "notabs", "nocr", "notrailingws"],
|
||||||
"*.py": ["utf8", "nobom", "notabs", "nocr", "notrailingws", "pyflakes", "pep8"],
|
"*.py": ["utf8", "nobom", "notabs", "nocr", "notrailingws", "pep8"],
|
||||||
"*.rst": ["utf8", "nobom", "notabs", "nocr", "notrailingws"],
|
"*.rst": ["utf8", "nobom", "notabs", "nocr", "notrailingws"],
|
||||||
"* *": ["invalidpath"],
|
"* *": ["invalidpath"],
|
||||||
"*.sh": ["utf8", "nobom", "notabs", "nocr", "notrailingws"],
|
"*.sh": ["utf8", "nobom", "notabs", "nocr", "notrailingws"],
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import types
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
import yaml
|
import yaml
|
||||||
@@ -9,6 +11,16 @@ import connexion.utils as utils
|
|||||||
logger = logging.getLogger('connexion.api')
|
logger = logging.getLogger('connexion.api')
|
||||||
|
|
||||||
|
|
||||||
|
def jsonify(function: types.FunctionType) -> types.FunctionType:
|
||||||
|
"""
|
||||||
|
Decorator to jsonify the return value of the wrapped function
|
||||||
|
"""
|
||||||
|
@functools.wraps(function)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
return flask.jsonify(function(*args, **kwargs))
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class Api:
|
class Api:
|
||||||
"""
|
"""
|
||||||
Single API that corresponds to a flask blueprint
|
Single API that corresponds to a flask blueprint
|
||||||
@@ -19,28 +31,47 @@ class Api:
|
|||||||
with swagger_yaml_path.open() as swagger_yaml:
|
with swagger_yaml_path.open() as swagger_yaml:
|
||||||
self.specification = yaml.load(swagger_yaml)
|
self.specification = yaml.load(swagger_yaml)
|
||||||
|
|
||||||
|
# https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#fixed-fields
|
||||||
|
# TODO Validate yaml
|
||||||
# TO_DOC:
|
# TO_DOC:
|
||||||
# If base_url is not on provided then we try to read it from the swagger.yaml or use / by default
|
# If base_url is not on provided then we try to read it from the swagger.yaml or use / by default
|
||||||
if base_url is None:
|
if base_url is None:
|
||||||
self.base_url = self.specification.get('basePath', '/')
|
self.base_url = self.specification.get('basePath', '/') # type: dict
|
||||||
else:
|
else:
|
||||||
self.base_url = base_url
|
self.base_url = base_url
|
||||||
self.specification['basePath'] = base_url
|
self.specification['basePath'] = base_url
|
||||||
|
|
||||||
|
# A list of MIME types the APIs can produce. This is global to all APIs but can be overridden on specific
|
||||||
|
# API calls.
|
||||||
|
self.produces = self.specification.get('produces', []) # type: List[str]
|
||||||
|
|
||||||
|
# Create blueprint and enpoints
|
||||||
self.blueprint = self.create_blueprint()
|
self.blueprint = self.create_blueprint()
|
||||||
|
|
||||||
self.add_swagger_json()
|
self.add_swagger_json()
|
||||||
self.add_paths()
|
self.add_paths()
|
||||||
|
|
||||||
def add_endpoint(self, method: str, path: str, endpoint: dict):
|
def add_endpoint(self, method: str, path: str, operation: dict):
|
||||||
"""
|
"""
|
||||||
Adds one endpoint to the api.
|
Adds one endpoint to the api.
|
||||||
"""
|
"""
|
||||||
operation_id = endpoint['operationId']
|
# https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#fixed-fields-5
|
||||||
|
# From Spec: A friendly name for the operation. The id MUST be unique among all operations described in the API.
|
||||||
|
# Tools and libraries MAY use the operation id to uniquely identify an operation.
|
||||||
|
# In connexion: Used to identify the module and function
|
||||||
|
operation_id = operation['operationId']
|
||||||
|
|
||||||
|
# From Spec: A list of MIME types the operation can produce. This overrides the produces definition at the
|
||||||
|
# Swagger Object. An empty value MAY be used to clear the global definition.
|
||||||
|
# In connexion: if produces == ['application/json'] then the function return value s jsonified
|
||||||
|
produces = operation['produces'] if 'produces' in operation else self.produces
|
||||||
|
returns_json = produces == ['application/json']
|
||||||
|
|
||||||
logger.debug('... adding %s -> %s', method.upper(), operation_id)
|
logger.debug('... adding %s -> %s', method.upper(), operation_id)
|
||||||
endpoint_name = utils.flaskify_endpoint(operation_id)
|
endpoint_name = utils.flaskify_endpoint(operation_id)
|
||||||
function = utils.get_function_from_name(operation_id)
|
function = utils.get_function_from_name(operation_id)
|
||||||
|
if returns_json:
|
||||||
|
function = jsonify(function)
|
||||||
# TODO wrap function with json.dumps if produces is ['application/json']
|
# TODO wrap function with json.dumps if produces is ['application/json']
|
||||||
self.blueprint.add_url_rule(path, endpoint_name, function, methods=[method])
|
self.blueprint.add_url_rule(path, endpoint_name, function, methods=[method])
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import tornado.httpserver
|
|||||||
import tornado.ioloop
|
import tornado.ioloop
|
||||||
|
|
||||||
import connexion.api
|
import connexion.api
|
||||||
import connexion.utils as utils
|
|
||||||
|
|
||||||
logger = logging.getLogger('api')
|
logger = logging.getLogger('api')
|
||||||
|
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
|
|
||||||
def __init__(self, import_name: str, port: int=5000, specification_dir: pathlib.Path=''):
|
def __init__(self, import_name: str, port: int=5000, specification_dir: pathlib.Path=''):
|
||||||
@@ -44,3 +44,5 @@ class App:
|
|||||||
http_server.listen(self.port)
|
http_server.listen(self.port)
|
||||||
logger.info('Listening on http://127.0.0.1:{port}/'.format(port=self.port))
|
logger.info('Listening on http://127.0.0.1:{port}/'.format(port=self.port))
|
||||||
tornado.ioloop.IOLoop.instance().start()
|
tornado.ioloop.IOLoop.instance().start()
|
||||||
|
|
||||||
|
# TODO: default and changeable json errors
|
||||||
|
|||||||
Reference in New Issue
Block a user