code: def _construct_clients(self):
      _, _, compute, tpu = construct_clients_from_provider_config(
          self.provider_config
      )
  
      # Dict of different resources provided by GCP.
      # At this moment - Compute and TPUs
      self.resources: Dict[GCPNodeType, GCPResource] = {}
  
      # Compute is always required
      self.resources[GCPNodeType.COMPUTE] = GCPCompute(
          compute,
          self.provider_config["project_id"],
          self.provider_config["availability_zone"],
          self.cluster_name,
      )
  
      # if there are no TPU nodes defined in config, tpu will be None.
      if tpu is not None:
          self.resources[GCPNodeType.TPU] = GCPTPU(
              tpu,
              self.provider_config["project_id"],
              self.provider_config["availability_zone"],
              self.cluster_name,
          )
  
imports: import copy
  import logging
  import time
  from functools import wraps
  from threading import RLock
  from types import ModuleType
  from typing import Any, Dict, List, Optional, Tuple
  import googleapiclient
  from ray.autoscaler._private.gcp.config import bootstrap_gcp, construct_clients_from_provider_config, get_node_type, tpu_accelerator_config_to_type
  from ray.autoscaler._private.gcp.node import GCPTPU
  from ray.autoscaler._private.gcp.node import GCPCompute, GCPNode, GCPNodeType, GCPResource
  from ray.autoscaler._private.gcp.tpu_command_runner import TPUCommandRunner
  from ray.autoscaler.command_runner import CommandRunnerInterface
  from ray.autoscaler.node_provider import NodeProvider
label_desc: Use image node_id 2 for calling the GCPNodeProvider obj's underlying member method code with example usage: obj._construct_clients() without return types