docs: def run_simple(
      hostname,
      port,
      application,
      use_reloader=False,
      use_debugger=False,
      use_evalex=True,
      extra_files=None,
      reloader_interval=1,
      reloader_type="auto",
      threaded=False,
      processes=1,
      request_handler=None,
      static_files=None,
      passthrough_errors=False,
      ssl_context=None,
  ):
      """Start a WSGI application. Optional features include a reloader,
      multithreading and fork support.
  
      This function has a command-line interface too::
  
          python -m werkzeug.serving --help
  
      .. versionadded:: 0.5
         `static_files` was added to simplify serving of static files as well
         as `passthrough_errors`.
  
      .. versionadded:: 0.6
         support for SSL was added.
  
      .. versionadded:: 0.8
         Added support for automatically loading a SSL context from certificate
         file and private key.
  
      .. versionadded:: 0.9
         Added command-line interface.
  
      .. versionadded:: 0.10
         Improved the reloader and added support for changing the backend
         through the `reloader_type` parameter.  See :ref:`reloader`
         for more information.
  
      .. versionchanged:: 0.15
          Bind to a Unix socket by passing a path that starts with
          ``unix://`` as the ``hostname``.
  
      :param hostname: The host to bind to, for example ``'localhost'``.
          If the value is a path that starts with ``unix://`` it will bind
          to a Unix socket instead of a TCP socket..
      :param port: The port for the server.  eg: ``8080``
      :param application: the WSGI application to execute
      :param use_reloader: should the server automatically restart the python
                           process if modules were changed?
      :param use_debugger: should the werkzeug debugging system be used?
      :param use_evalex: should the exception evaluation feature be enabled?
      :param extra_files: a list of files the reloader should watch
                          additionally to the modules.  For example configuration
                          files.
      :param reloader_interval: the interval for the reloader in seconds.
      :param reloader_type: the type of reloader to use.  The default is
                            auto detection.  Valid values are ``'stat'`` and
                            ``'watchdog'``. See :ref:`reloader` for more
                            information.
      :param threaded: should the process handle each request in a separate
                       thread?
      :param processes: if greater than 1 then handle each request in a new process
                        up to this maximum number of concurrent processes.
      :param request_handler: optional parameter that can be used to replace
                              the default one.  You can use this to replace it
                              with a different
                              :class:`~BaseHTTPServer.BaseHTTPRequestHandler`
                              subclass.
      :param static_files: a list or dict of paths for static files.  This works
                           exactly like :class:`SharedDataMiddleware`, it's actually
                           just wrapping the application in that middleware before
                           serving.
      :param passthrough_errors: set this to `True` to disable the error catching.
                                 This means that the server will die on errors but
                                 it can be useful to hook debuggers in (pdb etc.)
      :param ssl_context: an SSL context for the connection. Either an
                          :class:`ssl.SSLContext`, a tuple in the form
                          ``(cert_file, pkey_file)``, the string ``'adhoc'`` if
                          the server should automatically create one, or ``None``
                          to disable SSL (which is the default).
      """
      if not isinstance(port, int):
          raise TypeError("port must be an integer")
      if use_debugger:
          from .debug import DebuggedApplication
  
          application = DebuggedApplication(application, use_evalex)
      if static_files:
          from .middleware.shared_data import SharedDataMiddleware
  
          application = SharedDataMiddleware(application, static_files)
  
      def log_startup(sock):
          display_hostname = hostname if hostname not in ("", "*") else "localhost"
          quit_msg = "(Press CTRL+C to quit)"
          if sock.family == af_unix:
              _log("info", " * Running on %s %s", display_hostname, quit_msg)
          else:
              if ":" in display_hostname:
                  display_hostname = "[%s]" % display_hostname
              port = sock.getsockname()[1]
              _log(
                  "info",
                  " * Running on %s://%s:%d/ %s",
                  "http" if ssl_context is None else "https",
                  display_hostname,
                  port,
                  quit_msg,
              )
  
      def inner():
          try:
              fd = int(os.environ["WERKZEUG_SERVER_FD"])
          except (LookupError, ValueError):
              fd = None
          srv = make_server(
              hostname,
              port,
              application,
              threaded,
              processes,
              request_handler,
              passthrough_errors,
              ssl_context,
              fd=fd,
          )
          if fd is None:
              log_startup(srv.socket)
          srv.serve_forever()
  
      if use_reloader:
          # If we're not running already in the subprocess that is the
          # reloader we want to open up a socket early to make sure the
          # port is actually available.
          if not is_running_from_reloader():
              if port == 0 and not can_open_by_fd:
                  raise ValueError(
                      "Cannot bind to a random port with enabled "
                      "reloader if the Python interpreter does "
                      "not support socket opening by fd."
                  )
  
              # Create and destroy a socket so that any exceptions are
              # raised before we spawn a separate Python interpreter and
              # lose this ability.
              address_family = select_address_family(hostname, port)
              server_address = get_sockaddr(hostname, port, address_family)
              s = socket.socket(address_family, socket.SOCK_STREAM)
              s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
              s.bind(server_address)
              if hasattr(s, "set_inheritable"):
                  s.set_inheritable(True)
  
              # If we can open the socket by file descriptor, then we can just
              # reuse this one and our socket will survive the restarts.
              if can_open_by_fd:
                  os.environ["WERKZEUG_SERVER_FD"] = str(s.fileno())
                  s.listen(LISTEN_QUEUE)
                  log_startup(s)
              else:
                  s.close()
                  if address_family == af_unix:
                      _log("info", "Unlinking %s" % server_address)
                      os.unlink(server_address)
  
          # Do not use relative imports, otherwise "python -m werkzeug.serving"
          # breaks.
          from ._reloader import run_with_reloader
  
          run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
      else:
          inner()