support app factory patten in CLI (#2157)

* support app factory patten in CLI

* Update sanic/__main__.py

* fix mypy errors

* Update mypy further

* Update sanic/utils.py

* Update sanic/utils.py

* support hypercorn/gunicorn style 'asgi.app:create_app()'

* add test for app factory
This commit is contained in:
Thomas Grainger
2021-06-09 10:05:56 +01:00
committed by GitHub
parent 141be0028d
commit 48f8b37b74
5 changed files with 33 additions and 4 deletions

View File

@@ -75,6 +75,14 @@ def main():
action="store_true",
help="Watch source directory for file changes and reload on changes",
)
parser.add_argument(
"--factory",
action="store_true",
help=(
"Treat app as an application factory, "
"i.e. a () -> <Sanic app> callable."
),
)
parser.add_argument(
"-v",
"--version",
@@ -97,13 +105,20 @@ def main():
delimiter = ":" if ":" in args.module else "."
module_name, app_name = args.module.rsplit(delimiter, 1)
if app_name.endswith("()"):
args.factory = True
app_name = app_name[:-2]
module = import_module(module_name)
app = getattr(module, app_name, None)
app_name = type(app).__name__
if args.factory:
app = app()
app_type_name = type(app).__name__
if not isinstance(app, Sanic):
raise ValueError(
f"Module is not a Sanic app, it is a {app_name}. "
f"Module is not a Sanic app, it is a {app_type_name}. "
f"Perhaps you meant {args.module}.app?"
)
if args.cert is not None or args.key is not None:

View File

@@ -105,6 +105,7 @@ def load_module_from_file_location(
_mod_spec = spec_from_file_location(
name, location, *args, **kwargs
)
assert _mod_spec is not None # type assertion for mypy
module = module_from_spec(_mod_spec)
_mod_spec.loader.exec_module(module) # type: ignore