class_docstr: This is the `ExpManager` class for managing experiments. The API is designed similar to mlflow.
  (The link: https://mlflow.org/docs/latest/python_api/mlflow.html)
  
  The `ExpManager` is expected to be a singleton (btw, we can have multiple `Experiment`s with different uri. user can get different experiments from different uri, and then compare records of them). Global Config (i.e. `C`)  is also a singleton.
  
  So we try to align them together.  They share the same variable, which is called **default uri**. Please refer to `ExpManager.default_uri` for details of variable sharing.
  
  When the user starts an experiment, the user may want to set the uri to a specific uri (it will override **default uri** during this period), and then unset the **specific uri** and fallback to the **default uri**.    `ExpManager._active_exp_uri` is that **specific uri**.
docstr: Start an experiment. This method includes first get_or_create an experiment, and then
  set it to be active.
  
  Maintaining `_active_exp_uri` is included in start_exp, remaining implementation should be included in _end_exp in subclass
  
  Parameters
  ----------
  experiment_id : str
      id of the active experiment.
  experiment_name : str
      name of the active experiment.
  recorder_id : str
      id of the recorder to be started.
  recorder_name : str
      name of the recorder to be started.
  uri : str
      the current tracking URI.
  resume : boolean
      whether to resume the experiment and recorder.
  
  Returns
  -------
  An active experiment.
code: def start_exp(
      self,
      *,
      experiment_id: Optional[Text] = None,
      experiment_name: Optional[Text] = None,
      recorder_id: Optional[Text] = None,
      recorder_name: Optional[Text] = None,
      uri: Optional[Text] = None,
      resume: bool = False,
      **kwargs,
  ) -> Experiment:
      """
      Start an experiment. This method includes first get_or_create an experiment, and then
      set it to be active.
  
      Maintaining `_active_exp_uri` is included in start_exp, remaining implementation should be included in _end_exp in subclass
  
      Parameters
      ----------
      experiment_id : str
          id of the active experiment.
      experiment_name : str
          name of the active experiment.
      recorder_id : str
          id of the recorder to be started.
      recorder_name : str
          name of the recorder to be started.
      uri : str
          the current tracking URI.
      resume : boolean
          whether to resume the experiment and recorder.
  
      Returns
      -------
      An active experiment.
      """
      self._active_exp_uri = uri
      # The subclass may set the underlying uri back.
      # So setting `_active_exp_uri` come before `_start_exp`
      return self._start_exp(
          experiment_id=experiment_id,
          experiment_name=experiment_name,
          recorder_id=recorder_id,
          recorder_name=recorder_name,
          resume=resume,
          **kwargs,
      )
  
imports: from urllib.parse import urlparse
  import mlflow
  from filelock import FileLock
  from mlflow.exceptions import MlflowException, RESOURCE_ALREADY_EXISTS, ErrorCode
  from mlflow.entities import ViewType
  import os
  from typing import Optional, Text
  from .exp import MLflowExperiment, Experiment
  from ..config import C
  from .recorder import Recorder
  from ..log import get_module_logger
  from ..utils.exceptions import ExpAlreadyExistError
label_desc: Use image node_id 3 for calling the ExpManager obj's underlying member method code with example usage: obj.start_exp() and returns: self