code: def _get_web_address(self):
      svc_data = self._core_api.read_namespaced_service(
          "marsservice", self._namespace
      ).to_dict()
      node_port = svc_data["spec"]["ports"][0]["node_port"]
  
      # docker desktop use a VM to hold docker processes, hence
      # we need to use API address instead
      desktop_nodes = self._core_api.list_node(
          field_selector="metadata.name=docker-desktop"
      ).to_dict()
      if desktop_nodes["items"]:  # pragma: no cover
          host_ip = urlparse(
              self._core_api.api_client.configuration.host
          ).netloc.split(":", 1)[0]
      else:
          web_pods = self._core_api.list_namespaced_pod(
              self._namespace,
              label_selector="mars/service-type="
              + MarsSupervisorsConfig.rc_name,
          ).to_dict()
          host_ip = random.choice(web_pods["items"])["status"][
              "host_ip"
          ]
      return f"http://{host_ip}:{node_port}"
  
imports: import asyncio
  import functools
  import logging
  import random
  import time
  import uuid
  from urllib.parse import urlparse
  from ...lib.aio import new_isolation, stop_isolation
  from ...services.cluster.api import WebClusterAPI
  from ...session import new_session
  from ...utils import calc_size_by_str
  from ..utils import wait_services_ready
  from .config import NamespaceConfig, RoleConfig, RoleBindingConfig, ServiceConfig, MarsSupervisorsConfig, MarsWorkersConfig
label_desc: Use image node_id 12 for calling the KubernetesCluster obj's underlying member method code with example usage: obj._get_web_address() and returns: str, host_ip, str, node_port