mirror of
https://github.com/LukeHagar/connexion.git
synced 2025-12-10 12:27:46 +00:00
@@ -9,40 +9,23 @@ from os import path
|
|||||||
|
|
||||||
import click
|
import click
|
||||||
import importlib_metadata
|
import importlib_metadata
|
||||||
from clickclick import AliasedGroup, fatal_error
|
from clickclick import AliasedGroup
|
||||||
|
|
||||||
import connexion
|
import connexion
|
||||||
from connexion.mock import MockResolver
|
from connexion.mock import MockResolver
|
||||||
|
|
||||||
logger = logging.getLogger("connexion.cli")
|
logger = logging.getLogger("connexion.cli")
|
||||||
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
|
||||||
FLASK_APP = "flask"
|
FLASK_APP = "flask"
|
||||||
AVAILABLE_SERVERS = {
|
ASYNC_APP = "async"
|
||||||
"flask": [FLASK_APP],
|
|
||||||
"gevent": [FLASK_APP],
|
|
||||||
"tornado": [FLASK_APP],
|
|
||||||
}
|
|
||||||
AVAILABLE_APPS = {
|
AVAILABLE_APPS = {
|
||||||
FLASK_APP: "connexion.apps.flask_app.FlaskApp",
|
FLASK_APP: "connexion.apps.flask.FlaskApp",
|
||||||
}
|
ASYNC_APP: "connexion.apps.asynchronous.AsyncApp",
|
||||||
DEFAULT_SERVERS = {
|
|
||||||
FLASK_APP: FLASK_APP,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# app is defined globally so it can be passed as an import_string to `app.run`, which is needed
|
||||||
def validate_server_requirements(ctx, param, value):
|
# to enable reloading
|
||||||
if value == "gevent":
|
app = None
|
||||||
try:
|
|
||||||
import gevent # NOQA
|
|
||||||
except ImportError:
|
|
||||||
fatal_error("gevent library is not installed")
|
|
||||||
elif value == "tornado":
|
|
||||||
try:
|
|
||||||
import tornado # NOQA
|
|
||||||
except ImportError:
|
|
||||||
fatal_error("tornado library is not installed")
|
|
||||||
else:
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def print_version(ctx, param, value):
|
def print_version(ctx, param, value):
|
||||||
@@ -52,7 +35,7 @@ def print_version(ctx, param, value):
|
|||||||
ctx.exit()
|
ctx.exit()
|
||||||
|
|
||||||
|
|
||||||
@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS)
|
@click.group(cls=AliasedGroup, context_settings={"help_option_names": ["-h", "--help"]})
|
||||||
@click.option(
|
@click.option(
|
||||||
"-V",
|
"-V",
|
||||||
"--version",
|
"--version",
|
||||||
@@ -70,20 +53,8 @@ def main():
|
|||||||
@click.argument("spec_file")
|
@click.argument("spec_file")
|
||||||
@click.argument("base_module_path", required=False)
|
@click.argument("base_module_path", required=False)
|
||||||
@click.option("--port", "-p", default=5000, type=int, help="Port to listen.")
|
@click.option("--port", "-p", default=5000, type=int, help="Port to listen.")
|
||||||
@click.option("--host", "-H", type=str, help="Host interface to bind on.")
|
|
||||||
@click.option(
|
@click.option(
|
||||||
"--wsgi-server",
|
"--host", "-H", default="127.0.0.1", type=str, help="Host interface to bind on."
|
||||||
"-w",
|
|
||||||
type=click.Choice(list(AVAILABLE_SERVERS)),
|
|
||||||
callback=validate_server_requirements,
|
|
||||||
help="Which WSGI server container to use. (deprecated, use --server instead)",
|
|
||||||
)
|
|
||||||
@click.option(
|
|
||||||
"--server",
|
|
||||||
"-s",
|
|
||||||
type=click.Choice(list(AVAILABLE_SERVERS)),
|
|
||||||
callback=validate_server_requirements,
|
|
||||||
help="Which server container to use.",
|
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--stub",
|
"--stub",
|
||||||
@@ -147,7 +118,7 @@ def main():
|
|||||||
@click.option(
|
@click.option(
|
||||||
"--app-framework",
|
"--app-framework",
|
||||||
"-f",
|
"-f",
|
||||||
default=FLASK_APP,
|
default=ASYNC_APP,
|
||||||
type=click.Choice(list(AVAILABLE_APPS)),
|
type=click.Choice(list(AVAILABLE_APPS)),
|
||||||
help="The app framework used to run the server",
|
help="The app framework used to run the server",
|
||||||
)
|
)
|
||||||
@@ -156,8 +127,6 @@ def run(
|
|||||||
base_module_path,
|
base_module_path,
|
||||||
port,
|
port,
|
||||||
host,
|
host,
|
||||||
wsgi_server,
|
|
||||||
server,
|
|
||||||
stub,
|
stub,
|
||||||
mock,
|
mock,
|
||||||
hide_spec,
|
hide_spec,
|
||||||
@@ -181,23 +150,6 @@ def run(
|
|||||||
|
|
||||||
- BASE_MODULE_PATH (optional): filesystem path where the API endpoints handlers are going to be imported from.
|
- BASE_MODULE_PATH (optional): filesystem path where the API endpoints handlers are going to be imported from.
|
||||||
"""
|
"""
|
||||||
if wsgi_server and server:
|
|
||||||
raise click.BadParameter(
|
|
||||||
"these options are mutually exclusive",
|
|
||||||
param_hint="'wsgi-server' and 'server'",
|
|
||||||
)
|
|
||||||
elif wsgi_server:
|
|
||||||
server = wsgi_server
|
|
||||||
|
|
||||||
if server is None:
|
|
||||||
server = DEFAULT_SERVERS[app_framework]
|
|
||||||
|
|
||||||
if app_framework not in AVAILABLE_SERVERS[server]:
|
|
||||||
message = "Invalid server '{}' for app-framework '{}'".format(
|
|
||||||
server, app_framework
|
|
||||||
)
|
|
||||||
raise click.UsageError(message)
|
|
||||||
|
|
||||||
logging_level = logging.WARN
|
logging_level = logging.WARN
|
||||||
if verbose > 0:
|
if verbose > 0:
|
||||||
logging_level = logging.INFO
|
logging_level = logging.INFO
|
||||||
@@ -224,14 +176,17 @@ def run(
|
|||||||
|
|
||||||
app_cls = connexion.utils.get_function_from_name(AVAILABLE_APPS[app_framework])
|
app_cls = connexion.utils.get_function_from_name(AVAILABLE_APPS[app_framework])
|
||||||
|
|
||||||
options = {
|
swagger_ui_options = {
|
||||||
"serve_spec": not hide_spec,
|
"serve_spec": not hide_spec,
|
||||||
"swagger_path": console_ui_from or None,
|
"swagger_path": console_ui_from or None,
|
||||||
"swagger_ui": not hide_console_ui,
|
"swagger_ui": not hide_console_ui,
|
||||||
"swagger_url": console_ui_url or None,
|
"swagger_url": console_ui_url or None,
|
||||||
}
|
}
|
||||||
|
|
||||||
app = app_cls(__name__, auth_all_paths=auth_all_paths, options=options)
|
global app
|
||||||
|
app = app_cls(
|
||||||
|
__name__, auth_all_paths=auth_all_paths, swagger_ui_options=swagger_ui_options
|
||||||
|
)
|
||||||
|
|
||||||
app.add_api(
|
app.add_api(
|
||||||
spec_file_full_path,
|
spec_file_full_path,
|
||||||
@@ -242,7 +197,7 @@ def run(
|
|||||||
**api_extra_args,
|
**api_extra_args,
|
||||||
)
|
)
|
||||||
|
|
||||||
app.run(port=port, host=host, server=server, debug=debug)
|
app.run("connexion.cli:app", port=port, host=host, debug=debug)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": # pragma: no cover
|
if __name__ == "__main__": # pragma: no cover
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ def expected_arguments():
|
|||||||
Default values arguments used to call `connexion.App` by cli.
|
Default values arguments used to call `connexion.App` by cli.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
"options": {
|
"swagger_ui_options": {
|
||||||
"serve_spec": True,
|
"serve_spec": True,
|
||||||
"swagger_ui": True,
|
"swagger_ui": True,
|
||||||
"swagger_path": None,
|
"swagger_path": None,
|
||||||
@@ -90,7 +90,7 @@ def test_run_using_option_hide_spec(mock_app_run, expected_arguments, spec_file)
|
|||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
runner.invoke(main, ["run", spec_file, "--hide-spec"], catch_exceptions=False)
|
runner.invoke(main, ["run", spec_file, "--hide-spec"], catch_exceptions=False)
|
||||||
|
|
||||||
expected_arguments["options"]["serve_spec"] = False
|
expected_arguments["swagger_ui_options"]["serve_spec"] = False
|
||||||
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
||||||
|
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ def test_run_using_option_hide_console_ui(mock_app_run, expected_arguments, spec
|
|||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
runner.invoke(main, ["run", spec_file, "--hide-console-ui"], catch_exceptions=False)
|
runner.invoke(main, ["run", spec_file, "--hide-console-ui"], catch_exceptions=False)
|
||||||
|
|
||||||
expected_arguments["options"]["swagger_ui"] = False
|
expected_arguments["swagger_ui_options"]["swagger_ui"] = False
|
||||||
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ def test_run_using_option_console_ui_from(mock_app_run, expected_arguments, spec
|
|||||||
main, ["run", spec_file, "--console-ui-from", user_path], catch_exceptions=False
|
main, ["run", spec_file, "--console-ui-from", user_path], catch_exceptions=False
|
||||||
)
|
)
|
||||||
|
|
||||||
expected_arguments["options"]["swagger_path"] = user_path
|
expected_arguments["swagger_ui_options"]["swagger_path"] = user_path
|
||||||
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
||||||
|
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ def test_run_using_option_console_ui_url(mock_app_run, expected_arguments, spec_
|
|||||||
main, ["run", spec_file, "--console-ui-url", user_url], catch_exceptions=False
|
main, ["run", spec_file, "--console-ui-url", user_url], catch_exceptions=False
|
||||||
)
|
)
|
||||||
|
|
||||||
expected_arguments["options"]["swagger_url"] = user_url
|
expected_arguments["swagger_ui_options"]["swagger_url"] = user_url
|
||||||
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
mock_app_run.assert_called_with("connexion.cli", **expected_arguments)
|
||||||
|
|
||||||
|
|
||||||
@@ -202,37 +202,3 @@ def test_run_unimplemented_operations_and_mock(mock_app_run):
|
|||||||
main, ["run", spec_file, "--mock=all"], catch_exceptions=False
|
main, ["run", spec_file, "--mock=all"], catch_exceptions=False
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
|
||||||
def test_run_with_wsgi_containers(mock_app_run, spec_file):
|
|
||||||
runner = CliRunner()
|
|
||||||
|
|
||||||
# missing gevent
|
|
||||||
result = runner.invoke(
|
|
||||||
main, ["run", spec_file, "-w", "gevent"], catch_exceptions=False
|
|
||||||
)
|
|
||||||
assert "gevent library is not installed" in result.output
|
|
||||||
assert result.exit_code == 1
|
|
||||||
|
|
||||||
# missing tornado
|
|
||||||
result = runner.invoke(
|
|
||||||
main, ["run", spec_file, "-w", "tornado"], catch_exceptions=False
|
|
||||||
)
|
|
||||||
assert "tornado library is not installed" in result.output
|
|
||||||
assert result.exit_code == 1
|
|
||||||
|
|
||||||
# using flask
|
|
||||||
result = runner.invoke(
|
|
||||||
main, ["run", spec_file, "-w", "flask"], catch_exceptions=False
|
|
||||||
)
|
|
||||||
assert result.exit_code == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_run_with_wsgi_server_and_server_opts(mock_app_run, spec_file):
|
|
||||||
runner = CliRunner()
|
|
||||||
|
|
||||||
result = runner.invoke(
|
|
||||||
main, ["run", spec_file, "-w", "flask", "-s", "flask"], catch_exceptions=False
|
|
||||||
)
|
|
||||||
assert "these options are mutually exclusive" in result.output
|
|
||||||
assert result.exit_code == 2
|
|
||||||
|
|||||||
Reference in New Issue
Block a user