code: def test_custom_input_procedure(self):
      class CustomJsonReader(JsonReader):
          def __init__(self, ioctx: IOContext):
              super().__init__(ioctx.input_config["input_files"], ioctx)
  
      def input_creator(ioctx: IOContext) -> InputReader:
          return ShuffledInput(CustomJsonReader(ioctx))
  
      register_input("custom_input", input_creator)
      test_input_procedure = [
          "custom_input",
          input_creator,
          "ray.rllib.examples.custom_input_api.CustomJsonReader",
      ]
  
      for input_procedure in test_input_procedure:
          config = (
              PPOConfig()
              .environment("CartPole-v1")
              .offline_data(input_=input_procedure)
              .evaluation(off_policy_estimation_methods={})
          )
  
          for fw in framework_iterator(
              config, frameworks=("torch", "tf")
          ):
              self.write_outputs(self.test_dir, fw)
              config.offline_data(
                  input_config={"input_files": self.test_dir + fw}
              )
              algo = config.build()
              result = algo.train()
              self.assertEqual(result["timesteps_total"], 4000)
              self.assertTrue(np.isnan(result["episode_reward_mean"]))
              algo.stop()
  
imports: import glob
  import json
  import numpy
  import os
  import random
  import shutil
  import tempfile
  import unittest
  import ray
  from ray.tune.registry import register_env, register_input, registry_get_input, registry_contains_input
  from ray.rllib.algorithms.algorithm_config import AlgorithmConfig
  from ray.rllib.algorithms.pg import PGConfig
  from ray.rllib.algorithms.ppo import PPOConfig
  from ray.rllib.examples.env.multi_agent import MultiAgentCartPole
  from ray.rllib.offline import IOContext, JsonWriter, JsonReader, InputReader, ShuffledInput, DatasetWriter
  from ray.rllib.offline.json_reader import from_json_data
  from ray.rllib.offline.json_writer import _to_json_dict, _to_json
  from ray.rllib.policy.sample_batch import SampleBatch, convert_ma_batch_to_sample_batch
  from ray.rllib.utils.test_utils import framework_iterator
label_desc: Use image node_id 14 for calling the AgentIOTest obj's underlying member method code with example usage: obj.test_custom_input_procedure() and returns: ShuffledInput