Skip to content

Commit

Permalink
replace interal cache with dogpile & created a dogpile backend for dj…
Browse files Browse the repository at this point in the history
…ango cache system :s
  • Loading branch information
nanorepublica committed Nov 2, 2015
1 parent 2dddf52 commit 03c8c70
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 134 deletions.
12 changes: 4 additions & 8 deletions duedil/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from .search.pro import CompanySearchResult as ProCompanySearchResult, DirectorSearchResult
from .search.international import CompanySearchResult as InternationalCompanySearchResult

from .cache import configure_cache, dp_region as cache_region

import os
import json

Expand Down Expand Up @@ -66,9 +68,8 @@ class Client(object):
cache = None
base_url = None

def __init__(self, api_key=None, sandbox=False, cache=None):
def __init__(self, api_key=None, sandbox=False):
'Initialise the Client with which API to connect to and what cache to use'
self.cache = cache
self.set_api(api_key, sandbox)

def set_api(self, api_key=None, sandbox=False):
Expand All @@ -90,6 +91,7 @@ def set_api(self, api_key=None, sandbox=False):
def get(self, endpoint, data=None):
return self._get(endpoint, data)

@cache_region.cache_on_arguments()
@retry(retry_on_exception=retry_throttling, wait_exponential_multiplier=1000, wait_exponential_max=10000)
def _get(self, endpoint, data=None):
'this should become the private interface to all reequests to the api'
Expand All @@ -108,19 +110,13 @@ def _get(self, endpoint, data=None):
endpoint=endpoint,
format=resp_format)

if self.cache:
result = self.cache.get_url(prepared_url, url_params=data)

if not result:
params = data.copy()
params['api_key'] = self.api_key
response = requests.get(prepared_url, params=params)
try:
if not response.raise_for_status():
result = response.json()
if self.cache:
self.cache.set_url(prepared_url, result,
url_params=params)
except HTTPError:
if response.status_code == 404:
result = {}
Expand Down
67 changes: 0 additions & 67 deletions duedil/cache.py

This file was deleted.

57 changes: 57 additions & 0 deletions duedil/cache/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
#
# DuedilApiClient v3 Pro + Credit
# @copyright 2015 Andrew Miller
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#



from dogpile.cache import make_region
import json

# from dogpile.cache.proxy import ProxyBackend
# from requests import Response
# from urlparse import urlsplit
#
# class HttpProxy(ProxyBackend):
# def set(self, key, value):
# # value should be a http response object
# assert isinstance(value, Response)
# value = value.json()
# params = value.url
# self.proxied.set(key, value)


def kwargs_key_generator(namespace, fn, **kw):
fname = fn.__name__
def generate_key(*args, **kwargs):
args_str = "_".join(str(s) for s in args)
kwargs_str = json.dumps(kwargs)
return '{}_{}:{}_{}'.format(namespace, fname, args_str, kwargs_str)
return generate_key

dp_region = make_region(name='duedilv3', function_key_generator = kwargs_key_generator)


def configure_cache(backend='dogpile.cache.pylibmc', expiration_time=86400, **kwargs):
if not kwargs:
kwargs = {
'url': ["127.0.0.1"],
}
return dp_region.configure(
backend,
expiration_time = expiration_time, # 1 day
arguments = kwargs
)
Empty file.
21 changes: 21 additions & 0 deletions duedil/cache/contrib/django.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

from dogpile.cache.api import CacheBackend, NO_VALUE
from dogpile.cache import register_backend
from django.core.cache import get_cache

register_backend("django_cache", "duedilv3.contrib.django", "DjangoCacheBackend")


class DjangoCacheBackend(CacheBackend):
def __init__(self, arguments):
django_cache_name = arguments.pop('cache_name', 'default')
self.cache = get_cache(django_cache_name)

def get(self, key):
return self.cache.get(key, NO_VALUE)

def set(self, key, value):
self.cache.set(key, value, self.timeout)

def delete(self, key):
self.cache.delete(key)
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ def run_tests(self):
# -*- Extra requirements: -*-
'requests>=2,<3',
'six==1.9.0',
'retrying'
'retrying',
'dogpile.cache',
],
tests_require=['pytest', 'requests_mock'],
cmdclass = {'test': PyTest},
Expand Down
58 changes: 29 additions & 29 deletions tests/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,32 @@
# under the License.
#

import unittest

from duedil.cache import Cache


class CacheTestCase(unittest.TestCase):
cache = Cache()

def test_get_cached(self):
url = 'http://duedil.io/v3/uk/companies/06999618'
data = {'name': 'Duedil Limited', 'company_number': '06999618'}

self.cache.set_url(url, data)

self.assertEqual(data, self.cache.get_url(url))

def test_get_uncached(self):
url = 'http://duedil.io/v3/uk/companies/07071234'

self.assertIsNone(self.cache.get_url(url))


def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(CacheTestCase))
return suite

if __name__ == '__main__':
unittest.main()
# import unittest
#
# from duedil.cache import Cache
#
#
# class CacheTestCase(unittest.TestCase):
# cache = Cache()
#
# def test_get_cached(self):
# url = 'http://duedil.io/v3/uk/companies/06999618'
# data = {'name': 'Duedil Limited', 'company_number': '06999618'}
#
# self.cache.set_url(url, data)
#
# self.assertEqual(data, self.cache.get_url(url))
#
# def test_get_uncached(self):
# url = 'http://duedil.io/v3/uk/companies/07071234'
#
# self.assertIsNone(self.cache.get_url(url))
#
#
# def test_suite():
# suite = unittest.TestSuite()
# suite.addTest(unittest.makeSuite(CacheTestCase))
# return suite
#
# if __name__ == '__main__':
# unittest.main()
53 changes: 26 additions & 27 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from requests.exceptions import HTTPError

from duedil.api import LiteClient, ProClient, InternationalClient, Client
from duedil.cache import Cache
from duedil.resources.lite import Company as LiteCompany
from duedil.search.pro import CompanySearchResult as ProCompanySearchResult, DirectorSearchResult
from duedil.search.lite import CompanySearchResult as LiteCompanySearchResult
Expand Down Expand Up @@ -62,32 +61,32 @@ def test_get(self, m):

self.assertEqual(response, {'name': 'Duedil', 'id': '12345'})

@requests_mock.mock()
def test_cached_get(self, m):
cache = Cache()
client = TestClient(API_KEY, cache=cache)
url = 'http://duedil.io/v3/12345.json'
m.register_uri('GET', (url + '?api_key=' + API_KEY),
json={'name': 'Duedil', 'id': '12345'})

client.get('12345')

self.assertEqual(cache.get_url(url),
{'name': 'Duedil', 'id': '12345'})

@requests_mock.mock()
def test_get_with_params(self, m):
cache = Cache()
client = TestClient(API_KEY, cache=cache)
params = {'filters': {'name': 'Duedil Ltd'}}
url = 'http://duedil.io/v3/12345.json'
m.register_uri('GET', url, json={'name': 'Duedil', 'id': '12345'})

client.get('12345', data=params)

cached = cache.get_url('http://duedil.io/v3/12345.json',
url_params=params)
self.assertEqual(cached, {'name': 'Duedil', 'id': '12345'})
# @requests_mock.mock()
# def test_cached_get(self, m):
# cache = Cache()
# client = TestClient(API_KEY, cache=cache)
# url = 'http://duedil.io/v3/12345.json'
# m.register_uri('GET', (url + '?api_key=' + API_KEY),
# json={'name': 'Duedil', 'id': '12345'})
#
# client.get('12345')
#
# self.assertEqual(cache.get_url(url),
# {'name': 'Duedil', 'id': '12345'})
#
# @requests_mock.mock()
# def test_get_with_params(self, m):
# cache = Cache()
# client = TestClient(API_KEY, cache=cache)
# params = {'filters': {'name': 'Duedil Ltd'}}
# url = 'http://duedil.io/v3/12345.json'
# m.register_uri('GET', url, json={'name': 'Duedil', 'id': '12345'})
#
# client.get('12345', data=params)
#
# cached = cache.get_url('http://duedil.io/v3/12345.json',
# url_params=params)
# self.assertEqual(cached, {'name': 'Duedil', 'id': '12345'})

@requests_mock.mock()
def test_404(self, m):
Expand Down
8 changes: 6 additions & 2 deletions tests/test_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@
from duedil.resources import Resource, ProResource, RelatedResourceMixin
from duedil.resources.pro.company import Company
from duedil.resources.lite import Company as LiteCompany
from duedil.cache import configure_cache

API_KEY = '12345'


cache_region = configure_cache('dogpile.cache.null')


class TestResource(Resource):
pass

Expand Down Expand Up @@ -178,7 +182,7 @@ def test_load_related_list(self, m):
class LiteCompanyTestCase(unittest.TestCase):

def test_company_number(self):
company = LiteCompany(api_key=API_KEY, company_number=12345)
company = LiteCompany(api_key=API_KEY, company_number=12345, cache_backend='dogpile.cache.null')
self.assertEqual(company.rid, 12345)

@requests_mock.mock()
Expand All @@ -187,7 +191,7 @@ def test_load_company_number(self, m):
json={'name': 'Duedil',
'company_number': "12345"})

company = LiteCompany(api_key=API_KEY, company_number=12345)
company = LiteCompany(api_key=API_KEY, company_number=12345, cache_backend='dogpile.cache.null')
self.assertEqual(company.name, 'Duedil')


Expand Down

0 comments on commit 03c8c70

Please sign in to comment.