docs: def _request(self, method, endpoint, id=None, **kwargs):
          "Handles retrying failed requests and error handling."
          request = getattr(requests, method, None)
          if not callable(request):
              raise RequestError('Invalid method %s' % method)
          # Find files, separate them out to correct kwarg for requests.
          data = kwargs.get('data')
          if data:
              files = {}
              for name, value in list(data.items()):
                  # Value might be a file-like object (with a read method), or it
                  # might be a (filename, file-like) tuple.
                  if hasattr(value, 'read') or isinstance(value, tuple):
                      files[name] = data.pop(name)
              if files:
                  kwargs.setdefault('files', {}).update(files)
          path = ['api', self.version, endpoint]
          # If we received an ID, append it to the path.
          if id:
              path.append(str(id))
          # Join fragments into a URL
          path = '/'.join(path)
          if not path.endswith('/'):
              path += '/'
          while '//' in path:
              path = path.replace('//', '/')
          url = self.url + path
          # Add our user agent.
          kwargs.setdefault('headers', {}).setdefault('User-Agent',
                                                      HTTP_USER_AGENT)
          # Now try the request, if we get throttled, sleep and try again.
          trys, retrys = 0, 3
          while True:
              if trys == retrys:
                  raise RequestError('Could not complete request after %s trys.'
                                     % trys)
              trys += 1
              try:
                  return self._do_request(request, url, **kwargs)
              except ResponseError as e:
                  if self.throttle_wait and e.status_code == 503:
                      m = THROTTLE_PATTERN.match(
                          e.response.headers.get('x-throttle', ''))
                      if m:
                          time.sleep(float(m.group(1)))
                          continue
                  # Failed for a reason other than throttling.
                  raise