Skip to content

Commit

Permalink
completely refactored api_call
Browse files Browse the repository at this point in the history
  • Loading branch information
ramusus committed Dec 22, 2014
1 parent c56aeab commit d08727a
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 139 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Django Vkontakte API

### Запрос API

>>> from vkontakte_api.utils import api_call
>>> from vkontakte_api.api import api_call
>>> api_call('resolveScreenName', **{'screen_name': 'durov'})
{u'object_id': 1, u'type': u'user'}
>>> api_call('users.get', **{'user_ids': 'durov'})
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
license='BSD',
packages=find_packages(),
include_package_data=True,
zip_safe=False, # because we're including media that Django needs
zip_safe=False, # because we're including media that Django needs
install_requires=[
'django',
'django-annoying',
'django-picklefield',
'django-oauth-tokens>=0.3.0',
'django-oauth-tokens>=0.4.5',
'vkontakte',
'simplejson',
],
Expand Down
2 changes: 1 addition & 1 deletion vkontakte_api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
VERSION = (0, 6, 6)
VERSION = (0, 7, 0)
__version__ = '.'.join(map(str, VERSION))
64 changes: 64 additions & 0 deletions vkontakte_api/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
import time

from django.conf import settings
from oauth_tokens.api import ApiAbstractBase, Singleton
from oauth_tokens.models import AccessToken
from vkontakte import VKError as VkontakteError, API

__all__ = ['api_call', 'VkontakteError']


class VkontakteApi(ApiAbstractBase):

__metaclass__ = Singleton

provider = 'vkontakte'
error_class = VkontakteError
request_timeout = getattr(settings, 'VKONTAKTE_API_REQUEST_TIMEOUT', 1)

def get_consistent_token(self):
return getattr(settings, 'VKONTAKTE_API_ACCESS_TOKEN', None)

def get_tokens(self, **kwargs):
return AccessToken.objects.filter_active_tokens_of_provider(self.provider, **kwargs)

def get_api(self, **kwargs):
return API(token=self.get_token(**kwargs))

def get_api_response(self, *args, **kwargs):
return self.api.get(self.method, timeout=self.request_timeout, *args, **kwargs)

def handle_error_code_5(self, e, *args, **kwargs):
self.logger.info("Updating vkontakte access token, recursion count: %d" % self.recursion_count)
self.update_tokens()
return self.repeat_call(*args, **kwargs)

def handle_error_code_6(self, e, *args, **kwargs):
# try access_token by another user
self.logger.info(
"Vkontakte error 'Too many requests per second' on method: %s, recursion count: %d" % (self.method, self.recursion_count))
self.used_access_tokens += [self.api.token]
return self.repeat_call(*args, **kwargs)

def handle_error_code_9(self, e, *args, **kwargs):
self.logger.warning("Vkontakte flood control registered while executing method %s with params %s, \
recursion count: %d" % (self.method, kwargs, self.recursion_count))
time.sleep(1)
self.used_access_tokens += [self.api.token]
return self.repeat_call(*args, **kwargs)

def handle_error_code_10(self, e, *args, **kwargs):
self.logger.warning("Internal server error: Database problems, try later. Error registered while executing \
method %s with params %s, recursion count: %d" % (self.method, kwargs, self.recursion_count))
time.sleep(1)
return self.repeat_call(*args, **kwargs)

def handle_error_code_501(self, e, *args, **kwargs):
# strange HTTP error appears sometimes
return self.repeat_call(*args, **kwargs)


def api_call(*args, **kwargs):
api = VkontakteApi()
return api.call(*args, **kwargs)
3 changes: 1 addition & 2 deletions vkontakte_api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
from django.utils import timezone

from . import fields
from .api import api_call, VkontakteError
from .exceptions import VkontakteDeniedAccessError, VkontakteContentError, VkontakteParseError, WrongResponseType
from .signals import vkontakte_api_post_fetch
from .utils import api_call, VkontakteError


log = logging.getLogger('vkontakte_api')

Expand Down
16 changes: 10 additions & 6 deletions vkontakte_api/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from django.test import TestCase
import mock

from .api import api_call, VkontakteError, VkontakteApi
from .decorators import opt_generator
from .models import VkontakteIDModel, VkontaktePKModel, VkontakteManager
from .parser import VkontakteParser
from .utils import api_call, VkontakteError


class User(VkontaktePKModel):
Expand All @@ -30,6 +30,10 @@ class UserID(VkontakteIDModel):

class VkontakteApiTest(TestCase):

def test_api_instance_singleton(self):

self.assertEqual(id(VkontakteApi()), id(VkontakteApi()))

@mock.patch('vkontakte_api.models.api_call', side_effect=lambda *a, **kw: {'items': []})
def test_api_call_versions(self, method):

Expand Down Expand Up @@ -100,11 +104,11 @@ def test_get_by_slug(self):
instance = User.remote.get_by_slug('durov')
self.assertEqual(instance.remote_id, 1)

@mock.patch('time.sleep')
def test_requests_limit_per_sec(self, sleep, *args, **kwargs):
for i in range(0, 30):
api_call('resolveScreenName', screen_name='durov')

# @mock.patch('time.sleep')
# def test_requests_limit_per_sec(self, sleep, *args, **kwargs):
# for i in range(0, 30):
# api_call('resolveScreenName', screen_name='durov')
#
# self.assertTrue(sleep.called)
# self.assertTrue(sleep.call_count >= 1)

Expand Down
127 changes: 0 additions & 127 deletions vkontakte_api/utils.py

This file was deleted.

0 comments on commit d08727a

Please sign in to comment.