def host_bento(
    bento_name: str | Tag | None = None,
    project_path: str = ".",
    config_file: str | None = None,
    deployment_mode: t.Literal["standalone", "distributed", "container"] = "standalone",
    bentoml_home: str | None = None,
    use_grpc: bool = False,
    clean_context: contextlib.ExitStack | None = None,
    host: str = "127.0.0.1",
    timeout: float = 120,
    backend: str = "docker",
    protocol_version: str = LATEST_PROTOCOL_VERSION,
    container_mode_options: dict[str, t.Any] = None,
) -> t.Generator[str, None, None]:
    """
    Host a bentoml service, yields the host URL.

    Args:
        bento: a bento tag or :code:`module_path:service`
        project_path: the path to the project directory
        config_file: the path to the config file
        deployment_mode: the deployment mode, one of :code:`standalone`, :code:`docker` or :code:`distributed`
        clean_context: a contextlib.ExitStack to clean up the intermediate files,
                       like docker image and bentos. If None, it will be created. Used for reusing
                       those files in the same test session.
        bentoml_home: if set, we will change the given BentoML home folder to :code:`bentoml_home`. Default
                      to :code:`$HOME/bentoml`
        use_grpc: if True, running gRPC tests.
        host: set a given host for the bento, default to ``127.0.0.1``
        timeout: the timeout for the server to start
        backend: the backend to use for building container, default to ``docker``

    Returns:
        :obj:`str`: a generated host URL where we run the test bento.
    """
    import bentoml

    # NOTE: clean_context here to ensure we can close all running context manager
    # to avoid dangling processes. When running pytest, we have a clean_context fixture
    # as a ExitStack.
    if clean_context is None:
        clean_context = contextlib.ExitStack()
        clean_on_exit = True
    else:
        clean_on_exit = False

    # NOTE: we need to set the BENTOML_HOME to a temporary folder to avoid
    # conflict with the user's BENTOML_HOME.
    if bentoml_home:
        from bentoml._internal.configuration.containers import BentoMLContainer

        BentoMLContainer.bentoml_home.set(bentoml_home)
    try:
        if bento_name is None or not bentoml.list(bento_name):
            bento = clean_context.enter_context(
                build(project_path, cleanup=clean_on_exit)
            )
        else:
            bento = bentoml.get(bento_name)
        print(
            f"Hosting BentoServer '{bento.tag}' in {deployment_mode} mode at '{project_path}'{' with config file ' + config_file if config_file else ''}."
        )
        if deployment_mode == "standalone":
            with run_bento_server_standalone(
                bento.path,
                config_file=config_file,
                use_grpc=use_grpc,
                host=host,
                timeout=timeout,
                protocol_version=protocol_version,
            ) as host_url:
                yield host_url
        elif deployment_mode == "container":
            from bentoml._internal.container import REGISTERED_BACKENDS

            if container_mode_options is None:
                container_mode_options = {}

            if "platform" not in container_mode_options:
                # NOTE: by default, we use linux/amd64 for the container image
                container_mode_options["platform"] = "linux/amd64"

            platform = container_mode_options["platform"]
            if backend not in REGISTERED_BACKENDS:
                raise ValueError(
                    f"Unknown backend: {backend}. To register your custom backend, use 'bentoml.container.register_backend()'"
                )
            container_tag = clean_context.enter_context(
                containerize(
                    bento.tag,
                    use_grpc=use_grpc,
                    backend=backend,
                    **container_mode_options,
                )
            )
            with run_bento_server_container(
                container_tag,
                config_file=config_file,
                use_grpc=use_grpc,
                host=host,
                timeout=timeout,
                backend=backend,
                protocol_version=protocol_version,
                platform=platform,
            ) as host_url:
                yield host_url
        elif deployment_mode == "distributed":
            with run_bento_server_distributed(
                bento.tag,
                config_file=config_file,
                use_grpc=use_grpc,
                host=host,
                timeout=timeout,
                protocol_version=protocol_version,
            ) as host_url:
                yield host_url
        else:
            raise ValueError(f"Unknown deployment mode: {deployment_mode}") from None
    finally:
        print("Shutting down bento server...")
        if clean_on_exit:
            print("Cleaning on exit...")
            clean_context.close()
Host a bentoml service, yields the host URL.

Args:
bento: a bento tag or :code:`module_path:service`
project_path: the path to the project directory
config_file: the path to the config file
deployment_mode: the deployment mode, one of :code:`standalone`, :code:`docker` or :code:`distributed`
clean_context: a contextlib.ExitStack to clean up the intermediate files,
like docker image and bentos. If None, it will be created. Used for reusing
those files in the same test session.
bentoml_home: if set, we will change the given BentoML home folder to :code:`bentoml_home`. Default
to :code:`$HOME/bentoml`
use_grpc: if True, running gRPC tests.
host: set a given host for the bento, default to ``127.0.0.1``
timeout: the timeout for the server to start
backend: the backend to use for building container, default to ``docker``

Returns:
:obj:`str`: a generated host URL where we run the test bento.
src/bentoml/testing/server.py