code: def build_reporters(
      job_name: str,
      m: Dict[str, float],
      local_path: Optional[str] = None,
      gcloud_path: Optional[str] = None,
      tensorboard_path: Optional[str] = None,
  ) -> Dict[str, uv.AbstractReporter]:
      """Returns a dict of namespace to reporter."""
  
      # This reporter keeps all metrics in an internal dictionary of metric name
      # (string) to a list of metric values.
      #
      # The "stepped()" function here is a convenience, here in the early days of
      # this library, that wraps every value that reaches the MemoryReporter - say,
      # the number 10.5 - in a dictionary that looks like
      #
      # {"step": step_idx, "value": 10.5}
      #
      # This lets you access the value of the step later.
      mem = uv.MemoryReporter(m).stepped()
  
      # The "tqdm()" function returns a LoggingReporter() implementation that's
      # able to log above a tqdm progress bar. If you simply called
      # r.LoggingReporter(), the reporter would log to sys.stdout.
      logging = uv.LoggingReporter.tqdm()
  
      mlf = MLFlowReporter()
  
      # This is a new, compound reporter. When you log to this compound reporter,
      # it will turn around and pass metrics to the memory and logging reporters.
      base = mem.plus(logging, mlf)
  
      # reporters that persist to disk. These are optional, so we overwrite base
      # only if local_path or gcloud_path are supplied.
      if local_path is not None:
          local = local_reporter(local_path, job_name)
          base = base.plus(local)
  
      # This reporter, if the gcloud_path is supplied, will log to a gcloud bucket.
      if gcloud_path is not None:
          gcloud = gcloud_reporter(gcloud_path, job_name)
          base = base.plus(gcloud)
  
      # See how easy it is to build non-trivial reporters? At this stage, we have a
      # reporter that is logging to four reporter implementations - an in-memory
      # version for immediate graphing (imagine a notebook usecase), a logging
      # version, and two separate filesystem instances.
  
      # Finally, let's append a tensorboard reporter if the user's supplied it:
  
      if tensorboard_path is not None:
          tboard = tensorboard_reporter(job_name)
          base = base.plus(tboard).map_values(
              lambda step, v: u.to_metric(v)
          )
  
      # The final step here is to call "map_values" with a function that will
      # accept each step and value as it's reported, and transform the value before
      # passing into all of our underlying reporters. to_metric, in this case,
      # simply extracts the numpy() argument if it exists on the supplied value.
      # This allows you to report tensors directly without calling numpy() before
      # reporting them.
      base = base.map_values(lambda step, v: u.to_metric(v))
  
      # Here we return the base reporter itself, AND a convenient map of string to
      # a few new reporters. Each one will act just like base, except each will
      # prepend a different prefix onto any metric passed in.
      return base, {
          "test": base.with_prefix("test"),
          "train": base.with_prefix("train"),
          "model": base.with_prefix("model"),
      }
  
imports: from __future__ import division, print_function
  import getpass
  from typing import Dict, Optional
  import fs
  import tensorflow
  import tensorflow_datasets
  import tqdm
  import uv
  import uv.tensorflow.reporter
  import uv.util
  from absl import app
  from uv.fs.reporter import FSReporter
  from uv.mlflow.reporter import MLFlowReporter
  from trainer import cli
label_desc: Use image node_id 12 for calling a global function with example usage: build_reporters(job_name, m, local_path, gcloud_path, tensorboard_path) and returns: base,  dict