text: from typing import Dict, List, Literal, Optional, Type, Union
  
  from .clients import ScaladeAPIClient, ScaladeDevAPIClient
  from .entities import JobEntity, VariableEntity
  from .exceptions import (
      ContextBlockError,
      ContextCompleteError,
      ContextInitError,
      ContextLogError,
      ContextOutputError,
      InputNotFoundError,
      OutputNotFoundError,
  )
  from .variables import Variable
  
  _TScaladeAPIClient = Union[ScaladeAPIClient, ScaladeDevAPIClient]
  ScaladeAPIClientMap: Dict[
      str, Type[Union[ScaladeAPIClient, ScaladeDevAPIClient]]
  ] = {"dev": ScaladeDevAPIClient, "prod": ScaladeAPIClient}
  
  
  class ContextManager:
      def __init__(
          self,
          job: Optional[JobEntity],
          api_client: _TScaladeAPIClient,
          inputs: Optional[List[VariableEntity]] = None,
          outputs: Optional[List[VariableEntity]] = None,
      ):
          self._job = job
          self.__client = api_client
          self._inputs = inputs
          self._outputs = outputs
  
      @property
      def job(self):
          return self._job
  
      @property
      def inputs(self):
          return self._inputs
  
      @property
      def input_names(self):
          return [var_entity.get("id_name") for var_entity in self._inputs]
  
      @property
      def outputs(self):
          return self._outputs
  
      @property
      def output_names(self):
          return [var_entity.get("id_name") for var_entity in self._outputs]
  
      @classmethod
      async def initialize_from_token(
          cls, token: str, client_type: Literal["dev", "prod"] = "prod"
      ):
          api_client = ScaladeAPIClientMap[client_type](token)
          resp, ok = api_client.retrieve_job_context()
          data = resp.json()
          if ok:
              return cls(
                  job=JobEntity.create_from_dict(data["job"]),
                  api_client=api_client,
                  inputs=VariableEntity.create_multi(data["inputs"]),
                  outputs=VariableEntity.create_multi(data["outputs"]),
              )
          else:
              raise ContextInitError(data)
  
      async def Log(self, message: str):
          resp, ok = self.__client.create_job_log(body={"log_message": message})
          data = resp.json()
          if not ok:
              raise ContextLogError(data)
  
      async def Block(self):
          resp, ok = self.__client.update_job_status(
              body={"status_method": "block"}
          )
          data = resp.json()
          if not ok:
              raise ContextBlockError(data)
          else:
              self._job = JobEntity.create_from_dict(data["job"])
  
      async def Complete(self):
          resp, ok = self.__client.update_job_status(
              body={"status_method": "complete"}
          )
          data = resp.json()
          if not ok:
              raise ContextCompleteError(data)
          else:
              self._job = JobEntity.create_from_dict(data["job"])
  
      async def Output(self, variable: Variable):
          resp, ok = self.__client.create_job_output(
              body={"output": variable.dump()}
          )
          data = resp.json()
          if not ok:
              raise ContextOutputError(data)
          else:
              self._outputs = VariableEntity.create_multi(data["outputs"])
  
      def GetInput(self, id_name: str) -> Variable:
          if self._inputs:
              for ipt in self._inputs:
                  if ipt.get("id_name") == id_name:
                      return ipt.to_var
          raise InputNotFoundError(id_name, self.input_names)
  
      def GetOutput(self, id_name: str) -> Variable:
          if self._outputs:
              for opt in self._outputs:
                  if opt.get("id_name") == id_name:
                      return opt.to_var
          raise OutputNotFoundError(id_name, self.output_names)
  