sanic/sanic/__main__.py

198 lines
5.6 KiB
Python
Raw Normal View History

import os
import sys
2020-10-25 19:22:19 +00:00
from argparse import ArgumentParser, RawTextHelpFormatter
2016-10-18 09:22:49 +01:00
from importlib import import_module
from pathlib import Path
from typing import Any, Dict, Optional
2016-10-18 09:22:49 +01:00
from sanic_routing import __version__ as __routing_version__ # type: ignore
from sanic import __version__
2017-02-20 09:57:15 +00:00
from sanic.app import Sanic
2020-10-25 18:45:06 +00:00
from sanic.config import BASE_LOGO
from sanic.log import error_logger
from sanic.simple import create_simple_server
2018-10-18 05:20:16 +01:00
2016-10-18 09:22:49 +01:00
2020-10-25 18:36:22 +00:00
class SanicArgumentParser(ArgumentParser):
def add_bool_arguments(self, *args, **kwargs):
group = self.add_mutually_exclusive_group()
group.add_argument(*args, action="store_true", **kwargs)
kwargs["help"] = f"no {kwargs['help']}\n "
2020-10-25 18:36:22 +00:00
group.add_argument(
"--no-" + args[0][2:], *args[1:], action="store_false", **kwargs
)
def main():
2020-10-25 18:45:06 +00:00
parser = SanicArgumentParser(
2020-10-25 19:22:19 +00:00
prog="sanic",
description=BASE_LOGO,
formatter_class=lambda prog: RawTextHelpFormatter(
prog, max_help_position=33
),
)
parser.add_argument(
"-v",
"--version",
action="version",
version=f"Sanic {__version__}; Routing {__routing_version__}",
2020-10-25 18:45:06 +00:00
)
parser.add_argument(
"--factory",
action="store_true",
help=(
"Treat app as an application factory, "
"i.e. a () -> <Sanic app> callable"
),
)
parser.add_argument(
"-s",
"--simple",
dest="simple",
action="store_true",
help="Run Sanic as a Simple Server (module arg should be a path)\n ",
)
2018-10-14 01:55:33 +01:00
parser.add_argument(
"-H",
"--host",
dest="host",
type=str,
default="127.0.0.1",
help="Host address [default 127.0.0.1]",
2018-10-14 01:55:33 +01:00
)
parser.add_argument(
"-p",
"--port",
dest="port",
type=int,
default=8000,
help="Port to serve on [default 8000]",
)
parser.add_argument(
"-u",
"--unix",
dest="unix",
type=str,
default="",
help="location of unix socket\n ",
)
parser.add_argument(
"--cert", dest="cert", type=str, help="Location of certificate for SSL"
)
parser.add_argument(
"--key", dest="key", type=str, help="location of keyfile for SSL\n "
)
parser.add_bool_arguments(
"--access-logs", dest="access_log", help="display access logs"
)
parser.add_argument(
"-w",
"--workers",
dest="workers",
type=int,
default=1,
help="number of worker processes [default 1]\n ",
2018-10-14 01:55:33 +01:00
)
parser.add_argument("-d", "--debug", dest="debug", action="store_true")
parser.add_argument(
"-r",
"--reload",
"--auto-reload",
dest="auto_reload",
action="store_true",
help="Watch source directory for file changes and reload on changes",
2020-10-25 18:36:22 +00:00
)
parser.add_argument(
"-R",
"--reload-dir",
dest="path",
action="append",
help="Extra directories to watch and reload on changes\n ",
)
parser.add_argument(
"module",
help=(
"Path to your Sanic app. Example: path.to.server:app\n"
"If running a Simple Server, path to directory to serve. "
"Example: ./\n"
),
)
2016-10-18 09:22:49 +01:00
args = parser.parse_args()
try:
module_path = os.path.abspath(os.getcwd())
if module_path not in sys.path:
sys.path.append(module_path)
if args.simple:
path = Path(args.module)
app = create_simple_server(path)
else:
delimiter = ":" if ":" in args.module else "."
module_name, app_name = args.module.rsplit(delimiter, 1)
2016-10-18 09:22:49 +01:00
if app_name.endswith("()"):
args.factory = True
app_name = app_name[:-2]
module = import_module(module_name)
app = getattr(module, app_name, None)
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_type_name}. "
f"Perhaps you meant {args.module}.app?"
)
2017-04-08 21:31:11 +01:00
if args.cert is not None or args.key is not None:
ssl: Optional[Dict[str, Any]] = {
"cert": args.cert,
"key": args.key,
}
2017-04-08 21:31:11 +01:00
else:
ssl = None
2016-10-18 09:22:49 +01:00
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
if args.path:
if args.auto_reload or args.debug:
kwargs["reload_dir"] = args.path
else:
error_logger.warning(
"Ignoring '--reload-dir' since auto reloading was not "
"enabled. If you would like to watch directories for "
"changes, consider using --debug or --auto-reload."
)
app.run(**kwargs)
except ImportError as e:
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
2018-10-26 09:29:53 +01:00
except ValueError:
error_logger.exception("Failed to run app")
if __name__ == "__main__":
main()