class_docstr: Stackdriver Hook for connecting with Google Cloud Stackdriver.
docstr:  Creates a new alert or updates an existing policy identified the name field in the alerts parameter.
  
  :param project_id: The project in which alert needs to be created/updated.
  :param alerts: A JSON string or file that specifies all the alerts that needs
       to be either created or updated. For more details, see
       https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.alertPolicies#AlertPolicy.
       (templated)
  :param retry: A retry object used to retry requests. If ``None`` is
      specified, requests will be retried using a default configuration.
  :param timeout: The amount of time, in seconds, to wait
      for the request to complete. Note that if ``retry`` is
      specified, the timeout applies to each individual attempt.
  :param metadata: Additional metadata that is provided to the method.
docstr_tok: ["Creates","a","new","alert","or","updates","an","existing","policy","identified","the","name","field","in","the","alerts","parameter",".",":","param","project_id",":","The","project","in","which","alert","needs","to","be","created\/updated",".",":","param","alerts",":","A","JSON","string","or","file","that","specifies","all","the","alerts","that","needs","to","be","either","created","or","updated",".","For","more","details",",","see","https",":","\/\/cloud.google.com\/monitoring\/api\/ref_v3\/rest\/v3\/projects.alertPolicies","#","AlertPolicy",".","(","templated",")",":","param","retry",":","A","retry","object","used","to","retry","requests",".","If","``","None","``","is","specified",",","requests","will","be","retried","using","a","default","configuration",".",":","param","timeout",":","The","amount","of","time",",","in","seconds",",","to","wait","for","the","request","to","complete",".","Note","that","if","``","retry","``","is","specified",",","the","timeout","applies","to","each","individual","attempt",".",":","param","metadata",":","Additional","metadata","that","is","provided","to","the","method","."]
code: def upsert_alert(
      self,
      alerts: str,
      project_id: str = PROVIDE_PROJECT_ID,
      retry: Retry | _MethodDefault = DEFAULT,
      timeout: float | None = None,
      metadata: Sequence[tuple[str, str]] = (),
  ) -> None:
      """
       Creates a new alert or updates an existing policy identified the name field in the alerts parameter.
  
      :param project_id: The project in which alert needs to be created/updated.
      :param alerts: A JSON string or file that specifies all the alerts that needs
           to be either created or updated. For more details, see
           https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.alertPolicies#AlertPolicy.
           (templated)
      :param retry: A retry object used to retry requests. If ``None`` is
          specified, requests will be retried using a default configuration.
      :param timeout: The amount of time, in seconds, to wait
          for the request to complete. Note that if ``retry`` is
          specified, the timeout applies to each individual attempt.
      :param metadata: Additional metadata that is provided to the method.
      """
      policy_client = self._get_policy_client()
      channel_client = self._get_channel_client()
  
      record = json.loads(alerts)
      existing_policies = [
          policy["name"]
          for policy in self.list_alert_policies(
              project_id=project_id, format_="dict"
          )
      ]
      existing_channels = [
          channel["name"]
          for channel in self.list_notification_channels(
              project_id=project_id, format_="dict"
          )
      ]
      policies_ = []
      channels = []
      for channel in record.get("channels", []):
          channels.append(NotificationChannel(**channel))
      for policy in record.get("policies", []):
          policies_.append(AlertPolicy(**policy))
  
      channel_name_map = {}
  
      for channel in channels:
          channel.verification_status = (
              monitoring_v3.NotificationChannel.VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED
          )
  
          if channel.name in existing_channels:
              channel_client.update_notification_channel(
                  request={"notification_channel": channel},
                  retry=retry,
                  timeout=timeout,
                  metadata=metadata,
              )
          else:
              old_name = channel.name
              channel.name = None
              new_channel = channel_client.create_notification_channel(
                  request={
                      "name": f"projects/{project_id}",
                      "notification_channel": channel,
                  },
                  retry=retry,
                  timeout=timeout,
                  metadata=metadata,
              )
              channel_name_map[old_name] = new_channel.name
  
      for policy in policies_:
          policy.creation_record = None
          policy.mutation_record = None
  
          for i, channel in enumerate(policy.notification_channels):
              new_channel = channel_name_map.get(channel)
              if new_channel:
                  policy.notification_channels[i] = new_channel
  
          if policy.name in existing_policies:
              with contextlib.suppress(InvalidArgument):
                  policy_client.update_alert_policy(
                      request={"alert_policy": policy},
                      retry=retry,
                      timeout=timeout,
                      metadata=metadata,
                  )
          else:
              policy.name = None
              for condition in policy.conditions:
                  condition.name = None
              policy_client.create_alert_policy(
                  request={
                      "name": f"projects/{project_id}",
                      "alert_policy": policy,
                  },
                  retry=retry,
                  timeout=timeout,
                  metadata=metadata,
              )
  
imports: from __future__ import annotations
  import contextlib
  import json
  from typing import TYPE_CHECKING, Any, Sequence
  from google.api_core.exceptions import InvalidArgument
  from google.api_core.gapic_v1.method import DEFAULT, _MethodDefault
  from google.cloud import monitoring_v3
  from google.cloud.monitoring_v3 import AlertPolicy, NotificationChannel
  from google.protobuf.field_mask_pb2 import FieldMask
  from googleapiclient.errors import HttpError
  from airflow.exceptions import AirflowException
  from airflow.providers.google.common.hooks.base_google import PROVIDE_PROJECT_ID, GoogleBaseHook
label_desc: Use image node_id 8 for calling the StackdriverHook obj's underlying member method code with example usage: obj.upsert_alert(alerts, project_id, retry, timeout, metadata) without return types