code: def _register_context_if_not_exist(
      metadata_handle: metadata.Metadata,
      context_spec: pipeline_pb2.ContextSpec,
      parent_contexts: Optional[
          List[metadata_store_pb2.Context]
      ] = None,
  ) -> metadata_store_pb2.Context:
      """Registers a context if not exist, otherwise returns the existing one.
  
      Args:
        metadata_handle: A handler to access MLMD store.
        context_spec: A pipeline_pb2.ContextSpec message that instructs registering
          of a context.
        parent_contexts: Optional. If it is provided, will set the new context as a
          child of the parent contexts.
  
      Returns:
        An MLMD context.
      """
      context_type_name = context_spec.type.name
      context_name = data_types_utils.get_value(context_spec.name)
      context = metadata_handle.store.get_context_by_type_and_name(
          type_name=context_type_name, context_name=context_name
      )
      if context is not None:
          return context
  
      logging.debug(
          "Failed to get context of type %s and name %s",
          context_type_name,
          context_name,
      )
      # If Context is not found, try to register it.
      context = _generate_context_proto(
          metadata_handle=metadata_handle, context_spec=context_spec
      )
      try:
          [context_id] = metadata_handle.store.put_contexts([context])
          context.id = context_id
      # This might happen in cases we have parallel executions of nodes.
      except mlmd.errors.AlreadyExistsError:
          logging.debug("Context %s already exists.", context_name)
          context = metadata_handle.store.get_context_by_type_and_name(
              type_name=context_type_name, context_name=context_name
          )
          assert context is not None, (
              "Context is missing for %s while put_contexts "
              "reports that it existed."
          ) % (context_name)
  
      logging.debug("ID of context %s is %s.", context_spec, context.id)
  
      if parent_contexts:
          for parent_context in parent_contexts:
              put_parent_context_if_not_exists(
                  metadata_handle,
                  parent_id=parent_context.id,
                  child_id=context.id,
              )
      return context
  
file_path: tfx/tfx/orchestration/portable/mlmd/context_lib.py
imports: from typing import List, Optional
  from absl import logging
  from tfx.dsl.compiler import constants
  from tfx.orchestration import data_types_utils
  from tfx.orchestration import metadata
  from tfx.orchestration.portable.mlmd import common_utils
  from tfx.utils import metrics_utils
  from tfx.proto.orchestration import pipeline_pb2
  from tfx.utils import telemetry_utils
  import ml_metadata
  from ml_metadata import errors
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 2 for calling a global function with example usage: _register_context_if_not_exist(metadata_handle, context_spec, parent_contexts) and returns: context, context