class_docstr: The generic environment runner for the single agent case.
class_docstr_tok: ["The","generic","environment","runner","for","the","single","agent","case","."]
docstr: Runs and returns a sample (n timesteps or m episodes) on the env(s).
docstr_tok: ["Runs","and","returns","a","sample","(","n","timesteps","or","m","episodes",")","on","the","env","(","s",")","."]
code: def sample(
      self,
      *,
      num_timesteps: int = None,
      num_episodes: int = None,
      explore: bool = True,
      random_actions: bool = False,
      with_render_data: bool = False,
  ) -> List["SingleAgentEpisode"]:
      """Runs and returns a sample (n timesteps or m episodes) on the env(s)."""
      assert not (
          num_timesteps is not None and num_episodes is not None
      )
  
      # If no execution details are provided, use the config to try to infer the
      # desired timesteps/episodes to sample.
      if (
          num_timesteps is None
          and num_episodes is None
          and self.config.batch_mode == "truncate_episodes"
      ):
          num_timesteps = (
              self.config.get_rollout_fragment_length(
                  worker_index=self.worker_index
              )
              * self.num_envs
          )
  
      # Sample n timesteps.
      if num_timesteps is not None:
          samples = self._sample_timesteps(
              num_timesteps=num_timesteps,
              explore=explore,
              random_actions=random_actions,
              force_reset=False,
          )
      # Sample m episodes.
      elif num_episodes is not None:
          samples = self._sample_episodes(
              num_episodes=num_episodes,
              explore=explore,
              random_actions=random_actions,
              with_render_data=with_render_data,
          )
      # For complete episodes mode, sample as long as the number of timesteps
      # done is smaller than the `train_batch_size`.
      else:
          total = 0
          samples = []
          while total < self.config.train_batch_size:
              episodes = self._sample_episodes(
                  num_episodes=self.num_envs,
                  explore=explore,
                  random_actions=random_actions,
                  with_render_data=with_render_data,
              )
              total += sum(len(e) for e in episodes)
              samples.extend(episodes)
  
      # Make the `on_sample_end` callback.
      self._callbacks.on_sample_end(env_runner=self, samples=samples)
  
      return samples
  
imports: import gymnasium
  import numpy
  import tree
  from collections import defaultdict
  from functools import partial
  from typing import Dict, List, Optional
  from ray.rllib.algorithms.algorithm_config import AlgorithmConfig
  from ray.rllib.algorithms.callbacks import DefaultCallbacks
  from ray.rllib.core.rl_module.rl_module import RLModule, SingleAgentRLModuleSpec
  from ray.rllib.env.env_runner import EnvRunner
  from ray.rllib.env.single_agent_episode import SingleAgentEpisode
  from ray.rllib.env.utils import _gym_env_creator
  from ray.rllib.evaluation.metrics import RolloutMetrics
  from ray.rllib.policy.sample_batch import DEFAULT_POLICY_ID, SampleBatch
  from ray.rllib.utils.annotations import ExperimentalAPI, override
  from ray.rllib.utils.framework import try_import_tf, try_import_torch
  from ray.rllib.utils.torch_utils import convert_to_torch_tensor
  from ray.rllib.utils.typing import TensorType
  from ray.tune.registry import ENV_CREATOR, _global_registry
label_desc: Use image node_id 2 for calling the SingleAgentEnvRunner obj's underlying member method code with example usage: obj.sample() and returns: samples