code: def test_api_callbacks_checkpoints_per_epoch(
      tmpdir,
      csv_filename,
      epochs,
      batch_size,
      num_examples,
      checkpoints_per_epoch,
  ):
      mock_callback = mock.Mock(wraps=Callback())
  
      total_checkpoints = epochs * checkpoints_per_epoch
      total_batches = epochs * (num_examples / batch_size)
  
      input_features = [
          sequence_feature(encoder={"reduce_output": "sum"})
      ]
      output_features = [
          category_feature(
              decoder={"vocab_size": 5}, reduce_input="sum"
          )
      ]
  
      config = {
          "input_features": input_features,
          "output_features": output_features,
          "combiner": {"type": "concat", "output_size": 14},
          TRAINER: {
              "epochs": epochs,
              "batch_size": batch_size,
              "checkpoints_per_epoch": checkpoints_per_epoch,
              "early_stop": 0,  # Disable early stopping.
          },
      }
      model = LudwigModel(config, callbacks=[mock_callback])
  
      data_csv = generate_data(
          input_features,
          output_features,
          os.path.join(tmpdir, csv_filename),
          num_examples=num_examples,
      )
      val_csv = shutil.copyfile(
          data_csv, os.path.join(tmpdir, "validation.csv")
      )
      test_csv = shutil.copyfile(
          data_csv, os.path.join(tmpdir, "test.csv")
      )
  
      model.train(
          training_set=data_csv,
          validation_set=val_csv,
          test_set=test_csv,
      )
  
      assert mock_callback.on_epoch_start.call_count == epochs
      assert mock_callback.on_epoch_end.call_count == epochs
  
      assert (
          mock_callback.should_early_stop.call_count
          == total_checkpoints
      )
  
      assert (
          mock_callback.on_validation_start.call_count
          == total_checkpoints
      )
      assert (
          mock_callback.on_validation_end.call_count
          == total_checkpoints
      )
  
      assert mock_callback.on_test_start.call_count == total_checkpoints
      assert mock_callback.on_test_end.call_count == total_checkpoints
  
      assert mock_callback.on_batch_start.call_count == total_batches
      assert mock_callback.on_batch_end.call_count == total_batches
  
      assert mock_callback.on_eval_end.call_count == total_checkpoints
      assert mock_callback.on_eval_start.call_count == total_checkpoints
  
imports: import json
  import os
  import shutil
  from unittest import mock
  import pandas
  import pytest
  import torch
  import yaml
  from ludwig.api import LudwigModel
  from ludwig.callbacks import Callback
  from ludwig.constants import BATCH_SIZE, ENCODER, TRAINER, TYPE
  from ludwig.globals import MODEL_HYPERPARAMETERS_FILE_NAME
  from ludwig.models.inference import InferenceModule
  from ludwig.utils.data_utils import read_csv
  from tests.integration_tests.utils import category_feature, ENCODERS, generate_data, get_weights, image_feature, run_api_experiment, sequence_feature, text_feature
label_desc: Use image node_id 12 for calling a global function with example usage: test_api_callbacks_checkpoints_per_epoch(tmpdir, csv_filename, epochs, batch_size, num_examples, checkpoints_per_epoch) without return types