code: def run_api_commands(
      input_features,
      output_features,
      data_csv,
      output_dir,
      skip_save_training_description=False,
      skip_save_training_statistics=False,
      skip_save_model=False,
      skip_save_progress=False,
      skip_save_log=False,
      skip_save_processed_input=False,
      skip_save_unprocessed_output=False,
      skip_save_predictions=False,
      skip_save_eval_stats=False,
      skip_collect_predictions=False,
      skip_collect_overall_stats=False,
  ):
      """Helper method to avoid code repetition in running an experiment.
  
      :param input_features: input schema
      :param output_features: output schema
      :param data_csv: path to data
      :return: None
      """
      config = {
          "input_features": input_features,
          "output_features": output_features,
          "combiner": {"type": "concat", "output_size": 14},
          TRAINER: {"epochs": 2, BATCH_SIZE: 128},
      }
  
      model = LudwigModel(config)
  
      # Training with csv
      model.train(
          dataset=data_csv,
          skip_save_training_description=skip_save_training_description,
          skip_save_training_statistics=skip_save_training_statistics,
          skip_save_model=skip_save_model,
          skip_save_progress=skip_save_progress,
          skip_save_log=skip_save_log,
          skip_save_processed_input=skip_save_processed_input,
          output_directory=output_dir,
      )
      model.predict(
          dataset=data_csv,
          skip_save_unprocessed_output=skip_save_unprocessed_output,
          skip_save_predictions=skip_save_predictions,
          output_directory=output_dir,
      )
      model.evaluate(
          dataset=data_csv,
          skip_save_unprocessed_output=skip_save_unprocessed_output,
          skip_save_predictions=skip_save_predictions,
          skip_save_eval_stats=skip_save_eval_stats,
          collect_predictions=not skip_collect_predictions,
          collect_overall_stats=not skip_collect_overall_stats,
          output_directory=output_dir,
      )
      model.experiment(
          dataset=data_csv,
          skip_save_training_description=skip_save_training_description,
          skip_save_training_statistics=skip_save_training_statistics,
          skip_save_model=skip_save_model,
          skip_save_progress=skip_save_progress,
          skip_save_log=skip_save_log,
          skip_save_processed_input=skip_save_processed_input,
          skip_save_unprocessed_output=skip_save_unprocessed_output,
          skip_save_predictions=skip_save_predictions,
          skip_save_eval_stats=skip_save_eval_stats,
          skip_collect_predictions=skip_collect_predictions,
          skip_collect_overall_stats=skip_collect_overall_stats,
          output_directory=output_dir,
      )
  
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 7 for calling a global function with example usage: run_api_commands(input_features, output_features, data_csv, output_dir, skip_save_training_description, skip_save_training_statistics, skip_save_model, skip_save_progress, skip_save_log, skip_save_processed_input, skip_save_unprocessed_output, skip_save_predictions, skip_save_eval_stats, skip_collect_predictions, skip_collect_overall_stats) without return types