code: def _GetMetadataUpdate(
        self, metadata_key='', recursive=True, wait=True, timeout=None):
      
      metadata_key = os.path.join(metadata_key, '') if recursive else metadata_key
      metadata_url = os.path.join(METADATA_SERVER, metadata_key)
      params = {
          'alt': 'json',
          'last_etag': self.etag,
          'recursive': recursive,
          'timeout_sec': timeout or self.timeout,
          'wait_for_change': wait,
      }
      while True:
        response = self._GetMetadataRequest(
            metadata_url, params=params, timeout=timeout)
        etag_updated = self._UpdateEtag(response)
        if wait and not etag_updated and not timeout:
          # Retry until the etag is updated.
          continue
        else:
          # One of the following are true:
          # - Waiting for change is not required.
          # - The etag is updated.
          # - The user specified a request timeout.
          break
      return json.loads(response.read().decode('utf-8'))
docs: Request the contents of metadata server and deserialize the response.
  
      Args:
        metadata_key: string, the metadata key to watch for changes.
        recursive: bool, True if we should recursively watch for metadata changes.
        wait: bool, True if we should wait for a metadata change.
        timeout: int, timeout in seconds for returning metadata output.
  
      Returns:
        json, the deserialized contents of the metadata server.