text: from types import SimpleNamespace
  import re
  import json
  from multidict import CIMultiDictProxy
  
  class Collection(SimpleNamespace):
  
      def __init__(self, **kwargs) -> None:
          clean_kwargs = {Collection.clean(key): value for key, value in kwargs.items()}
          SimpleNamespace.__init__(self, **clean_kwargs)
  
      @staticmethod
      def clean(string: str) -> str:
          string = re.sub(
              '[^0-9a-zA-Z_]', '', 
              re.sub('^[^a-zA-Z_]+', '', string)
          )
          return string
    
  class BaseType(object):
  
      def __init__(self) -> None:
          pass
  
      _exclude_from_str = ["json", "text"]
      def __str__(self) -> str:
          items = (
              f"{k}={v!r}" for k, v in self.__dict__\
                  .items() if k not in self.__class__._exclude_from_str)
          return "{}({})".format(type(self).__name__, ", ".join(items))
  
      def __repr__(self) -> str:
          items = (f"{k}={v!r}" for k, v in self.__dict__.items())
          return "{}({})".format(type(self).__name__, ", ".join(items))
  
  class Resource(object):
  
      _base_url = "https://api.chess.com/pub"
      
      def __init__(self, uri, top_level_attr = None, no_json = False, **kwargs):
          self.url = Resource._base_url + uri
          self.top_level_attr = top_level_attr
          self.no_json = no_json
          self.request_extras = {**kwargs}
  
  class ChessDotComResponse(BaseType):
      """
      Custom object for holding the API's response.
  
      :ivar json: Dictionary representation of the API's response.
      :ivar {nested_object}: Object representation of the API's response.
      :ivar text: API's raw response decoded into a string.
      """
  
      def __init__(self, response_text: str, top_level_attr: str = None, no_json = False) -> None:
          self._parse_response(response_text, top_level_attr, no_json)
          self.text = response_text
  
      def _parse_response(self, response_text: str, top_level_attr: str, no_json) -> None: 
          if no_json:
              response_text = json.dumps({top_level_attr: response_text})
          try:
              self._create_json_attr(response_text, top_level_attr)
              self._create_object_attrs(response_text, top_level_attr)
          except Exception as err:
              raise ChessDotComError(
                  status_code = 200,
                  response_text = json.dumps({
                      "message": "The server did not return a json response",
                  })
              ) from err
              
      def _create_json_attr(self, response_text: str, top_level_attr: str) -> None:
          dict_ = json.loads(response_text)
          if top_level_attr:
              dict_ = {top_level_attr: dict_}
          self.json = dict_
  
      def _create_object_attrs(self, response_text: str, top_level_attr: str) -> None:
          attrs = json.loads(response_text, object_hook=lambda d: Collection(**d))
          if top_level_attr:
              setattr(self, top_level_attr, Collection(**attrs.__dict__))
          else:
              self.__dict__.update(**attrs.__dict__)
      
  class ChessDotComError(Exception):
      """
      Custom Exception object.
  
      :ivar status_code: Contains the status code of the API's response.
      :ivar json: Dictionary representation of the API's response.
      :ivar text: API's raw response decoded into a string.
      """
  
      def __init__(self, status_code: int, response_text: str, headers: CIMultiDictProxy) -> None:
          super().__init__()
          self._create_json_attr(response_text)
          self.status_code = status_code
          self.text = response_text
          self.header = headers
  
      def __str__(self):
          return f'{type(self)}(status_code={self.status_code}, text={self.text})'
  
      def _create_json_attr(self, response_text: str) -> None:
          try: self.json = json.loads(response_text)
          except: self.json = {}
  