text: from .xml2dict import xml2dict
  from .errors import DrsReturnError, DrsParserError
  
  
  class DrsResponse:
      """
      The DrsResponse object deals with the (pretty convoluted) xml response of the Doctorsender API
      """
  
      def __init__(self, res):
          """
          Initialize a DrsResponse object with an API return
          :param res: A requests Response object, containing the response of an Doctorsender API call
          """
          self.xml = res.content
          self._xml2dict()
  
      @property
      def content(self):
          """
          :return: Returns the inner content of the API response (remove all unnecessary stuff around
          """
          if 'Fault' in self.dict['Envelope']['Body']:
              error_code = self.dict['Envelope']['Body']['Fault']['faultcode']
              error_msg = self.dict['Envelope']['Body']['Fault']['faultstring']
              raise DrsReturnError(f"Doctorsender error: {error_code}, error message: {error_msg}")
          return self._drs_reduce_dict()
  
      def _xml2dict(self):
          """
          Sets a dict property that contains the full response converted into a dictionary
          """
          d = xml2dict(self.xml)
          self.dict = self._remove_env_str(d)
  
      def _key_value(self, ele):
          if type(ele) == dict:
              if type(ele['item']) == dict:
                  # One
                  return {ele['item']['key']: ele['item']['value']}
  
              # Case i.e. for dsIpGroupGetNames
              elif type(ele['item']) == str:
                  return ele['item']
  
              # In some cases (e.g. getting all categories, the result is a list of id and name of each object)
              elif type(ele['item']) == list:
                  # Case UserLists
                  if ele['item'][0]['item']['key'] == 'listName':
                      k = ele['item'][0]['item']['value']
                      v = dict()
                      for kv_pair in ele['item']:
                          # The listname is already the key of each user list dict, so we exclude it from the value dict
                          if kv_pair['item']['value'] != k:
                              v.update(self._key_value(kv_pair))
  
                  # Case languages, categories, countries
                  else:
                      k = ele['item'][0]['item']['value']
                      for kv_pair in ele['item']:
                          if kv_pair['item']['key'] in {'name', 'language'}:
                              v = kv_pair['item']['value']
  
                  return {k: v}
              else:
                  raise DrsParserError
  
          elif type(ele) == list:
              res_dict = dict()
              for i, child in enumerate(ele):
                  # Returns an have multiple shapes. dsSettingsGetAllFromEmail e.g. returns
                  try:
                      res_dict.update(self._key_value(child))
                  except (TypeError, ValueError):
                      res_dict.update({i: ele[i]['item']})
              return res_dict
  
          elif type(ele) == str:
              return ele
  
          else:
              print(ele)
              print(type(ele))
  
      def _drs_reduce_dict(self):
          # Remove the first layer
          res_list = self.dict['Envelope']['Body']['{ns1}webserviceResponse']['webserviceReturn']
  
          for i, sub_dict in enumerate(res_list):
  
              # Check for the error value, if there is an error, the error message is in the next dict in the dict-list
              if sub_dict['item']['key'] == 'error':
                  if sub_dict['item']['value'] == 'true':
                      raise DrsReturnError(res_list[i + 1]['item']['value'])
  
              elif sub_dict['item']['key'] == 'msg':
                  res_dict = self._key_value(sub_dict['item']['value'])
  
          return res_dict
  
      def _remove_env_str(self, d):
          for k, v in d.items():
              if type(v) == dict:
                  v = self._remove_env_str(v)
  
              if '{http://schemas.xmlsoap.org/soap/envelope/}' in k:
                  d[k.replace('{http://schemas.xmlsoap.org/soap/envelope/}', '')] = d.pop(k)
  
              return d
  