text: import argparse
  import logging
  import sys
  
  from .access import AccessLogGenerator
  from .endpoints import build_endpoint_description_strings
  from .server import Server
  from .utils import import_by_path
  
  logger = logging.getLogger(__name__)
  
  DEFAULT_HOST = "127.0.0.1"
  DEFAULT_PORT = 8000
  
  
  class CommandLineInterface(object):
      """
      Acts as the main CLI entry point for running the server.
      """
  
      description = "Django HTTP/WebSocket server"
  
      server_class = Server
  
      def __init__(self):
          self.parser = argparse.ArgumentParser(description=self.description)
          self.parser.add_argument(
              "-p", "--port", type=int, help="Port number to listen on", default=None
          )
          self.parser.add_argument(
              "-b",
              "--bind",
              dest="host",
              help="The host/address to bind to",
              default=None,
          )
          self.parser.add_argument(
              "--websocket_timeout",
              type=int,
              help="Maximum time to allow a websocket to be connected. -1 for infinite.",
              default=86400,
          )
          self.parser.add_argument(
              "--websocket_connect_timeout",
              type=int,
              help="Maximum time to allow a connection to handshake. -1 for infinite",
              default=5,
          )
          self.parser.add_argument(
              "-u",
              "--unix-socket",
              dest="unix_socket",
              help="Bind to a UNIX socket rather than a TCP host/port",
              default=None,
          )
          self.parser.add_argument(
              "--fd",
              type=int,
              dest="file_descriptor",
              help="Bind to a file descriptor rather than a TCP host/port or named unix socket",
              default=None,
          )
          self.parser.add_argument(
              "-e",
              "--endpoint",
              dest="socket_strings",
              action="append",
              help="Use raw server strings passed directly to twisted",
              default=[],
          )
          self.parser.add_argument(
              "-v",
              "--verbosity",
              type=int,
              help="How verbose to make the output",
              default=1,
          )
          self.parser.add_argument(
              "-t",
              "--http-timeout",
              type=int,
              help="How long to wait for worker before timing out HTTP connections",
              default=None,
          )
          self.parser.add_argument(
              "--access-log",
              help="Where to write the access log (- for stdout, the default for verbosity=1)",
              default=None,
          )
          self.parser.add_argument(
              "--ping-interval",
              type=int,
              help="The number of seconds a WebSocket must be idle before a keepalive ping is sent",
              default=20,
          )
          self.parser.add_argument(
              "--ping-timeout",
              type=int,
              help="The number of seconds before a WebSocket is closed if no response to a keepalive ping",
              default=30,
          )
          self.parser.add_argument(
              "--application-close-timeout",
              type=int,
              help="The number of seconds an ASGI application has to exit after client disconnect before it is killed",
              default=10,
          )
          self.parser.add_argument(
              "--ws-protocol",
              nargs="*",
              dest="ws_protocols",
              help="The WebSocket protocols you wish to support",
              default=None,
          )
          self.parser.add_argument(
              "--root-path",
              dest="root_path",
              help="The setting for the ASGI root_path variable",
              default="",
          )
          self.parser.add_argument(
              "--proxy-headers",
              dest="proxy_headers",
              help="Enable parsing and using of X-Forwarded-For and X-Forwarded-Port headers and using that as the "
              "client address",
              default=False,
              action="store_true",
          )
          self.parser.add_argument(
              "application",
              help="The application to dispatch to as path.to.module:instance.path",
          )
          sub_parsers = self.parser.add_subparsers()
          tcp_parser = sub_parsers.add_parser('--tcp_server', help="Start TCP server")
          tcp_parser.add_argument(
              '--tcp_port',
              type=int,
              dest='tcp_port',
              help='Port number of TCP Server',
              default=9999
          )
  
          self.server = None
  
      @classmethod
      def entrypoint(cls):
          """
          Main entrypoint for external starts.
          """
          cls().run(sys.argv[1:])
  
      def run(self, args):
          """
          Pass in raw argument list and it will decode them
          and run the server.
          """
          # Decode args
          args = self.parser.parse_args(args)
          # Set up logging
          logging.basicConfig(
              level={
                  0: logging.WARN,
                  1: logging.INFO,
                  2: logging.DEBUG,
                  3: logging.DEBUG,  # Also turns on asyncio debug
              }[args.verbosity],
              format="%(asctime)-15s %(levelname)-8s %(message)s",
          )
          # If verbosity is 1 or greater, or they told us explicitly, set up access log
          access_log_stream = None
          if args.access_log:
              if args.access_log == "-":
                  access_log_stream = sys.stdout
              else:
                  access_log_stream = open(args.access_log, "a", 1)
          elif args.verbosity >= 1:
              access_log_stream = sys.stdout
          # Import application
          sys.path.insert(0, ".")
          application = import_by_path(args.application)
          # Set up port/host bindings
          if not any(
              [
                  args.host,
                  args.port is not None,
                  args.unix_socket,
                  args.file_descriptor,
                  args.socket_strings,
              ]
          ):
              # no advanced binding options passed, patch in defaults
              args.host = DEFAULT_HOST
              args.port = DEFAULT_PORT
          elif args.host and args.port is None:
              args.port = DEFAULT_PORT
          elif args.port is not None and not args.host:
              args.host = DEFAULT_HOST
          # Build endpoint description strings from (optional) cli arguments
          endpoints = build_endpoint_description_strings(
              host=args.host,
              port=args.port,
              unix_socket=args.unix_socket,
              file_descriptor=args.file_descriptor,
          )
          endpoints = sorted(args.socket_strings + endpoints)
          # Start the server
          logger.info("Starting server at %s" % (", ".join(endpoints),))
          self.server = self.server_class(
              application=application,
              endpoints=endpoints,
              http_timeout=args.http_timeout,
              ping_interval=args.ping_interval,
              ping_timeout=args.ping_timeout,
              websocket_timeout=args.websocket_timeout,
              websocket_connect_timeout=args.websocket_connect_timeout,
              application_close_timeout=args.application_close_timeout,
              action_logger=AccessLogGenerator(access_log_stream)
              if access_log_stream
              else None,
              ws_protocols=args.ws_protocols,
              root_path=args.root_path,
              verbosity=args.verbosity,
              proxy_forwarded_address_header="X-Forwarded-For"
              if args.proxy_headers
              else None,
              proxy_forwarded_port_header="X-Forwarded-Port"
              if args.proxy_headers
              else None,
              proxy_forwarded_proto_header="X-Forwarded-Proto"
              if args.proxy_headers
              else None,
          )
          self.server.run()
  