Flask required only if necessary (#424)

* Example with Flask support

* Only show import error when trying to use Flask

* Re-organize imports

* Move flask_utils next to related module

* Code style

* Change back to incentivizes

* Includes Flask by default

* Project clean up

* Update Rafael Caricio's e-mail address

* Fix conflicts
This commit is contained in:
Rafael Carício
2017-04-04 20:48:08 +02:00
committed by Henning Jacobs
parent 6f567ee4de
commit 1858c9d4a0
28 changed files with 46 additions and 67 deletions

View File

@@ -1,10 +0,0 @@
checks:
- specification
- branch-release
- codevalidator
- protect-master
specification:
allowed_schemes: ['https']
allowed_formats: ['uri', 'github']
branch-release:
pattern: '^v(?:\d|\_|\.)+$'

View File

@@ -1,3 +1,3 @@
João Santos <joao.santos@zalando.de>
Henning Jacobs <henning.jacobs@zalando.de>
Rafael Caricio <rafael.caricio@zalando.de>
Rafael Caricio <rafael@caricio.com>

View File

@@ -33,7 +33,8 @@ Connexion is a framework on top of Flask_ that automagically handles
HTTP requests based on `OpenAPI 2.0 Specification`_ (formerly known as
Swagger Spec) of your API described in `YAML format`_. Connexion
allows you to write a Swagger specification, then maps the
endpoints to your Python functions; this makes it unique, as many tools generate the specification based on your Python
endpoints to your Python functions; this makes it unique, as many
tools generate the specification based on your Python
code. You can describe your REST API in as much detail as
you want; then Connexion guarantees that it will work as
you specified.
@@ -93,7 +94,6 @@ In your command line, type:
$ pip install connexion
Running It
----------

View File

@@ -1,11 +1,25 @@
import werkzeug.exceptions as exceptions # NOQA
from .apps import AbstractApp, FlaskApp # NOQA
from .apis import AbstractAPI, FlaskApi # NOQA
from .apps import AbstractApp # NOQA
from .apis import AbstractAPI # NOQA
from .exceptions import ProblemException # NOQA
from .problem import problem # NOQA
from .decorators.produces import NoContent # NOQA
from .resolver import Resolution, Resolver, RestyResolver # NOQA
try:
from .apis.flask_api import FlaskApi
from .apps.flask_app import FlaskApp
except ImportError as e: # pragma: no cover
import sys
import six
import functools
def _required_lib(exec_info, *args, **kwargs):
six.reraise(*exec_info)
FlaskApi = functools.partial(_required_lib, sys.exc_info())
FlaskApp = functools.partial(_required_lib, sys.exc_info())
App = FlaskApp
Api = FlaskApi

View File

@@ -1,4 +1 @@
from .abstract import AbstractAPI
from .flask_api import FlaskApi
__all__ = ['AbstractAPI', 'FlaskApi']
from .abstract import AbstractAPI # NOQA

View File

@@ -4,12 +4,11 @@ import logging
import pathlib
import sys
import jinja2
import six
import yaml
from swagger_spec_validator.validator20 import validate_spec
import jinja2
from ..exceptions import ResolverError
from ..operation import Operation
from ..resolver import Resolver

View File

@@ -1,10 +1,10 @@
import logging
import six
import flask
import six
import werkzeug.exceptions
from connexion import flask_utils
from connexion.apis import flask_utils
from connexion.apis.abstract import AbstractAPI
from connexion.decorators.produces import BaseSerializer, NoContent
from connexion.handlers import AuthErrorHandler

View File

@@ -3,7 +3,6 @@ import random
import re
import string
import flask
import werkzeug.wrappers

View File

@@ -1,4 +1 @@
from .abstract import AbstractApp
from .flask_app import FlaskApp
__all__ = ['AbstractApp', 'FlaskApp']
from .abstract import AbstractApp # NOQA

View File

@@ -1,6 +1,7 @@
import abc
import logging
import pathlib
import six
from ..resolver import Resolver

View File

@@ -13,7 +13,6 @@ from ..problem import problem
from ..resolver import Resolver
from .abstract import AbstractApp
logger = logging.getLogger('connexion.app')

View File

@@ -1,6 +1,5 @@
from collections import namedtuple
_ConnexionRequest = namedtuple('SwaggerRequest', [
'url', 'method', 'path_params', 'query', 'headers',
'form', 'body', 'json', 'files', 'context'

View File

@@ -1,6 +1,5 @@
from collections import namedtuple
_ConnexionResponse = namedtuple('SwaggerRequest', [
'mimetype', 'content_type', 'status_code', 'body', 'headers'
])

View File

@@ -89,7 +89,7 @@ setup(
keywords='openapi oai swagger rest api oauth flask microservice framework',
license='Apache License Version 2.0',
setup_requires=['flake8'],
install_requires=install_requires,
install_requires=install_requires + [flask_require],
tests_require=tests_require,
extras_require={'tests': tests_require, 'flask': flask_require},
cmdclass={'test': PyTest},

View File

@@ -1,10 +1,9 @@
import jinja2
import yaml
import jinja2
import pytest
from conftest import TEST_FOLDER, build_app_from_fixture
from connexion.apis import FlaskApi
from connexion.apps import FlaskApp
from connexion import FlaskApp
from connexion.exceptions import InvalidSpecification
@@ -22,7 +21,6 @@ def test_app_with_relative_path(simple_api_spec_dir):
def test_no_swagger_ui(simple_api_spec_dir):
app = FlaskApp(__name__, 5001, simple_api_spec_dir, swagger_ui=False, debug=True)
# app = FlaskApp(__name__, 5001, simple_api_spec_dir, debug=True)
app.add_api('swagger.yaml')
app_client = app.app.test_client()

View File

@@ -1,4 +1,5 @@
import json
import flask

View File

@@ -1,6 +1,7 @@
import json
from io import BytesIO
def test_parameter_validation(simple_app):
app_client = simple_app.app.test_client()

View File

@@ -1,7 +1,6 @@
import json
from connexion.apis import FlaskApi
from connexion.apps import FlaskApp
from connexion import FlaskApp
def test_security_over_inexistent_endpoints(oauth_requests, secure_api_spec_dir):

View File

@@ -3,8 +3,7 @@ import logging
import pathlib
import pytest
from connexion.apis import FlaskApi
from connexion.apps import FlaskApp
from connexion import FlaskApi, FlaskApp
logging.basicConfig(level=logging.DEBUG)

View File

@@ -1,10 +1,8 @@
#!/usr/bin/env python3
import json
from flask import jsonify, redirect
from connexion import NoContent, ProblemException, problem
from connexion.apis import FlaskApi
from flask import jsonify, redirect, request
class DummyClass(object):

View File

@@ -7,9 +7,8 @@ from swagger_spec_validator.common import SwaggerValidationError
from yaml import YAMLError
import pytest
from connexion.apis import FlaskApi
from connexion import FlaskApi
from connexion.apis.abstract import canonical_base_url
from connexion.apis.flask_api import FlaskApi
from connexion.exceptions import InvalidSpecification, ResolverError
TEST_FOLDER = pathlib.Path(__file__).parent

View File

@@ -1,7 +1,6 @@
import datetime
import json
import math
from decimal import Decimal
from connexion.apps.flask_app import FlaskJSONEncoder

View File

@@ -1,10 +1,4 @@
import math
import connexion.apps
import connexion.flask_utils as flask_utils
import connexion.utils as utils
import pytest
from mock import MagicMock
import connexion.apis.flask_utils as flask_utils
def test_flaskify_path():

View File

@@ -1,8 +1,8 @@
import json
import connexion
import flask
from connexion.apis import FlaskApi
import connexion
from connexion.decorators.metrics import UWSGIMetricsCollector
from mock import MagicMock

View File

@@ -3,7 +3,6 @@ import types
import mock
import pytest
from connexion.apis.flask_api import Jsonifier
from connexion.decorators.security import security_passthrough, verify_oauth
from connexion.exceptions import InvalidSpecification

View File

@@ -8,13 +8,13 @@ PARAMETER_DEFINITIONS = {'myparam': {'in': 'path', 'type': 'integer'}}
def test_standard_get_function():
function = Resolver().resolve_function_from_operation_id('connexion.apps.FlaskApp.common_error_handler')
assert function == connexion.apps.FlaskApp.common_error_handler
function = Resolver().resolve_function_from_operation_id('connexion.FlaskApp.common_error_handler')
assert function == connexion.FlaskApp.common_error_handler
def test_resty_get_function():
function = RestyResolver('connexion').resolve_function_from_operation_id('connexion.apps.FlaskApp.common_error_handler')
assert function == connexion.apps.FlaskApp.common_error_handler
function = RestyResolver('connexion').resolve_function_from_operation_id('connexion.FlaskApp.common_error_handler')
assert function == connexion.FlaskApp.common_error_handler
def test_missing_operation_id():

View File

@@ -1,10 +1,8 @@
import math
import connexion.apps
import connexion.flask_utils as flask_utils
import connexion.utils as utils
import pytest
from connexion import utils
from mock import MagicMock
@@ -28,8 +26,8 @@ def test_get_function_from_name_attr_error(monkeypatch):
def test_get_function_from_name_for_class_method():
function = utils.get_function_from_name('connexion.apps.FlaskApp.common_error_handler')
assert function == connexion.apps.FlaskApp.common_error_handler
function = utils.get_function_from_name('connexion.FlaskApp.common_error_handler')
assert function == connexion.FlaskApp.common_error_handler
def test_boolean():

View File

@@ -1,4 +1,5 @@
import json
import flask
from connexion.apis.flask_api import FlaskApi
@@ -7,7 +8,6 @@ from connexion.decorators.validation import ParameterValidator
from mock import MagicMock
def test_parameter_validator(monkeypatch):
request = MagicMock(name='request')
request.args = {}