class_docstr: Base class used for composite model structure definition
  
  Args:
      nodes: :obj:`PipelineNode` object(s)
      use_input_preprocessing: whether to do input preprocessing or not, ``True`` by default.
docstr: Makes obligatory and optional (if needed) steps of data preprocessing
  
  Args:
      input_data: to be copied and preprocessed
      is_fit_stage: True when it's fitting stage
  
  Returns:
      preprocessed copy of the original data
docstr_tok: ["Makes","obligatory","and","optional","(","if","needed",")","steps","of","data","preprocessing","Args",":","input_data",":","to","be","copied","and","preprocessed","is_fit_stage",":","True","when","it","'s","fitting","stage","Returns",":","preprocessed","copy","of","the","original","data"]
code: def _preprocess(
      self,
      input_data: Union[InputData, MultiModalData],
      *,
      is_fit_stage: bool = True,
  ) -> Union[InputData, MultiModalData]:
      """
      Makes obligatory and optional (if needed) steps of data preprocessing
  
      Args:
          input_data: to be copied and preprocessed
          is_fit_stage: True when it's fitting stage
  
      Returns:
          preprocessed copy of the original data
      """
      copied_input_data = deepcopy(input_data)
      if is_fit_stage:
          copied_input_data = (
              self.preprocessor.obligatory_prepare_for_fit(
                  copied_input_data
              )
          )
          # Make additional preprocessing if it is needed
          copied_input_data = (
              self.preprocessor.optional_prepare_for_fit(
                  pipeline=self, data=copied_input_data
              )
          )
          copied_input_data = self.preprocessor.convert_indexes_for_fit(
              pipeline=self, data=copied_input_data
          )
      else:
          copied_input_data = (
              self.preprocessor.obligatory_prepare_for_predict(
                  copied_input_data
              )
          )
          # Make additional preprocessing if it is needed
          copied_input_data = (
              self.preprocessor.optional_prepare_for_predict(
                  pipeline=self, data=copied_input_data
              )
          )
          copied_input_data = (
              self.preprocessor.convert_indexes_for_predict(
                  pipeline=self, data=copied_input_data
              )
          )
          copied_input_data = (
              self.preprocessor.update_indices_for_time_series(
                  copied_input_data
              )
          )
      return copied_input_data
  
imports: from copy import deepcopy
  from datetime import timedelta
  from os import PathLike
  from typing import Optional, Tuple, Union, Sequence, List, Dict
  import func_timeout
  from golem.core.dag.graph import Graph
  from golem.core.dag.graph_delegate import GraphDelegate
  from golem.core.dag.graph_node import GraphNode
  from golem.core.dag.graph_utils import distance_to_primary_level, graph_structure
  from golem.core.dag.linked_graph import LinkedGraph
  from golem.core.log import default_log
  from golem.core.optimisers.timer import Timer
  from golem.core.paths import copy_doc
  from golem.utilities.serializable import Serializable
  from golem.visualisation.graph_viz import NodeColorType
  from fedot.core.caching.pipelines_cache import OperationsCache
  from fedot.core.caching.preprocessing_cache import PreprocessingCache
  from fedot.core.data.data import InputData, OutputData
  from fedot.core.data.multi_modal import MultiModalData
  from fedot.core.operations.data_operation import DataOperation
  from fedot.core.operations.model import Model
  from fedot.core.pipelines.node import PipelineNode
  from fedot.core.pipelines.template import PipelineTemplate
  from fedot.core.repository.tasks import TaskTypesEnum
  from fedot.core.visualisation.pipeline_specific_visuals import PipelineVisualizer
  from fedot.preprocessing.dummy_preprocessing import DummyPreprocessor
  from fedot.preprocessing.preprocessing import DataPreprocessor
label_desc: Use image node_id 5 for calling the Pipeline obj's underlying member method code with example usage: obj._preprocess(input_data) and returns: copied_input_data