docs: def open_url(self, url, headers):
          """ open url with python libraries
          """
          
          data = self.cache.get_cached_data(url)
          if data is not None:
              return data, 200, headers
          
          self.rate_limit_ensembl_requests()
          req = request.Request(url, headers=headers)
          
          try:
              handler = request.urlopen(req)
          except HTTPError as error:
              # if we get a http error, we still process the status code, since a
              # later step deals with different status codes differently.
              handler = error
          except (URLError, ConnectionResetError, TimeoutError):
              # if we get a ConnectionResetError, assume something has gone wrong
              # with the server. Later code will wait before retrying.
              return '', 500, headers
          
          status_code = handler.getcode()
          response = handler.read()
          if IS_PYTHON3:
              response = response.decode("utf-8")
          
          # parse the headers into a key, value dictionary
          headers = dict(zip(map(str.lower, handler.headers.keys()), handler.headers.values()))
          
          now = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
          logging.warning("{}\t{}\t{}".format(now, status_code, url))
          
          return response, status_code, headers