def METHOD_NAME(self, method, path=None, url=None, skip_quota=False, **kwargs):
    if url is None and \
        (self.__access_token is None or
         self.__expires_at <= datetime.utcnow()):
        self.refresh()
    if url is None and path:
        url = '{}{}'.format(self.BASE_URL, path)
    if 'endpoint' in kwargs:
        endpoint = kwargs['endpoint']
        del kwargs['endpoint']
    else:
        endpoint = None
    if 'headers' not in kwargs:
        kwargs['headers'] = {}
    kwargs['headers']['Authorization'] = 'Bearer {}'.format(
        self.__access_token)
    if self.__user_agent:
        kwargs['headers']['User-Agent'] = self.__user_agent
    with metrics.http_request_timer(endpoint) as timer:
        response = self.__session.METHOD_NAME(method, url, **kwargs)
        timer.tags[metrics.Tag.http_status_code] = response.status_code
    if response.status_code >= 500:
        raise Server5xxError(response.text)
    if response.status_code == 429:
        self.logger.info('Rate limit hit - 429')
        self.sleep_for_reset_period(response)
        raise RateLimitError()
    response.raise_for_status()
    if not skip_quota and self.__quota_limit:
        # quota_limit > (1 - (X-RateLimit-Remaining / X-RateLimit-Limit))
        quota_used = 1 - int(response.headers['x-ratelimit-remaining']) / \
            int(response.headers['x-ratelimit-remaining'])
        if quota_used > float(self.__quota_limit):
            self.logger.info(
                'Quota used: {:.2f} / {}'.format(quota_used, self.__quota_limit))
            self.sleep_for_reset_period(response)
    return response.json()