Provide CLI support for runnning specifications

This commit is contained in:
Rafael Caricio
2016-09-12 18:28:14 +02:00
parent 1f317d24f3
commit c74d8cdd3b
6 changed files with 111 additions and 4 deletions

56
connexion/cli.py Normal file
View File

@@ -0,0 +1,56 @@
import logging
import sys
from os import path
import click
from connexion import App
from clickclick import AliasedGroup
main = AliasedGroup(context_settings=dict(help_option_names=[
'-h', '--help']))
@main.command()
@click.argument('spec_file')
@click.argument('base_path', required=False)
@click.option('--port', '-p', default=5000, type=int, help='Port to listen.')
@click.option('--server', '-s', default='gevent',
type=click.Choice(['gevent', 'tornado']),
help='Which WSGI server to use.')
@click.option('--hide-spec',
help='Hides the API spec in JSON format which is by default available at `/swagger.json`.',
is_flag=True, default=True)
@click.option('--hide-swagger-ui',
help='Hides the the Swagger UI which is by default available at `/ui`.',
is_flag=True, default=True)
@click.option('--swagger-ui-url', metavar='URL',
help='Personalize what URL path the Swagger UI will be mounted.')
@click.option('--swagger-ui-from', metavar='PATH',
help='Path to a customized Swagger UI dashboard.')
@click.option('--auth-all-paths',
help='Enable authentication to paths not defined in the spec.',
is_flag=True, default=False)
@click.option('--debug', '-d', help='Show debugging information.',
is_flag=True, default=False)
def run(spec_file, base_path, port, server, debug):
"""
Runs a server using the passed OpenAPI/Swagger 2.0 Specification file.
Possible arguments:
- SPEC_FILE: specification file of the API to run.
- BASE_PATH (optional): filesystem path from where to import the API handlers.
"""
logging_level = logging.ERROR
if debug:
logging_level = logging.DEBUG
logging.basicConfig(level=logging_level)
sys.path.insert(1, path.abspath(base_path or '.'))
app = App(__name__)
app.add_api(path.abspath(spec_file))
click.echo('Running at http://localhost:{}/...'.format(port))
app.run(port=port, server=server)

View File

@@ -20,7 +20,6 @@ import string
import flask
import werkzeug.wrappers
PATH_PARAMETER = re.compile(r'\{([^}]*)\}')
# map Swagger type to flask path converter

View File

@@ -5,3 +5,4 @@ requests>=2.9.1
six>=1.7
strict-rfc3339>=0.6
swagger_spec_validator>=2.0.2
clickclick>=1.1

View File

@@ -88,5 +88,6 @@ setup(
'Topic :: Software Development :: Libraries :: Application Frameworks'
],
include_package_data=True, # needed to include swagger-ui (see MANIFEST.in)
entry_points={'console_scripts': ['connexion = connexion.cli:main',
'cnx = connexion.cli:main']}
)

View File

@@ -287,5 +287,3 @@ def test_args_kwargs(simple_app):
resp = app_client.get('/v1.0/query-params-as-kwargs?foo=a&bar=b')
assert resp.status_code == 200
assert json.loads(resp.data.decode()) == {'foo': 'a'}

52
tests/test_cli.py Normal file
View File

@@ -0,0 +1,52 @@
import logging
from click.testing import CliRunner
from connexion import App, __version__
from connexion.cli import main
import pytest
from conftest import FIXTURES_FOLDER
from mock import MagicMock
@pytest.fixture()
def mock_app_run(monkeypatch):
test_server = MagicMock(wraps=App(__name__))
test_server.run = MagicMock(return_value=True)
test_app = MagicMock(return_value=test_server)
monkeypatch.setattr('connexion.cli.App', test_app)
return test_server
def test_run_missing_spec():
runner = CliRunner()
result = runner.invoke(main, ['run'], catch_exceptions=False)
assert "Missing argument" in result.output
def test_run_simple_spec(mock_app_run):
spec_file = str(FIXTURES_FOLDER / 'simple/swagger.yaml')
default_port = 5000
default_server = 'gevent'
runner = CliRunner()
result = runner.invoke(main,
['run', spec_file],
catch_exceptions=False)
mock_app_run.run.assert_called_with(port=default_port, server=default_server)
assert 'Running at' in result.output
def test_run_in_debug_mode(mock_app_run, monkeypatch):
spec_file = str(FIXTURES_FOLDER / 'simple/swagger.yaml')
logging_config = MagicMock(name='connexion.cli.logging.basicConfig')
monkeypatch.setattr('connexion.cli.logging.basicConfig',
logging_config)
runner = CliRunner()
result = runner.invoke(main,
['run', spec_file, '-d'],
catch_exceptions=False)
logging_config.assert_called_with(level=logging.DEBUG)