|
|
- import asyncio
- import logging
- import socket
- import sys
- from argparse import ArgumentParser
- from collections import Iterable
- from importlib import import_module
-
- from . import (helpers, web_app, web_exceptions, web_fileresponse,
- web_middlewares, web_protocol, web_request, web_response,
- web_routedef, web_runner, web_server, web_urldispatcher, web_ws)
- from .log import access_logger
- from .web_app import * # noqa
- from .web_exceptions import * # noqa
- from .web_fileresponse import * # noqa
- from .web_middlewares import * # noqa
- from .web_protocol import * # noqa
- from .web_request import * # noqa
- from .web_response import * # noqa
- from .web_routedef import * # noqa
- from .web_runner import * # noqa
- from .web_runner import AppRunner, GracefulExit, SockSite, TCPSite, UnixSite
- from .web_server import * # noqa
- from .web_urldispatcher import * # noqa
- from .web_ws import * # noqa
-
-
- __all__ = (web_protocol.__all__ +
- web_app.__all__ +
- web_fileresponse.__all__ +
- web_request.__all__ +
- web_response.__all__ +
- web_routedef.__all__ +
- web_exceptions.__all__ +
- web_urldispatcher.__all__ +
- web_ws.__all__ +
- web_server.__all__ +
- web_runner.__all__ +
- web_middlewares.__all__ +
- ('run_app',))
-
-
- def run_app(app, *, host=None, port=None, path=None, sock=None,
- shutdown_timeout=60.0, ssl_context=None,
- print=print, backlog=128, access_log_class=helpers.AccessLogger,
- access_log_format=helpers.AccessLogger.LOG_FORMAT,
- access_log=access_logger, handle_signals=True,
- reuse_address=None, reuse_port=None):
- """Run an app locally"""
- loop = asyncio.get_event_loop()
-
- if asyncio.iscoroutine(app):
- app = loop.run_until_complete(app)
-
- runner = AppRunner(app, handle_signals=handle_signals,
- access_log_class=access_log_class,
- access_log_format=access_log_format,
- access_log=access_log)
-
- loop.run_until_complete(runner.setup())
-
- sites = []
-
- try:
- if host is not None:
- if isinstance(host, (str, bytes, bytearray, memoryview)):
- sites.append(TCPSite(runner, host, port,
- shutdown_timeout=shutdown_timeout,
- ssl_context=ssl_context,
- backlog=backlog,
- reuse_address=reuse_address,
- reuse_port=reuse_port))
- else:
- for h in host:
- sites.append(TCPSite(runner, h, port,
- shutdown_timeout=shutdown_timeout,
- ssl_context=ssl_context,
- backlog=backlog,
- reuse_address=reuse_address,
- reuse_port=reuse_port))
- elif path is None and sock is None or port is not None:
- sites.append(TCPSite(runner, port=port,
- shutdown_timeout=shutdown_timeout,
- ssl_context=ssl_context, backlog=backlog,
- reuse_address=reuse_address,
- reuse_port=reuse_port))
-
- if path is not None:
- if isinstance(path, (str, bytes, bytearray, memoryview)):
- sites.append(UnixSite(runner, path,
- shutdown_timeout=shutdown_timeout,
- ssl_context=ssl_context,
- backlog=backlog))
- else:
- for p in path:
- sites.append(UnixSite(runner, p,
- shutdown_timeout=shutdown_timeout,
- ssl_context=ssl_context,
- backlog=backlog))
-
- if sock is not None:
- if not isinstance(sock, Iterable):
- sites.append(SockSite(runner, sock,
- shutdown_timeout=shutdown_timeout,
- ssl_context=ssl_context,
- backlog=backlog))
- else:
- for s in sock:
- sites.append(SockSite(runner, s,
- shutdown_timeout=shutdown_timeout,
- ssl_context=ssl_context,
- backlog=backlog))
- for site in sites:
- loop.run_until_complete(site.start())
- try:
- if print: # pragma: no branch
- names = sorted(str(s.name) for s in runner.sites)
- print("======== Running on {} ========\n"
- "(Press CTRL+C to quit)".format(', '.join(names)))
- loop.run_forever()
- except (GracefulExit, KeyboardInterrupt): # pragma: no cover
- pass
- finally:
- loop.run_until_complete(runner.cleanup())
- if hasattr(loop, 'shutdown_asyncgens'):
- loop.run_until_complete(loop.shutdown_asyncgens())
- loop.close()
-
-
- def main(argv):
- arg_parser = ArgumentParser(
- description="aiohttp.web Application server",
- prog="aiohttp.web"
- )
- arg_parser.add_argument(
- "entry_func",
- help=("Callable returning the `aiohttp.web.Application` instance to "
- "run. Should be specified in the 'module:function' syntax."),
- metavar="entry-func"
- )
- arg_parser.add_argument(
- "-H", "--hostname",
- help="TCP/IP hostname to serve on (default: %(default)r)",
- default="localhost"
- )
- arg_parser.add_argument(
- "-P", "--port",
- help="TCP/IP port to serve on (default: %(default)r)",
- type=int,
- default="8080"
- )
- arg_parser.add_argument(
- "-U", "--path",
- help="Unix file system path to serve on. Specifying a path will cause "
- "hostname and port arguments to be ignored.",
- )
- args, extra_argv = arg_parser.parse_known_args(argv)
-
- # Import logic
- mod_str, _, func_str = args.entry_func.partition(":")
- if not func_str or not mod_str:
- arg_parser.error(
- "'entry-func' not in 'module:function' syntax"
- )
- if mod_str.startswith("."):
- arg_parser.error("relative module names not supported")
- try:
- module = import_module(mod_str)
- except ImportError as ex:
- arg_parser.error("unable to import %s: %s" % (mod_str, ex))
- try:
- func = getattr(module, func_str)
- except AttributeError:
- arg_parser.error("module %r has no attribute %r" % (mod_str, func_str))
-
- # Compatibility logic
- if args.path is not None and not hasattr(socket, 'AF_UNIX'):
- arg_parser.error("file system paths not supported by your operating"
- " environment")
-
- logging.basicConfig(level=logging.DEBUG)
-
- app = func(extra_argv)
- run_app(app, host=args.hostname, port=args.port, path=args.path)
- arg_parser.exit(message="Stopped\n")
-
-
- if __name__ == "__main__": # pragma: no branch
- main(sys.argv[1:]) # pragma: no cover
|