hunk.code_window:         if isinstance(module, str):
               # module_path is a local path or a URI.
               module_path = module
           elif isinstance(module, ModuleType):
               # NOTE(edoakes): Python allows some installed Python packages to
               # be split into multiple directories. We could probably handle
  
hunk.labels: keep keep add keep keep keep
hunk.after_edit:         elif isinstance(module, Path):
               module_path = str(module)
  
hunk.file_path: python/ray/_private/runtime_env/py_modules.py
hunk.type: add
file: #!/usr/bin/env python
  import json
  import os
  
  import click
  
  import ray
  from ray.serve.api import Deployment
  from ray.serve.config import DeploymentMode
  from ray._private.utils import import_attr
  from ray import serve
  from ray.serve.constants import (DEFAULT_CHECKPOINT_PATH, DEFAULT_HTTP_HOST,
                                   DEFAULT_HTTP_PORT)
  
  
  @click.group(
      help="[EXPERIMENTAL] CLI for managing Serve instances on a Ray cluster.")
  @click.option(
      "--address",
      "-a",
      default=os.environ.get("RAY_ADDRESS", "auto"),
      required=False,
      type=str,
      help="Address of the running Ray cluster to connect to. "
      "Defaults to \"auto\".")
  @click.option(
      "--namespace",
      "-n",
      default="serve",
      required=False,
      type=str,
      help="Ray namespace to connect to. Defaults to \"serve\".")
  @click.option(
      "--runtime-env-json",
      default=r"{}",
      required=False,
      type=str,
      help=("Runtime environment dictionary to pass into ray.init. "
            "Defaults to empty."))
  def cli(address, namespace, runtime_env_json):
      ray.init(
          address=address,
          namespace=namespace,
          runtime_env=json.loads(runtime_env_json),
      )
  
  
  @cli.command(help="Start a detached Serve instance on the Ray cluster.")
  @click.option(
      "--http-host",
      default=DEFAULT_HTTP_HOST,
      required=False,
      type=str,
      help="Host for HTTP servers to listen on. "
      f"Defaults to {DEFAULT_HTTP_HOST}.")
  @click.option(
      "--http-port",
      default=DEFAULT_HTTP_PORT,
      required=False,
      type=int,
      help="Port for HTTP servers to listen on. "
      f"Defaults to {DEFAULT_HTTP_PORT}.")
  @click.option(
      "--http-location",
      default=DeploymentMode.HeadOnly,
      required=False,
      type=click.Choice(list(DeploymentMode)),
      help="Location of the HTTP servers. Defaults to HeadOnly.")
  @click.option(
      "--checkpoint-path",
      default=DEFAULT_CHECKPOINT_PATH,
      required=False,
      type=str,
      hidden=True,
  )
  def start(http_host, http_port, http_location, checkpoint_path):
      serve.start(
          detached=True,
          http_options=dict(
              host=http_host,
              port=http_port,
              location=http_location,
          ),
          _checkpoint_path=checkpoint_path)
  
  
  @cli.command(help="Shutdown the running Serve instance on the Ray cluster.")
  def shutdown():
      serve.api._connect()
      serve.shutdown()
  
  
  @cli.command(
      help="""
  [Experimental]
  Create a deployment in running Serve instance. The required argument is the
  import path for the deployment: ``my_module.sub_module.file.MyClass``. The
  class may or may not be decorated with ``@serve.deployment``.
  """,
      hidden=True,
  )
  @click.argument("deployment")
  @click.option(
      "--options-json",
      default=r"{}",
      required=False,
      type=str,
      help="JSON string for the deployments options")
  def deploy(deployment: str, options_json: str):
      deployment_cls = import_attr(deployment)
      if not isinstance(deployment_cls, Deployment):
          deployment_cls = serve.deployment(deployment_cls)
      options = json.loads(options_json)
      deployment_cls.options(**options).deploy()
  