Example #1
0
    def __init__(self, access_token=None):

        # logger.debug('API.__init__(access_token=%(access_token)r)', {'access_token': access_token})

        self.access_token = access_token
        self.access_token_is_needed = False

        self.requests_session = LoggingSession()
        self.requests_session.headers['Accept'] = 'application/json'
        self.requests_session.headers['Content-Type'] = 'application/x-www-form-urlencoded'
Example #2
0
File: api.py Project: chibisov/vk
    def __init__(self, access_token=None):

        logger.debug('API.__init__(access_token=%(access_token)r)', {'access_token': access_token})

        self.access_token = access_token
        self.access_token_is_needed = False

        self.requests_session = LoggingSession()
        self.requests_session.headers['Accept'] = 'application/json'
        self.requests_session.headers['Content-Type'] = 'application/x-www-form-urlencoded'
Example #3
0
File: api.py Project: itJunky/vk
    def __init__(self, access_token=None):

        logger.debug("API.__init__(access_token=%(access_token)r)", {"access_token": access_token})

        # self.api_version = api_version
        # self.default_timeout = default_timeout
        self.access_token = access_token
        self.access_token_is_needed = False

        # self.requests_session = requests.Session()
        self.requests_session = LoggingSession()
        self.requests_session.headers["Accept"] = "application/json"
        self.requests_session.headers["Content-Type"] = "application/x-www-form-urlencoded"
Example #4
0
    def get_access_token(self):
        """
        Get access token using app id and user login and password.
        """
        logger.debug('AuthMixin.get_access_token()')

        with LoggingSession() as auth_session:
            self.auth_session = auth_session
            self.login()
            auth_response_url_query = self.oauth2_authorization()

        if 'access_token' in auth_response_url_query:
            return auth_response_url_query['access_token']
        else:
            raise VKAuthError('OAuth2 authorization error')
Example #5
0
class Session(object):
    API_URL = 'https://api.vk.com/method/'

    def __init__(self, access_token=None):

        # logger.debug('API.__init__(access_token=%(access_token)r)', {'access_token': access_token})

        self.access_token = access_token
        self.access_token_is_needed = False

        self.requests_session = LoggingSession()
        self.requests_session.headers['Accept'] = 'application/json'
        self.requests_session.headers['Content-Type'] = 'application/x-www-form-urlencoded'

    @property
    def access_token(self):
        # logger.debug('Check that we need new access token')
        if self.access_token_is_needed:
            # logger.debug('We need new access token. Try to get it.')
            self.access_token = self.get_access_token()
        # else:
            # logger.debug('Use old access token')
        return self._access_token

    @access_token.setter
    def access_token(self, value):
        self._access_token = value
        if isinstance(value, str_type) and len(value) >= 12:
            self.censored_access_token = '{}***{}'.format(value[:4], value[-4:])
        else:
            self.censored_access_token = value
        # logger.debug('access_token = %r', self.censored_access_token)
        self.access_token_is_needed = not self._access_token

    def get_user_login(self):
        pass  # logger.debug('Do nothing to get user login')

    def get_access_token(self):
        """
        Dummy method
        """
        # logger.debug('API.get_access_token()')
        return self._access_token

    def make_request(self, method_request, captcha_response=None):

        # logger.debug('Prepare API Method request')

        response = self.send_api_request(method_request, captcha_response=captcha_response)
        # todo Replace with something less exceptional
        response.raise_for_status()

        # there are may be 2 dicts in one JSON
        # for example: "{'error': ...}{'response': ...}"
        for response_or_error in json_iter_parse(response.text):
            if 'response' in response_or_error:
                # todo Can we have error and response simultaneously
                # for error in errors:
                #     logger.warning(str(error))

                return response_or_error['response']

            elif 'error' in response_or_error:
                error_data = response_or_error['error']
                error = VkAPIError(error_data)

                if error.is_captcha_needed():
                    captcha_key = self.get_captcha_key(error.captcha_img)
                    if not captcha_key:
                        raise error

                    captcha_response = {
                        'sid': error.captcha_sid,
                        'key': captcha_key,
                    }
                    return self.make_request(method_request, captcha_response=captcha_response)

                elif error.is_access_token_incorrect():
                    # logger.info('Authorization failed. Access token will be dropped')
                    self.access_token = None
                    return self.make_request(method_request)

                else:
                    raise error

    def send_api_request(self, request, captcha_response=None):
        url = self.API_URL + request._method_name
        method_args = request._api._method_default_args.copy()
        method_args.update(stringify_values(request._method_args))
        access_token = self.access_token
        if access_token:
            method_args['access_token'] = access_token
        if captcha_response:
            method_args['captcha_sid'] = captcha_response['sid']
            method_args['captcha_key'] = captcha_response['key']
        timeout = request._api._timeout
        response = self.requests_session.post(url, method_args, timeout=timeout)
        return response

    def get_captcha_key(self, captcha_image_url):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """
        return None
    
    def auth_code_is_needed(self, content, session):
        """
        Default behavior on 2-AUTH CODE is to raise exception
        Reload this in child
        """           
        raise VkAuthError('Authorization error (2-factor code is needed)')
    
    def auth_captcha_is_needed(self, content, session):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """              
        raise VkAuthError('Authorization error (captcha)')
    
    def phone_number_is_needed(self, content, session):
        """
        Default behavior on PHONE NUMBER is to raise exception
        Reload this in child
        """
        # logger.error('Authorization error (phone number is needed)')
        raise VkAuthError('Authorization error (phone number is needed)')
Example #6
0
File: api.py Project: chibisov/vk
class Session(object):
    API_URL = 'https://api.vk.com/method/'

    def __init__(self, access_token=None):

        logger.debug('API.__init__(access_token=%(access_token)r)', {'access_token': access_token})

        self.access_token = access_token
        self.access_token_is_needed = False

        self.requests_session = LoggingSession()
        self.requests_session.headers['Accept'] = 'application/json'
        self.requests_session.headers['Content-Type'] = 'application/x-www-form-urlencoded'

    @property
    def access_token(self):
        logger.debug('Check that we need new access token')
        if self.access_token_is_needed:
            logger.debug('We need new access token. Try to get it.')
            self.access_token = self.get_access_token()
        else:
            logger.debug('Use old access token')
        return self._access_token

    @access_token.setter
    def access_token(self, value):
        self._access_token = value
        if isinstance(value, str_type) and len(value) >= 12:
            self.censored_access_token = '{}***{}'.format(value[:4], value[-4:])
        else:
            self.censored_access_token = value
        logger.debug('access_token = %r', self.censored_access_token)
        self.access_token_is_needed = not self._access_token

    def get_user_login(self):
        logger.debug('Do nothing to get user login')

    def get_access_token(self):
        """
        Dummy method
        """
        logger.debug('API.get_access_token()')
        return self._access_token

    def make_request(self, method_request, captcha_response=None):

        logger.debug('Prepare API Method request')

        response = self.send_api_request(method_request)
        # todo Replace with something less exceptional
        response.raise_for_status()

        # there are may be 2 dicts in one JSON
        # for example: "{'error': ...}{'response': ...}"
        for response_or_error in json_iter_parse(response.text):
            if 'response' in response_or_error:
                # todo Can we have error and response simultaneously
                # for error in errors:
                #     logger.warning(str(error))

                return response_or_error['response']

            elif 'error' in response_or_error:
                error_data = response_or_error['error']
                error = VkAPIError(error_data)

                if error.is_captcha_needed():
                    captcha_key = self.get_captcha_key(error.captcha_img)
                    if not captcha_key:
                        raise error

                    captcha_response = {
                        'sid': error.captcha_sid,
                        'key': captcha_key,
                    }
                    return self.make_request(method_request, captcha_response=captcha_response)

                elif error.is_access_token_incorrect():
                    logger.info('Authorization failed. Access token will be dropped')
                    self.access_token = None
                    return self.make_request(method_request)

                else:
                    raise error

    def send_api_request(self, request, captcha_response=None):
        url = self.API_URL + request._method_name
        method_args = request._api._method_default_args.copy()
        method_args.update(stringify_values(request._method_args))
        access_token = self.access_token
        if access_token:
            method_args['access_token'] = access_token
        if captcha_response:
            method_args['captcha_sid'] = captcha_response['sid']
            method_args['captcha_key'] = captcha_response['key']
        timeout = request._api._timeout
        response = self.requests_session.post(url, method_args, timeout=timeout)
        return response

    def get_captcha_key(self, captcha_image_url):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """
        return None
    
    def auth_code_is_needed(self, content, session):
        """
        Default behavior on 2-AUTH CODE is to raise exception
        Reload this in child
        """           
        raise VkAuthError('Authorization error (2-factor code is needed)')
    
    def auth_captcha_is_needed(self, content, session):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """              
        raise VkAuthError('Authorization error (captcha)')
    
    def phone_number_is_needed(self, content, session):
        """
        Default behavior on PHONE NUMBER is to raise exception
        Reload this in child
        """
        logger.error('Authorization error (phone number is needed)')
        raise VkAuthError('Authorization error (phone number is needed)')
Example #7
0
class Session(object):
    API_URL = 'https://api.vk.com/method/'

    def __init__(self, access_token=None):

        logger.debug('API.__init__(access_token=%(access_token)r)',
                     {'access_token': access_token})

        # self.api_version = api_version
        # self.default_timeout = default_timeout
        self.access_token = access_token
        self.access_token_is_needed = False

        # self.requests_session = requests.Session()
        self.requests_session = LoggingSession()
        self.requests_session.headers['Accept'] = 'application/json'
        self.requests_session.headers[
            'Content-Type'] = 'application/x-www-form-urlencoded'

    @property
    def access_token(self):
        logger.debug('Check that we need new access token')
        if self.access_token_is_needed:
            logger.debug('We need new access token. Try to get it.')
            self.access_token, self._access_token_expires_in = self.get_access_token(
            )
            logger.info('Got new access token')
        logger.debug('access_token = %r, expires in %s',
                     self.censored_access_token, self._access_token_expires_in)
        return self._access_token

    @access_token.setter
    def access_token(self, value):
        self._access_token = value
        self._access_token_expires_in = None
        self.access_token_is_needed = not self._access_token

    @property
    def censored_access_token(self):
        if self._access_token:
            return '{}***{}'.format(self._access_token[:4],
                                    self._access_token[-4:])

    def get_user_login(self):
        logger.debug('Do nothing to get user login')

    def get_access_token(self):
        """
        Dummy method
        """
        logger.debug('API.get_access_token()')
        return self._access_token, self._access_token_expires_in

    def make_request(self, method_request, **method_kwargs):

        logger.debug('Prepare API Method request')

        response = self.send_api_request(method_request)
        response.raise_for_status()

        # there are may be 2 dicts in one JSON
        # for example: {'error': ...}{'response': ...}
        errors = []
        error_codes = []
        for data in json_iter_parse(response.text):
            if 'error' in data:
                error_data = data['error']
                if error_data['error_code'] == CAPTCHA_IS_NEEDED:
                    return self.on_captcha_is_needed(error_data,
                                                     method_request)

                error_codes.append(error_data['error_code'])
                errors.append(error_data)

            if 'response' in data:
                for error in errors:
                    logger.warning(str(error))

                return data['response']

        if AUTHORIZATION_FAILED in error_codes:  # invalid access token
            logger.info('Authorization failed. Access token will be dropped')
            self.access_token = None
            return self.make_request(method_request)
        else:
            raise VkAPIMethodError(errors[0])

    def send_api_request(self, request):
        url = self.API_URL + request._method_name
        method_args = request._api._method_default_args.copy()
        method_args.update(stringify_values(request._method_args))
        if self.access_token:
            method_args['access_token'] = self.access_token
        timeout = request._api._timeout
        response = self.requests_session.post(url,
                                              method_args,
                                              timeout=timeout)
        return response

    def on_captcha_is_needed(self, error_data, method_request):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """
        raise VkAPIMethodError(error_data)

    def auth_code_is_needed(self, content, session):
        """
        Default behavior on 2-AUTH CODE is to raise exception
        Reload this in child
        """
        raise VkAuthError('Authorization error (2-factor code is needed)')

    def auth_captcha_is_needed(self, content, session):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """
        raise VkAuthError('Authorization error (captcha)')

    def phone_number_is_needed(self, content, session):
        """
        Default behavior on PHONE NUMBER is to raise exception
        Reload this in child
        """
        logger.error('Authorization error (phone number is needed)')
        raise VkAuthError('Authorization error (phone number is needed)')
Example #8
0
File: api.py Project: itJunky/vk
class Session(object):
    API_URL = "https://api.vk.com/method/"

    def __init__(self, access_token=None):

        logger.debug("API.__init__(access_token=%(access_token)r)", {"access_token": access_token})

        # self.api_version = api_version
        # self.default_timeout = default_timeout
        self.access_token = access_token
        self.access_token_is_needed = False

        # self.requests_session = requests.Session()
        self.requests_session = LoggingSession()
        self.requests_session.headers["Accept"] = "application/json"
        self.requests_session.headers["Content-Type"] = "application/x-www-form-urlencoded"

    @property
    def access_token(self):
        logger.debug("Check that we need new access token")
        if self.access_token_is_needed:
            logger.debug("We need new access token. Try to get it.")
            self.access_token, self._access_token_expires_in = self.get_access_token()
            logger.info("Got new access token")
        logger.debug("access_token = %r, expires in %s", self.censored_access_token, self._access_token_expires_in)
        return self._access_token

    @access_token.setter
    def access_token(self, value):
        self._access_token = value
        self._access_token_expires_in = None
        self.access_token_is_needed = not self._access_token

    @property
    def censored_access_token(self):
        if self._access_token:
            return "{}***{}".format(self._access_token[:4], self._access_token[-4:])

    def get_user_login(self):
        logger.debug("Do nothing to get user login")

    def get_access_token(self):
        """
        Dummy method
        """
        logger.debug("API.get_access_token()")
        return self._access_token, self._access_token_expires_in

    def make_request(self, method_request, **method_kwargs):

        logger.debug("Prepare API Method request")

        response = self.send_api_request(method_request)
        response.raise_for_status()

        # there are may be 2 dicts in one JSON
        # for example: {'error': ...}{'response': ...}
        errors = []
        error_codes = []
        for data in json_iter_parse(response.text):
            if "error" in data:
                error_data = data["error"]
                if error_data["error_code"] == CAPTCHA_IS_NEEDED:
                    return self.on_captcha_is_needed(error_data, method_request)

                error_codes.append(error_data["error_code"])
                errors.append(error_data)

            if "response" in data:
                for error in errors:
                    logger.warning(str(error))

                return data["response"]

        if AUTHORIZATION_FAILED in error_codes:  # invalid access token
            logger.info("Authorization failed. Access token will be dropped")
            self.access_token = None
            return self.make_request(method_request)
        else:
            raise VkAPIMethodError(errors[0])

    def send_api_request(self, request):
        url = self.API_URL + request._method_name
        method_args = request._api._method_default_args.copy()
        method_args.update(stringify_values(request._method_args))
        if self.access_token:
            method_args["access_token"] = self.access_token
        timeout = request._api._timeout
        response = self.requests_session.post(url, method_args, timeout=timeout)
        return response

    def on_captcha_is_needed(self, error_data, method_request):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """
        raise VkAPIMethodError(error_data)

    def auth_code_is_needed(self, content, session):
        """
        Default behavior on 2-AUTH CODE is to raise exception
        Reload this in child
        """
        raise VkAuthError("Authorization error (2-factor code is needed)")

    def auth_captcha_is_needed(self, content, session):
        """
        Default behavior on CAPTCHA is to raise exception
        Reload this in child
        """
        raise VkAuthError("Authorization error (captcha)")

    def phone_number_is_needed(self, content, session):
        """
        Default behavior on PHONE NUMBER is to raise exception
        Reload this in child
        """
        logger.error("Authorization error (phone number is needed)")
        raise VkAuthError("Authorization error (phone number is needed)")