code: def on_preprocess_end(
      self,
      training_set: "Dataset",  # noqa
      validation_set: "Dataset",  # noqa
      test_set: "Dataset",  # noqa
      training_set_metadata: TrainingSetMetadataDict,
  ):
      self.training_set_metadata = training_set_metadata
  
imports: import logging
  import os
  import queue
  import threading
  from ludwig.api_annotations import DeveloperAPI, PublicAPI
  from ludwig.callbacks import Callback
  from ludwig.constants import TRAINER
  from ludwig.globals import MODEL_HYPERPARAMETERS_FILE_NAME, TRAIN_SET_METADATA_FILE_NAME
  from ludwig.types import TrainingSetMetadataDict
  from ludwig.utils.data_utils import chunk_dict, flatten_dict, save_json, to_json_dict
  from ludwig.utils.package_utils import LazyLoader
label_desc: Use image node_id 3 for calling the MlflowCallback obj's underlying member method code with example usage: obj.on_preprocess_end(training_set, validation_set, test_set, training_set_metadata) without return types