code: def create_from_env(cls, env: Env, **kwargs):
      obs_space = env.observation_space
      assert isinstance(obs_space, spaces.Dict)
      user_obs_space = obs_space["user"]
      if not isinstance(user_obs_space, spaces.Box):
          raise NotImplementedError(
              f"User observation space {type(user_obs_space)} is not supported"
          )
  
      doc_obs_space = obs_space["doc"]
      if not isinstance(doc_obs_space, spaces.Dict):
          raise NotImplementedError(
              f"Doc space {type(doc_obs_space)} is not supported"
          )
  
      # Assume that all docs are in the same space
  
      discrete_keys: List[Tuple[str, int]] = []
      box_keys: List[Tuple[str, int]] = []
  
      key_0 = next(iter(doc_obs_space.spaces))
      doc_0_space = doc_obs_space[key_0]
  
      if isinstance(doc_0_space, spaces.Dict):
          for k, v in doc_obs_space[key_0].spaces.items():
              if isinstance(v, spaces.Discrete):
                  if v.n > 0:
                      discrete_keys.append((k, v.n))
              elif isinstance(v, spaces.Box):
                  shape_dim = len(v.shape)
                  if shape_dim == 0:
                      box_keys.append((k, 1))
                  elif shape_dim == 1:
                      box_keys.append((k, v.shape[0]))
                  else:
                      raise NotImplementedError
              else:
                  raise NotImplementedError(
                      f"Doc feature {k} with the observation space of {type(v)}"
                      " is not supported"
                  )
      elif isinstance(doc_0_space, spaces.Box):
          pass
      else:
          raise NotImplementedError(f"Unknown space {doc_0_space}")
  
      return cls(
          num_docs=len(doc_obs_space.spaces),
          discrete_keys=sorted(discrete_keys),
          box_keys=sorted(box_keys),
          **kwargs,
      )
  
file_path: ReAgent/reagent/gym/preprocessors/default_preprocessors.py
imports: import logging
  from typing import List, Tuple
  import numpy
  import reagent.core.types
  import torch
  import torch.nn.functional
  from gym import Env, spaces
label_desc: Use image node_id 2 for calling the RecsimObsPreprocessor obj's underlying member method code with example usage: obj.create_from_env(cls, env) and returns: cls