<commit_before># -*- coding: utf-8 -*-
"""
    pyvk.request
    ~~~~~~~~~~~~

    Implements VK API request object ready to be sent.

    :copyright: (c) 2013-2016, <NAME>
    :license: MIT, see LICENSE for more details.
"""

from __future__ import generators, with_statement, print_function, \
    unicode_literals, absolute_import

import requests
import logging
from time import sleep

from .utils import PY2
from .exceptions import ReqError, APIError, AuthError

if PY2:
    from urllib import urlencode
else:
    from urllib.parse import urlencode

logger = logging.getLogger(__name__)


class RequestHandler(object):
    def __init__(self, prefix, auth, config):
        self._prefix = prefix
        self._auth = auth
        self._config = config

    @property
    def method(self):
        return '.'.join(self._prefix)

    def __getattr__(self, suffix):
        return RequestHandler(self._prefix + [suffix], self._auth, self._config)

    def __call__(self, **args):
        return Request(self.method, args, self._auth, self._config).send()

    def __repr__(self):
        return '<RequestHandler | prefix=%s>' % repr(self.method)


class Request(object):
    def __init__(self, method, args, auth, config):
        self._method = method
        self._auth = auth
        self._config = config
        # Transform lists into comma-separated strings
        self._args = {k: ','.join(str(i) for i in v) if type(v) is list else v
                      for k, v in args.items()}

    def _fetch(self):

        args = self._args.copy()
        args['access_token'] = self._auth.token
        args['v'] = args.get('v', self._config.version)
        if self._config.lang:
            args['lang'] = self._config.lang

        url = 'https://api.vk.com/method/%s?%s' \
              % (self._method, urlencode(args))

        # 1. Send HTTP request
        response = requests.get(url, timeout=self._config.timeout)

        # 2. Unpack it
        try:
            data = response.json()

        except ValueError as e:
            raise ReqError('Response is not a valid JSON',
                           response=response, exc=e)
        assert isinstance(data, dict)

        # 3. Try to return the result
        try:
            return data if self._config.raw_response else data['response']
        except KeyError:
            # 'response' does not exist
            pass

        # 4. Handle possible API error response
        try:
            err = data['error']
            raise APIError('VK API returned an error', code=err['error_code'],
                           msg=err['error_msg'], error=err, response=response)

        except KeyError as e:
            raise ReqError('Error response from API is malformed',
                           response=response, data=data, exc=e)

    def send(self):

        for attempt in range(self._config.max_attempts):
            try:
                return self._fetch()

            except APIError as e:
                # User authorisation failed, try to reauthorise.
                if (e.code == 5 or e.code == 10) and self._config.auto_reauth:

                    logger.info('It seems that current token is unavailable '
                                'now. Trying to renew...')
                    try:
                        self._auth.auth()

                    except AuthError as e:
                        raise ReqError('Could not renew token',
                                       exc=e, attempt=attempt)

                    else:
                        assert self._auth.token
                        self._args['access_token'] = self._auth.token

                        logger.info('Access token succesfully renewed, '
                                    'repeating the request...')

                # Requests are too ofter.
                elif e.code in (6, 9) and self._config.slow_down:
                    t = 0.3 * (attempt + 1)
                    logger.info('Too many requests per second. '
                                'Wait %.1f sec and retry.' % t)
                    sleep(t)

                # Captcha needed.
                elif e.code == 14 and self._config.validation:
                    logger.debug('Captcha needed')
                    try:
                        self._args['captcha_sid'] = e.error['captcha_sid']
                        img = e.error['captcha_img']

                    except KeyError:
                        raise ReqError('Captcha is required, server response'
                                       'is malformed', exc=e)

                    else:
                        key = self._config.prompt.ask_captcha(img)
                        self._args['captcha_key'] = key

                # Validation needed.
                elif e.code == 17 and self._config.validation:
                    url = e.error['redirect_uri']
                    logger.debug('Validation needed: %s' % url)
                    response = requests.get(url, timeout=self._config.timeout)
                    self._auth.auth('router', response)
                    logger.debug('Continue...')

                # Cannot handle error, raise it as is.
                else:
                    raise

        raise ReqError('Request failed after all attempts.')<commit_msg>pyvk.request: Support new Prompt API<commit_after># -*- coding: utf-8 -*-
"""
    pyvk.request
    ~~~~~~~~~~~~

    Implements VK API request object ready to be sent.

    :copyright: (c) 2013-2016, <NAME>
    :license: MIT, see LICENSE for more details.
"""

from __future__ import generators, with_statement, print_function, \
    unicode_literals, absolute_import

import requests
import logging
from time import sleep

from .utils import PY2
from .exceptions import ReqError, APIError, AuthError

if PY2:
    from urllib import urlencode
else:
    from urllib.parse import urlencode

logger = logging.getLogger(__name__)


class RequestHandler(object):
    def __init__(self, prefix, auth, config):
        self._prefix = prefix
        self._auth = auth
        self._config = config

    @property
    def method(self):
        return '.'.join(self._prefix)

    def __getattr__(self, suffix):
        return RequestHandler(self._prefix + [suffix], self._auth, self._config)

    def __call__(self, **args):
        return Request(self.method, args, self._auth, self._config).send()

    def __repr__(self):
        return '<RequestHandler | prefix=%s>' % repr(self.method)


class Request(object):
    def __init__(self, method, args, auth, config):
        self._method = method
        self._auth = auth
        self._config = config
        # Transform lists into comma-separated strings
        self._args = {k: ','.join(str(i) for i in v) if type(v) is list else v
                      for k, v in args.items()}

    def _fetch(self):

        args = self._args.copy()
        args['access_token'] = self._auth.token
        args['v'] = args.get('v', self._config.version)
        if self._config.lang:
            args['lang'] = self._config.lang

        url = 'https://api.vk.com/method/%s?%s' \
              % (self._method, urlencode(args))

        # 1. Send HTTP request
        response = requests.get(url, timeout=self._config.timeout)

        # 2. Unpack it
        try:
            data = response.json()

        except ValueError as e:
            raise ReqError('Response is not a valid JSON',
                           response=response, exc=e)
        assert isinstance(data, dict)

        # 3. Try to return the result
        try:
            return data if self._config.raw_response else data['response']
        except KeyError:
            # 'response' does not exist
            pass

        # 4. Handle possible API error response
        try:
            err = data['error']
            raise APIError('VK API returned an error', code=err['error_code'],
                           msg=err['error_msg'], error=err, response=response)

        except KeyError as e:
            raise ReqError('Error response from API is malformed',
                           response=response, data=data, exc=e)

    def send(self):

        for attempt in range(self._config.max_attempts):
            try:
                return self._fetch()

            except APIError as e:
                # User authorisation failed, try to reauthorise.
                if (e.code == 5 or e.code == 10) and self._config.auto_reauth:

                    logger.info('It seems that current token is unavailable '
                                'now. Trying to renew...')
                    try:
                        self._auth.auth()

                    except AuthError as e:
                        raise ReqError('Could not renew token',
                                       exc=e, attempt=attempt)

                    else:
                        assert self._auth.token
                        self._args['access_token'] = self._auth.token

                        logger.info('Access token succesfully renewed, '
                                    'repeating the request...')

                # Requests are too ofter.
                elif e.code in (6, 9) and self._config.slow_down:
                    t = 0.3 * (attempt + 1)
                    logger.info('Too many requests per second. '
                                'Wait %.1f sec and retry.' % t)
                    sleep(t)

                # Captcha needed.
                elif e.code == 14 and self._config.validation:
                    logger.debug('Captcha needed')
                    try:
                        self._args['captcha_sid'] = e.error['captcha_sid']
                        img = e.error['captcha_img']

                    except KeyError:
                        raise ReqError('Captcha is required, server response'
                                       'is malformed', exc=e)

                    else:
                        key = self._config.prompt.ask('captcha', img=img)
                        self._args['captcha_key'] = key

                # Validation needed.
                elif e.code == 17 and self._config.validation:
                    url = e.error['redirect_uri']
                    logger.debug('Validation needed: %s' % url)
                    response = requests.get(url, timeout=self._config.timeout)
                    self._auth.auth('router', response)
                    logger.debug('Continue...')

                # Cannot handle error, raise it as is.
                else:
                    raise

        raise ReqError('Request failed after all attempts.')
{'fraction_non_alphanumeric': 0.09839773798303487, 'fraction_numerical': 0.00527803958529689, 'mean_word_length': 1.5079177499409122, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7008998', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2634, 'n_words': 792}