diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml new file mode 100644 index 000000000..415d1908e --- /dev/null +++ b/.github/workflows/pipeline.yml @@ -0,0 +1,41 @@ +name: CI/CD pipeline +on: + push: + branches: + - main + pull_request: +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.6, 3.7, 3.8] + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + pip install --upgrade pip + pip install tox tox-gh-actions setuptools coveralls + - name: Test with tox + run: tox + - name: Coveralls + run: coveralls --service github + env: + COVERALLS_PARALLEL: true + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_FLAG_NAME: test-${{ matrix.python-version }} + + finish-coveralls: + needs: test + runs-on: ubuntu-latest + steps: + - name: Install coveralls + run: pip install coveralls + - name: Coveralls Finished + run: coveralls --service github --finish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 867a03c69..000000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: python -python: - - "3.6" - - "3.7" - - "3.8" -install: - - pip install --upgrade setuptools tox tox-travis coveralls -dist: - - bionic -script: - - tox -after_success: - - coveralls diff --git a/README.rst b/README.rst index 2f622d4d4..a85a63c2d 100644 --- a/README.rst +++ b/README.rst @@ -5,9 +5,9 @@ Connexion :alt: Join the chat at https://gitter.im/zalando/connexion :target: https://gitter.im/zalando/connexion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge -.. image:: https://travis-ci.org/zalando/connexion.svg?branch=master - :target: https://travis-ci.org/zalando/connexion - :alt: Travis CI build status +.. image:: https://github.com/zalando/connexion/actions/workflows/pipeline.yml/badge.svg + :alt: Build status + :target: https://github.com/zalando/connexion/actions/workflows/pipeline.yml .. image:: https://coveralls.io/repos/zalando/connexion/badge.svg?branch=master :target: https://coveralls.io/r/zalando/connexion?branch=master diff --git a/connexion/__init__.py b/connexion/__init__.py index f88a7c10c..270e79ac0 100755 --- a/connexion/__init__.py +++ b/connexion/__init__.py @@ -25,9 +25,10 @@ def _required_lib(exc, *args, **kwargs): try: + from flask import request # NOQA + from .apis.flask_api import FlaskApi, context # NOQA from .apps.flask_app import FlaskApp - from flask import request # NOQA except ImportError as e: # pragma: no cover _flask_not_installed_error = not_installed_error(e) FlaskApi = _flask_not_installed_error diff --git a/connexion/apis/aiohttp_api.py b/connexion/apis/aiohttp_api.py index b7e94ad73..ba1731bc7 100644 --- a/connexion/apis/aiohttp_api.py +++ b/connexion/apis/aiohttp_api.py @@ -11,16 +11,16 @@ from aiohttp import web from aiohttp.web_exceptions import HTTPNotFound, HTTPPermanentRedirect from aiohttp.web_middlewares import normalize_path_middleware +from werkzeug.exceptions import HTTPException as werkzeug_HTTPException + from connexion.apis.abstract import AbstractAPI from connexion.exceptions import ProblemException from connexion.handlers import AuthErrorHandler from connexion.jsonifier import JSONEncoder, Jsonifier from connexion.lifecycle import ConnexionRequest, ConnexionResponse from connexion.problem import problem -from connexion.utils import yamldumper from connexion.security import AioHttpSecurityHandlerFactory -from werkzeug.exceptions import HTTPException as werkzeug_HTTPException - +from connexion.utils import yamldumper logger = logging.getLogger('connexion.apis.aiohttp_api') diff --git a/connexion/apis/flask_api.py b/connexion/apis/flask_api.py index feb095d19..4878c6cd0 100644 --- a/connexion/apis/flask_api.py +++ b/connexion/apis/flask_api.py @@ -3,14 +3,15 @@ import flask import werkzeug.exceptions +from werkzeug.local import LocalProxy + from connexion.apis import flask_utils from connexion.apis.abstract import AbstractAPI from connexion.handlers import AuthErrorHandler from connexion.jsonifier import Jsonifier from connexion.lifecycle import ConnexionRequest, ConnexionResponse -from connexion.utils import is_json_mimetype, yamldumper from connexion.security import FlaskSecurityHandlerFactory -from werkzeug.local import LocalProxy +from connexion.utils import is_json_mimetype, yamldumper logger = logging.getLogger('connexion.apis.flask_api') diff --git a/connexion/apps/flask_app.py b/connexion/apps/flask_app.py index 2ae02e132..a2ecc8142 100644 --- a/connexion/apps/flask_app.py +++ b/connexion/apps/flask_app.py @@ -96,9 +96,9 @@ def run(self, port=None, server=None, debug=None, host=None, **options): # prag self.app.run(self.host, port=self.port, debug=self.debug, **options) elif self.server == 'tornado': try: - import tornado.wsgi import tornado.httpserver import tornado.ioloop + import tornado.wsgi except ImportError: raise Exception('tornado library not installed') wsgi_container = tornado.wsgi.WSGIContainer(self.app) diff --git a/connexion/cli.py b/connexion/cli.py index 86b7f2033..31ee36514 100644 --- a/connexion/cli.py +++ b/connexion/cli.py @@ -3,8 +3,9 @@ from os import path import click -import connexion from clickclick import AliasedGroup, fatal_error + +import connexion from connexion.mock import MockResolver logger = logging.getLogger('connexion.cli') diff --git a/connexion/decorators/metrics.py b/connexion/decorators/metrics.py index 8c6e1d72b..a4bfb32d7 100644 --- a/connexion/decorators/metrics.py +++ b/connexion/decorators/metrics.py @@ -3,7 +3,9 @@ import time from werkzeug.exceptions import HTTPException + from connexion.exceptions import ProblemException + try: import uwsgi_metrics HAS_UWSGI_METRICS = True # pragma: no cover diff --git a/connexion/decorators/uri_parsing.py b/connexion/decorators/uri_parsing.py index 340ecaee9..5b297d52c 100644 --- a/connexion/decorators/uri_parsing.py +++ b/connexion/decorators/uri_parsing.py @@ -1,11 +1,11 @@ # Decorators to split query and path parameters import abc import functools +import json import logging import re -import json -from .. import utils +from .. import utils from .decorator import BaseDecorator logger = logging.getLogger('connexion.decorators.uri_parsing') diff --git a/connexion/decorators/validation.py b/connexion/decorators/validation.py index f1e2776cb..225fa3b43 100644 --- a/connexion/decorators/validation.py +++ b/connexion/decorators/validation.py @@ -8,7 +8,8 @@ from jsonschema.validators import extend from werkzeug.datastructures import FileStorage -from ..exceptions import ExtraParameterProblem, BadRequestProblem, UnsupportedMediaTypeProblem +from ..exceptions import (BadRequestProblem, ExtraParameterProblem, + UnsupportedMediaTypeProblem) from ..http_facts import FORM_CONTENT_TYPES from ..json_schema import Draft4RequestValidator, Draft4ResponseValidator from ..utils import all_json, boolean, is_json_mimetype, is_null, is_nullable diff --git a/connexion/exceptions.py b/connexion/exceptions.py index f86cdd226..53a253d2e 100644 --- a/connexion/exceptions.py +++ b/connexion/exceptions.py @@ -1,4 +1,5 @@ import warnings + from jsonschema.exceptions import ValidationError from werkzeug.exceptions import Forbidden, Unauthorized diff --git a/connexion/handlers.py b/connexion/handlers.py index dacd89e22..a5e130c7b 100644 --- a/connexion/handlers.py +++ b/connexion/handlers.py @@ -1,7 +1,7 @@ import logging -from .operations.secure import SecureOperation from .exceptions import AuthenticationProblem, ResolverProblem +from .operations.secure import SecureOperation logger = logging.getLogger('connexion.handlers') diff --git a/connexion/options.py b/connexion/options.py index 904332360..c19d2b8f4 100644 --- a/connexion/options.py +++ b/connexion/options.py @@ -3,8 +3,7 @@ from typing import Optional # NOQA try: - from swagger_ui_bundle import (swagger_ui_2_path, - swagger_ui_3_path) + from swagger_ui_bundle import swagger_ui_2_path, swagger_ui_3_path except ImportError: swagger_ui_2_path = swagger_ui_3_path = None diff --git a/connexion/resolver.py b/connexion/resolver.py index 3a50392e9..d4896b851 100644 --- a/connexion/resolver.py +++ b/connexion/resolver.py @@ -1,5 +1,4 @@ import logging -import re import sys import connexion.utils as utils diff --git a/connexion/security/__init__.py b/connexion/security/__init__.py index 0d918b924..5c5e12ebd 100644 --- a/connexion/security/__init__.py +++ b/connexion/security/__init__.py @@ -1,7 +1,9 @@ +"""isort:skip_file""" + # abstract -from .security_handler_factory import AbstractSecurityHandlerFactory # NOQA from .async_security_handler_factory import AbstractAsyncSecurityHandlerFactory # NOQA +from .security_handler_factory import AbstractSecurityHandlerFactory # NOQA # concrete -from .flask_security_handler_factory import FlaskSecurityHandlerFactory # NOQA from .aiohttp_security_handler_factory import AioHttpSecurityHandlerFactory # NOQA +from .flask_security_handler_factory import FlaskSecurityHandlerFactory # NOQA diff --git a/connexion/security/aiohttp_security_handler_factory.py b/connexion/security/aiohttp_security_handler_factory.py index 062eb31aa..698ef59e4 100644 --- a/connexion/security/aiohttp_security_handler_factory.py +++ b/connexion/security/aiohttp_security_handler_factory.py @@ -1,4 +1,3 @@ -import asyncio import logging import aiohttp diff --git a/connexion/security/security_handler_factory.py b/connexion/security/security_handler_factory.py index 3c237ba0c..90848b4d7 100644 --- a/connexion/security/security_handler_factory.py +++ b/connexion/security/security_handler_factory.py @@ -1,12 +1,11 @@ import abc import base64 import functools +import http.cookies import logging import os import textwrap -import http.cookies - from ..decorators.parameter import inspect_function_arguments from ..exceptions import (ConnexionException, OAuthProblem, OAuthResponseProblem, OAuthScopeProblem) diff --git a/connexion/spec.py b/connexion/spec.py index e11530e40..5be9dc8c3 100644 --- a/connexion/spec.py +++ b/connexion/spec.py @@ -1,11 +1,11 @@ import abc import copy import pathlib +from urllib.parse import urlsplit import jinja2 import yaml from openapi_spec_validator.exceptions import OpenAPIValidationError -from urllib.parse import urlsplit from .exceptions import InvalidSpecification from .json_schema import resolve_refs diff --git a/examples/openapi3/helloworld_aiohttp/hello.py b/examples/openapi3/helloworld_aiohttp/hello.py index 1453928ca..7f7a12bb5 100755 --- a/examples/openapi3/helloworld_aiohttp/hello.py +++ b/examples/openapi3/helloworld_aiohttp/hello.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import connexion from aiohttp import web +import connexion async def post_greeting(name): diff --git a/requirements-aiohttp.txt b/requirements-aiohttp.txt deleted file mode 100644 index 34182eb66..000000000 --- a/requirements-aiohttp.txt +++ /dev/null @@ -1,3 +0,0 @@ -aiohttp>=2.2.5 -aiohttp-swagger>=1.0.5 -aiohttp_jinja2==0.15.0 diff --git a/requirements-all.txt b/requirements-all.txt deleted file mode 100644 index c5b0879be..000000000 --- a/requirements-all.txt +++ /dev/null @@ -1,4 +0,0 @@ --r requirements-aiohttp.txt --r requirements-devel.txt -openapi_spec_validator -pytest-aiohttp \ No newline at end of file diff --git a/requirements-devel.txt b/requirements-devel.txt deleted file mode 100644 index f5f01893d..000000000 --- a/requirements-devel.txt +++ /dev/null @@ -1,12 +0,0 @@ --e git+https://github.com/Julian/jsonschema.git@v2.6.0#egg=jsonschema --e git+https://github.com/pallets/flask.git#egg=flask --e git+https://github.com/kennethreitz/requests#egg=requests --e git+https://github.com/zalando/python-clickclick.git#egg=clickclick -inflection -mock -pytest -testfixtures>=5.3.0 -# This repo doesn't have the latest version released on PyPI -# -e hg+https://bitbucket.org/pitrou/pathlib#egg=pathlib -# PyYAML is not that easy to build manually, it may fail. -#-e svn+http://svn.pyyaml.org/pyyaml/trunk#egg=PyYAML diff --git a/setup.py b/setup.py index fb5a77673..2d31841bc 100755 --- a/setup.py +++ b/setup.py @@ -21,20 +21,20 @@ def read_version(package): version = read_version('connexion') install_requires = [ - 'clickclick>=1.2', - 'jsonschema>=2.5.1', - 'PyYAML>=5.1', - 'requests>=2.9.1', - 'inflection>=0.3.1', - 'openapi-spec-validator>=0.2.4', + 'clickclick>=1.2,<21', + 'jsonschema>=2.5.1,<4', + 'PyYAML>=5.1,<6', + 'requests>=2.9.1,<3', + 'inflection>=0.3.1,<0.6', + 'openapi-spec-validator>=0.2.4,<2', 'werkzeug>=1.0,<2.0', ] swagger_ui_require = 'swagger-ui-bundle>=0.0.2' flask_require = 'flask>=1.0.4' aiohttp_require = [ - 'aiohttp>=2.3.10', - 'aiohttp-jinja2>=0.14.0' + 'aiohttp>=2.3.10,<4', + 'aiohttp-jinja2>=0.14.0,<2' ] tests_require = [ diff --git a/tests/aiohttp/test_aiohttp_api_secure.py b/tests/aiohttp/test_aiohttp_api_secure.py index 5a177b16a..ffc9a5a01 100644 --- a/tests/aiohttp/test_aiohttp_api_secure.py +++ b/tests/aiohttp/test_aiohttp_api_secure.py @@ -1,9 +1,7 @@ -import asyncio import base64 +from unittest.mock import MagicMock import pytest -from mock import MagicMock - from connexion import AioHttpApp diff --git a/tests/aiohttp/test_aiohttp_app.py b/tests/aiohttp/test_aiohttp_app.py index 1fcbb1049..3b841fb95 100644 --- a/tests/aiohttp/test_aiohttp_app.py +++ b/tests/aiohttp/test_aiohttp_app.py @@ -3,11 +3,11 @@ from unittest import mock import pytest - -from conftest import TEST_FOLDER from connexion import AioHttpApp from connexion.exceptions import ConnexionException +from conftest import TEST_FOLDER + @pytest.fixture def web_run_app_mock(monkeypatch): diff --git a/tests/aiohttp/test_aiohttp_errors.py b/tests/aiohttp/test_aiohttp_errors.py index f4693d132..a50f0f618 100644 --- a/tests/aiohttp/test_aiohttp_errors.py +++ b/tests/aiohttp/test_aiohttp_errors.py @@ -1,8 +1,7 @@ import asyncio -import pytest - import aiohttp.test_utils +import pytest from connexion import AioHttpApp from connexion.apis.aiohttp_api import HTTPStatus diff --git a/tests/aiohttp/test_aiohttp_simple_api.py b/tests/aiohttp/test_aiohttp_simple_api.py index 217421790..4d1433ace 100644 --- a/tests/aiohttp/test_aiohttp_simple_api.py +++ b/tests/aiohttp/test_aiohttp_simple_api.py @@ -3,9 +3,9 @@ import pytest import yaml +from connexion import AioHttpApp from conftest import TEST_FOLDER -from connexion import AioHttpApp try: import ujson as json diff --git a/tests/aiohttp/test_get_response.py b/tests/aiohttp/test_get_response.py index 5a3aa9a04..cc5a11967 100644 --- a/tests/aiohttp/test_get_response.py +++ b/tests/aiohttp/test_get_response.py @@ -1,7 +1,6 @@ import json import pytest - from aiohttp import web from connexion.apis.aiohttp_api import AioHttpApi from connexion.lifecycle import ConnexionResponse diff --git a/tests/api/test_bootstrap.py b/tests/api/test_bootstrap.py index 059b9dfc8..da22d56e2 100644 --- a/tests/api/test_bootstrap.py +++ b/tests/api/test_bootstrap.py @@ -1,15 +1,15 @@ import json +from unittest import mock import jinja2 -from unittest import mock import pytest import yaml -from openapi_spec_validator.loaders import ExtendedSafeLoader - -from conftest import TEST_FOLDER, build_app_from_fixture from connexion import App from connexion.exceptions import InvalidSpecification from connexion.http_facts import METHODS +from openapi_spec_validator.loaders import ExtendedSafeLoader + +from conftest import TEST_FOLDER, build_app_from_fixture SPECS = ["swagger.yaml", "openapi.yaml"] diff --git a/tests/conftest.py b/tests/conftest.py index be915dcab..f22052d34 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,6 @@ import sys import pytest - from connexion import App from connexion.security import FlaskSecurityHandlerFactory diff --git a/tests/decorators/test_security.py b/tests/decorators/test_security.py index b6b2e2262..c42441f1c 100644 --- a/tests/decorators/test_security.py +++ b/tests/decorators/test_security.py @@ -1,9 +1,8 @@ -import json +from unittest.mock import MagicMock +import json import pytest import requests -from unittest.mock import MagicMock - from connexion.exceptions import OAuthResponseProblem, OAuthScopeProblem diff --git a/tests/decorators/test_uri_parsing.py b/tests/decorators/test_uri_parsing.py index e14420925..81e1ef724 100644 --- a/tests/decorators/test_uri_parsing.py +++ b/tests/decorators/test_uri_parsing.py @@ -1,9 +1,8 @@ import pytest -from werkzeug.datastructures import MultiDict - from connexion.decorators.uri_parsing import (AlwaysMultiURIParser, FirstValueURIParser, Swagger2URIParser) +from werkzeug.datastructures import MultiDict QUERY1 = MultiDict([("letters", "a"), ("letters", "b,c"), ("letters", "d,e,f")]) diff --git a/tests/decorators/test_validation.py b/tests/decorators/test_validation.py index 2852996da..75eba0b9d 100644 --- a/tests/decorators/test_validation.py +++ b/tests/decorators/test_validation.py @@ -1,10 +1,10 @@ -import pytest -from jsonschema import ValidationError from unittest.mock import MagicMock +import pytest from connexion.decorators.validation import ParameterValidator from connexion.json_schema import (Draft4RequestValidator, Draft4ResponseValidator) +from jsonschema import ValidationError def test_get_valid_parameter(): diff --git a/tests/fakeapi/aiohttp_handlers.py b/tests/fakeapi/aiohttp_handlers.py index 503724753..92592f1df 100755 --- a/tests/fakeapi/aiohttp_handlers.py +++ b/tests/fakeapi/aiohttp_handlers.py @@ -78,6 +78,22 @@ async def aiohttp_token_info(token_info): return aiohttp.web.json_response(data=token_info) +async def aiohttp_all_auth(token_info): + return await aiohttp_token_info(token_info) + + +async def aiohttp_async_auth(token_info): + return await aiohttp_token_info(token_info) + + +async def aiohttp_bearer_auth(token_info): + return await aiohttp_token_info(token_info) + + +async def aiohttp_async_bearer_auth(token_info): + return await aiohttp_token_info(token_info) + + async def get_datetime(): return ConnexionResponse(body={'value': datetime.datetime(2000, 1, 2, 3, 4, 5, 6)}) diff --git a/tests/fixtures/aiohttp/openapi_secure.yaml b/tests/fixtures/aiohttp/openapi_secure.yaml index 36340c32d..80f08d7b8 100644 --- a/tests/fixtures/aiohttp/openapi_secure.yaml +++ b/tests/fixtures/aiohttp/openapi_secure.yaml @@ -8,7 +8,7 @@ paths: '/all_auth': get: summary: Test basic and oauth auth - operationId: fakeapi.aiohttp_handlers.aiohttp_token_info + operationId: fakeapi.aiohttp_handlers.aiohttp_all_auth security: - oauth: - myscope @@ -19,8 +19,8 @@ paths: $ref: "#/components/responses/Success" '/async_auth': get: - summary: Test api key auth - operationId: fakeapi.aiohttp_handlers.aiohttp_token_info + summary: Test async auth + operationId: fakeapi.aiohttp_handlers.aiohttp_async_auth security: - async_oauth: - myscope @@ -32,7 +32,7 @@ paths: '/bearer_auth': get: summary: Test api key auth - operationId: fakeapi.aiohttp_handlers.aiohttp_token_info + operationId: fakeapi.aiohttp_handlers.aiohttp_bearer_auth security: - bearer: [] responses: @@ -41,7 +41,7 @@ paths: '/async_bearer_auth': get: summary: Test api key auth - operationId: fakeapi.aiohttp_handlers.aiohttp_token_info + operationId: fakeapi.aiohttp_handlers.aiohttp_async_bearer_auth security: - async_bearer: [] responses: @@ -81,6 +81,7 @@ components: async_oauth: type: oauth2 + flows: {} x-tokenInfoFunc: fakeapi.auth.async_json_auth x-scopeValidateFunc: fakeapi.auth.async_scope_validation async_basic: diff --git a/tests/test_api.py b/tests/test_api.py index 6bcbf7dd2..c55c4cc35 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -3,14 +3,13 @@ import pathlib import os import tempfile - -import pytest from unittest.mock import MagicMock -from yaml import YAMLError +import pytest from connexion import FlaskApi from connexion.exceptions import InvalidSpecification, ResolverError from connexion.spec import canonical_base_path +from yaml import YAMLError TEST_FOLDER = pathlib.Path(__file__).parent diff --git a/tests/test_app.py b/tests/test_app.py index 409afc74a..d3bc06d04 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,8 +1,8 @@ # coding: utf-8 from flask import Flask -from connexion.apps.flask_app import FlaskApp from connexion.apis.flask_api import FlaskApi +from connexion.apps.flask_app import FlaskApp def test_flask_app_default_params(): diff --git a/tests/test_cli.py b/tests/test_cli.py index f4bae2d1b..43df1e5a4 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,14 +1,12 @@ import logging +from unittest.mock import MagicMock +import connexion import pytest from click.testing import CliRunner -from unittest.mock import MagicMock -from unittest.mock import call as mock_call +from connexion.cli import main -import connexion from conftest import FIXTURES_FOLDER -from connexion.cli import main -from connexion.exceptions import ResolverError @pytest.fixture() diff --git a/tests/test_flask_encoder.py b/tests/test_flask_encoder.py index 39c4a7e85..e1e8031b1 100644 --- a/tests/test_flask_encoder.py +++ b/tests/test_flask_encoder.py @@ -4,9 +4,9 @@ from decimal import Decimal import pytest +from connexion.apps.flask_app import FlaskJSONEncoder from conftest import build_app_from_fixture -from connexion.apps.flask_app import FlaskJSONEncoder SPECS = ["swagger.yaml", "openapi.yaml"] diff --git a/tests/test_json_validation.py b/tests/test_json_validation.py index d911abd3e..3a0a22f3f 100644 --- a/tests/test_json_validation.py +++ b/tests/test_json_validation.py @@ -1,15 +1,16 @@ import json import pytest -from jsonschema.validators import _utils, extend - -from conftest import build_app_from_fixture from connexion import App from connexion.decorators.validation import RequestBodyValidator from connexion.json_schema import Draft4RequestValidator +from jsonschema.validators import _utils, extend + +from conftest import build_app_from_fixture SPECS = ["swagger.yaml", "openapi.yaml"] + @pytest.mark.parametrize("spec", SPECS) def test_validator_map(json_validation_spec_dir, spec): def validate_type(validator, types, instance, schema): diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 9483003d1..20cfe0839 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -1,12 +1,9 @@ -import json +from unittest.mock import MagicMock import flask import pytest -from unittest.mock import MagicMock - -import connexion -from connexion.exceptions import ProblemException from connexion.decorators.metrics import UWSGIMetricsCollector +from connexion.exceptions import ProblemException def test_timer(monkeypatch): diff --git a/tests/test_mock.py b/tests/test_mock.py index 2c952308c..f23db4afc 100644 --- a/tests/test_mock.py +++ b/tests/test_mock.py @@ -1,5 +1,5 @@ from connexion.mock import MockResolver -from connexion.operations import Swagger2Operation, OpenAPIOperation +from connexion.operations import OpenAPIOperation, Swagger2Operation def test_mock_resolver_default(): diff --git a/tests/test_operation2.py b/tests/test_operation2.py index da273c52e..16a1a45d6 100644 --- a/tests/test_operation2.py +++ b/tests/test_operation2.py @@ -2,10 +2,9 @@ import math import pathlib import types - from unittest import mock -import pytest +import pytest from connexion.apis.flask_api import Jsonifier from connexion.exceptions import InvalidSpecification from connexion.json_schema import resolve_refs diff --git a/tests/test_references.py b/tests/test_references.py index be9feb22a..4e54f14a0 100644 --- a/tests/test_references.py +++ b/tests/test_references.py @@ -1,6 +1,6 @@ from unittest import mock -import pytest +import pytest from connexion.apis.flask_api import Jsonifier from connexion.json_schema import RefResolutionError, resolve_refs diff --git a/tests/test_resolver.py b/tests/test_resolver.py index 1b2d0d38f..a158047d9 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -1,5 +1,4 @@ import pytest - import connexion.apps from connexion.exceptions import ResolverError from connexion.operations import Swagger2Operation diff --git a/tests/test_utils.py b/tests/test_utils.py index af4f3363b..72c9e2774 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,9 +1,8 @@ import math - -import pytest from unittest.mock import MagicMock import connexion.apps +import pytest from connexion import utils diff --git a/tests/test_validation.py b/tests/test_validation.py index 308637f59..d544d64fe 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -1,12 +1,10 @@ -import json +from unittest.mock import MagicMock import flask import pytest -from unittest.mock import MagicMock - from connexion.apis.flask_api import FlaskApi -from connexion.exceptions import BadRequestProblem from connexion.decorators.validation import ParameterValidator +from connexion.exceptions import BadRequestProblem def test_parameter_validator(monkeypatch): diff --git a/tox.ini b/tox.ini index 414eed5f4..ba6b05230 100644 --- a/tox.ini +++ b/tox.ini @@ -12,23 +12,23 @@ envlist = isort-check-tests flake8 -[travis] -3.6=py36-min,py36-pypi -3.7=py37-min,py37-pypi,isort-check,isort-check-examples,isort-check-tests,flake8 -3.8=py38-min +[gh-actions] +python = + 3.6: py36-min,py36-pypi + 3.7: py37-min,py37-pypi,isort-check,isort-check-examples, isort-check-tests,flake8 + 3.8: py38-min [testenv] setenv=PYTHONPATH = {toxinidir}:{toxinidir} deps=pytest commands= pip install Requirements-Builder - min: requirements-builder --level=min -o {toxworkdir}/requirements-min.txt setup.py - min: pip install -r {toxworkdir}/requirements-min.txt - pypi: requirements-builder --level=pypi -o {toxworkdir}/requirements-pypi.txt setup.py - pypi: pip install -r {toxworkdir}/requirements-pypi.txt - dev: requirements-builder --level=dev --req=requirements-devel.txt -o {toxworkdir}/requirements-dev.txt setup.py - dev: pip install -r {toxworkdir}/requirements-dev.txt - py3{6,7,8}: pip install -r requirements-aiohttp.txt + min: requirements-builder --level=min --extras aiohttp -o {toxworkdir}/requirements-min.txt setup.py + min: pip install --upgrade -r {toxworkdir}/requirements-min.txt + pypi: requirements-builder --level=pypi --extras aiohttp -o {toxworkdir}/requirements-pypi.txt setup.py + pypi: pip install --upgrade -r {toxworkdir}/requirements-pypi.txt + dev: requirements-builder --level=dev --extras aiohttp --req=requirements-devel.txt -o {toxworkdir}/requirements-dev.txt setup.py + dev: pip install --upgrade -r {toxworkdir}/requirements-dev.txt python setup.py test [testenv:flake8] @@ -39,16 +39,16 @@ commands=python setup.py flake8 basepython=python3 deps=isort==4.3.15 changedir={toxinidir}/connexion -commands=isort -ns __init__.py -rc -c -df . +commands=isort -p connexion -c -diff . [testenv:isort-check-examples] basepython=python3 deps=isort==4.3.15 changedir={toxinidir}/examples -commands=isort -ns __init__.py -o connexion -rc -c -df . +commands=isort -o connexion -c -diff . [testenv:isort-check-tests] basepython=python3 deps=isort==4.3.15 changedir={toxinidir}/tests -commands=isort -ns __init__.py -p connexion -rc -c -df . +commands=isort -o connexion -c -diff .