docstr: Registers metadata with a task.
  
  Note that the same metadata can be registered multiple times for the same task (for example
  by multiple attempts). Internally, the timestamp of when the registration call is made is
  also recorded allowing the user to determine the latest value of the metadata.
  
  Parameters
  ----------
  run_id : int
      Run ID for the task
  step_name : string
      Step name for the task
  task_id : int
      Task ID for the task
  metadata : List of MetaDatum
      Metadata associated with this task
code: def register_metadata(self, run_id, step_name, task_id, metadata):
      """
      Registers metadata with a task.
  
      Note that the same metadata can be registered multiple times for the same task (for example
      by multiple attempts). Internally, the timestamp of when the registration call is made is
      also recorded allowing the user to determine the latest value of the metadata.
  
      Parameters
      ----------
      run_id : int
          Run ID for the task
      step_name : string
          Step name for the task
      task_id : int
          Task ID for the task
      metadata : List of MetaDatum
          Metadata associated with this task
      """
      raise NotImplementedError()
  
imports: import json
  import os
  import re
  import time
  from collections import namedtuple
  from itertools import chain
  from metaflow.exception import MetaflowInternalError, MetaflowTaggingError
  from metaflow.tagging_util import validate_tag
  from metaflow.util import get_username, resolve_identity_as_tuple, is_stringish
label_desc: Use image node_id 10 for calling the MetadataProvider obj's underlying member method code with example usage: obj.register_metadata(run_id, step_name, task_id, metadata) without return types