sanic/sanic/__main__.py

110 lines
2.9 KiB
Python
Raw Normal View History

import os
import sys
2016-10-18 09:22:49 +01:00
from argparse import ArgumentParser
from importlib import import_module
from typing import Any, Dict, Optional
2016-10-18 09:22:49 +01:00
from sanic import __version__
2017-02-20 09:57:15 +00:00
from sanic.app import Sanic
2018-10-18 05:20:16 +01:00
from sanic.log import logger
2016-10-18 09:22:49 +01:00
def main():
2018-10-14 01:55:33 +01:00
parser = ArgumentParser(prog="sanic")
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",
)
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."
)
parser.add_argument(
"-w",
"--workers",
dest="workers",
type=int,
default=1,
help="Number of worker processes [default 1]",
2018-10-14 01:55:33 +01:00
)
parser.add_argument("--debug", dest="debug", action="store_true")
parser.add_argument(
"-v", "--version", action="version", version=f"Sanic {__version__}",
)
parser.add_argument(
"module", help="Path to your Sanic app. Example: path.to.server:app"
)
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 ":" 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]
2016-10-18 09:22:49 +01:00
module = import_module(module_name)
app = getattr(module, app_name, None)
app_name = type(app).__name__
2016-12-26 11:37:16 +00:00
if not isinstance(app, Sanic):
2018-10-14 01:55:33 +01:00
raise ValueError(
f"Module is not a Sanic app, it is a {app_name}. "
f"Perhaps you meant {args.module}.app?"
2018-10-14 01:55:33 +01:00
)
2017-04-08 21:31:11 +01:00
if args.cert is not None or args.key is not None:
ssl = {
"cert": args.cert,
"key": args.key,
} # type: Optional[Dict[str, Any]]
2017-04-08 21:31:11 +01:00
else:
ssl = None
2016-10-18 09:22:49 +01:00
2018-10-14 01:55:33 +01:00
app.run(
host=args.host,
port=args.port,
Socket binding implemented properly for IPv6 and UNIX sockets. (#1641) * Socket binding implemented properly for IPv6 and UNIX sockets. - app.run("::1") for IPv6 - app.run("unix:/tmp/server.sock") for UNIX sockets - app.run("localhost") retains old functionality (randomly either IPv4 or IPv6) Do note that IPv6 and UNIX sockets are not fully supported by other Sanic facilities. In particular, request.server_name and request.server_port are currently unreliable. * Fix Windows compatibility by not referring to socket.AF_UNIX unless needed. * Compatibility fix. * Fix test of existing unix socket. * Cleaner unix socket removal. * Remove unix socket on exit also with workers=1. * More pedantic UNIX socket implementation. * Refactor app to take unix= argument instead of unix:-prefixed host. Goin' fast @ unix-socket fixed. * Linter * Proxy properties cleanup. Slight changes of semantics. SERVER_NAME now overrides everything. * Have server fill in connection info instead of request asking the socket. - Would be a good idea to remove request.transport entirely but I didn't dare to touch it yet. * Linter 💣🌟✊💀 * Fix typing issues. request.server_name returns empty string if host header is missing. * Fix tests * Tests were failing, fix connection info. * Linter nazi says you need that empty line. * Rename a to addr, leave client empty for unix sockets. * Add --unix support when sanic is run as module. * Remove remove_route, deprecated in 19.6. * Improved unix socket binding. * More robust creating and unlinking of sockets. Show proper and not temporary name in conn_info. * Add comprehensive tests for unix socket mode. * Hide some imports inside functions to avoid Windows failure. * Mention unix socket mode in deployment docs. * Fix merge commit. * Make test_unix_connection_multiple_workers pickleable for spawn mode multiprocessing. Co-authored-by: L. Kärkkäinen <tronic@users.noreply.github.com> Co-authored-by: Adam Hopkins <admhpkns@gmail.com>
2020-06-29 06:55:32 +01:00
unix=args.unix,
2018-10-14 01:55:33 +01:00
workers=args.workers,
debug=args.debug,
ssl=ssl,
)
except ImportError as e:
2018-10-14 01:55:33 +01:00
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"
2018-10-14 01:55:33 +01:00
)
2018-10-26 09:29:53 +01:00
except ValueError:
logger.exception("Failed to run app")
if __name__ == "__main__":
main()