Small improvements to CLI experience (#2136)

* Small improvements to CLI experience

* Add tests

* Add test server for cli testing

* Add LOGO logging to reloader and some additional context to logging debug

* Cleanup tests
This commit is contained in:
Adam Hopkins
2021-05-20 15:35:19 +03:00
committed by GitHub
parent 3a6fac7d59
commit 72a745bfd5
5 changed files with 211 additions and 28 deletions

View File

@@ -5,6 +5,8 @@ from argparse import ArgumentParser, RawDescriptionHelpFormatter
from importlib import import_module
from typing import Any, Dict, Optional
from sanic_routing import __version__ as __routing_version__ # type: ignore
from sanic import __version__
from sanic.app import Sanic
from sanic.config import BASE_LOGO
@@ -65,15 +67,22 @@ def main():
default=1,
help="number of worker processes [default 1]",
)
parser.add_argument("--debug", dest="debug", action="store_true")
parser.add_bool_arguments(
"--access-logs", dest="access_log", help="display access logs"
parser.add_argument("-d", "--debug", dest="debug", action="store_true")
parser.add_argument(
"-r",
"--auto-reload",
dest="auto_reload",
action="store_true",
help="Watch source directory for file changes and reload on changes",
)
parser.add_argument(
"-v",
"--version",
action="version",
version=f"Sanic {__version__}",
version=f"Sanic {__version__}; Routing {__routing_version__}",
)
parser.add_bool_arguments(
"--access-logs", dest="access_log", help="display access logs"
)
parser.add_argument(
"module", help="path to your Sanic app. Example: path.to.server:app"
@@ -85,12 +94,8 @@ def main():
if module_path not in sys.path:
sys.path.append(module_path)
if ":" in args.module:
module_name, app_name = args.module.rsplit(":", 1)
else:
module_parts = args.module.split(".")
module_name = ".".join(module_parts[:-1])
app_name = module_parts[-1]
delimiter = ":" if ":" in args.module else "."
module_name, app_name = args.module.rsplit(delimiter, 1)
module = import_module(module_name)
app = getattr(module, app_name, None)
@@ -102,28 +107,34 @@ def main():
f"Perhaps you meant {args.module}.app?"
)
if args.cert is not None or args.key is not None:
ssl = {
ssl: Optional[Dict[str, Any]] = {
"cert": args.cert,
"key": args.key,
} # type: Optional[Dict[str, Any]]
}
else:
ssl = None
app.run(
host=args.host,
port=args.port,
unix=args.unix,
workers=args.workers,
debug=args.debug,
access_log=args.access_log,
ssl=ssl,
)
kwargs = {
"host": args.host,
"port": args.port,
"unix": args.unix,
"workers": args.workers,
"debug": args.debug,
"access_log": args.access_log,
"ssl": ssl,
}
if args.auto_reload:
kwargs["auto_reload"] = True
app.run(**kwargs)
except ImportError as e:
error_logger.error(
f"No module named {e.name} found.\n"
f" Example File: project/sanic_server.py -> app\n"
f" Example Module: project.sanic_server.app"
)
if module_name.startswith(e.name):
error_logger.error(
f"No module named {e.name} found.\n"
" Example File: project/sanic_server.py -> app\n"
" Example Module: project.sanic_server.app"
)
else:
raise e
except ValueError:
error_logger.exception("Failed to run app")

View File

@@ -90,6 +90,7 @@ class Sanic(BaseSanic):
"_future_signals",
"_test_client",
"_test_manager",
"auto_reload",
"asgi",
"blueprints",
"config",
@@ -150,6 +151,7 @@ class Sanic(BaseSanic):
self._test_client = None
self._test_manager = None
self.asgi = False
self.auto_reload = False
self.blueprints: Dict[str, Blueprint] = {}
self.config = Config(load_env=load_env, env_prefix=env_prefix)
self.configure_logging = configure_logging
@@ -876,8 +878,9 @@ class Sanic(BaseSanic):
)
if auto_reload or auto_reload is None and debug:
self.auto_reload = True
if os.environ.get("SANIC_SERVER_RUNNING") != "true":
return reloader_helpers.watchdog(1.0)
return reloader_helpers.watchdog(1.0, self)
if sock is None:
host, port = host or "127.0.0.1", port or 8000
@@ -1176,6 +1179,10 @@ class Sanic(BaseSanic):
else:
logger.info(f"Goin' Fast @ {proto}://{host}:{port}")
debug_mode = "enabled" if self.debug else "disabled"
logger.debug("Sanic auto-reload: enabled")
logger.debug(f"Sanic debug mode: {debug_mode}")
return server_settings
def _build_endpoint_name(self, *parts):

View File

@@ -5,6 +5,9 @@ import sys
from time import sleep
from sanic.config import BASE_LOGO
from sanic.log import logger
def _iter_module_files():
"""This iterates over all relevant Python files.
@@ -56,7 +59,7 @@ def restart_with_reloader():
)
def watchdog(sleep_interval):
def watchdog(sleep_interval, app):
"""Watch project files, restart worker process if a change happened.
:param sleep_interval: interval in second.
@@ -73,6 +76,11 @@ def watchdog(sleep_interval):
worker_process = restart_with_reloader()
if app.config.LOGO:
logger.debug(
app.config.LOGO if isinstance(app.config.LOGO, str) else BASE_LOGO
)
try:
while True:
need_reload = False