Permalink
Browse files

Allow single-object lookups to bypass cached responses.

  • Loading branch information...
1 parent 39379b1 commit 1e59fc7bce1e6497b04d67bf5e807d1c0cdf36e7 @jacobb committed Apr 10, 2014
Showing with 45 additions and 23 deletions.
  1. +1 −2 nap/cache/base.py
  2. +2 −0 nap/cache/django_cache.py
  3. +23 −15 nap/engine.py
  4. +1 −1 setup.py
  5. +3 −2 tests/test_cache.py
  6. +15 −3 tests/test_engine.py
View
@@ -32,11 +32,10 @@ def get_cache_key(self, model, url):
key_parts = {
'resource_name': resource_name,
- 'root_url': root_url,
'url': url,
}
- cache_key = "%(resource_name)s::%(root_url)s::%(url)s" % key_parts
+ cache_key = "%(resource_name)s::%(url)s" % key_parts
return cache_key
@@ -10,8 +10,10 @@
class DjangoCacheBackend(BaseCacheBackend):
def get(self, key):
+ print "get key: ", key
return cache.get(key)
def set(self, key, value, response=None):
+ print "set key: ", key
timeout = self.get_timeout(response)
return cache.set(key, value, timeout)
View
@@ -16,12 +16,8 @@ def __init__(self, model):
def _request(self, request_method, url, *args, **kwargs):
"Construct a NapRequest and send it via a requests.rest call"
- try:
- root_url = self.model._meta['root_url']
- except KeyError:
- raise ValueError("Nap requests require root_url to be defined")
+ full_url = self.get_full_url(url)
- full_url = "%s%s" % (root_url, url)
self.logger.info("Trying to hit %s" % full_url)
request_args = self.get_request_args(kwargs)
@@ -38,8 +34,6 @@ def _request(self, request_method, url, *args, **kwargs):
headers=resource_response.headers,
content=resource_response.content,
request_method=request_method,
-
-
)
for mw in reversed(self.model._meta['middleware']):
@@ -144,7 +138,7 @@ def get_delete_url(self, resource_obj=None, **kwargs):
return self._generate_url(url_type='update', resource_obj=resource_obj, **kwargs)
# access methods
- def get(self, uri=None, **kwargs):
+ def get(self, uri=None, skip_cache=False, **kwargs):
"""Issues a get request to the API. If ``uri`` is passed, will send a
request directly to that URL. otherwise, attempt a lookup request.
@@ -154,25 +148,29 @@ def get(self, uri=None, **kwargs):
"""
if uri:
- return self.get_from_uri(uri)
+ return self.get_from_uri(uri, skip_cache=skip_cache)
- return self.lookup(**kwargs)
+ return self.lookup(skip_cache=skip_cache, **kwargs)
- def lookup(self, **lookup_vars):
+ def lookup(self, skip_cache=False, **lookup_vars):
"""Creates a get request to the API to the first URL found based on
``lookup_vars``
:param lookup_vars: variables to send to get_lookup_url
"""
uri = self.get_lookup_url(**lookup_vars)
- return self.get_from_uri(uri)
+ return self.get_from_uri(uri, skip_cache=skip_cache)
- def get_from_uri(self, url, *args, **kwargs):
+ def get_from_uri(self, url, skip_cache=False, *args, **kwargs):
"""instance method to perform all non-collection get requests
"""
cleaned_url = handle_slash(url, self.model._meta['add_slash'])
- cached_response = self.get_from_cache('GET', cleaned_url)
+
+ if skip_cache:
+ cached_response = None
+ else:
+ cached_response = self.get_from_cache('GET', cleaned_url)
if cached_response:
response = cached_response
@@ -448,9 +446,10 @@ def get_from_cache(self, request_method, url):
if request_method not in self.model._meta['cached_methods']:
return
+ full_url = self.get_full_url(url)
cache_key = self.cache.get_cache_key(
model=self.model,
- url=url,
+ url=full_url,
)
self.logger.debug("Trying to get cached response for %s" % cache_key)
cached_response = self.cache.get(cache_key)
@@ -507,3 +506,12 @@ def modify_request(self, **kwargs):
@property
def cache(self):
return self.model._meta['cache_backend']
+
+ def get_full_url(self, uri):
+ try:
+ root_url = self.model._meta['root_url']
+ except KeyError:
+ raise ValueError("Nap requests require root_url to be defined")
+
+ full_url = "%s%s" % (root_url, uri)
+ return full_url
View
@@ -6,7 +6,7 @@
test_requirements = ['mock', ]
setup(
name='nap',
- version="0.4",
+ version="0.4.1",
description=('api access modeling and tools'),
author="Jacob Burch",
author_email="jacobburch@gmail.com",
View
@@ -51,8 +51,9 @@ def test_get_cache_key(self):
cache_backend = self.get_backend()
uri = SampleResourceModel.objects.get_lookup_url(resource_obj=obj)
- key = cache_backend.get_cache_key(SampleResourceModel, uri)
- assert key == 'note::http://foo.com/v1/::expected_title/'
+ url = SampleResourceModel.objects.get_full_url(uri)
+ key = cache_backend.get_cache_key(SampleResourceModel, url)
+ assert key == "note::http://foo.com/v1/expected_title/"
def test_get_timeout_from_header(self):
View
@@ -79,7 +79,7 @@ def test_create_url(self):
class TestResourceEngineAccessMethods(BaseResourceModelTest):
- def test_get_from_uri(self):
+ def test_get_from_uri(self, skip_cache=False):
engine = self.get_engine()
fake_dict = {
@@ -96,13 +96,25 @@ def test_get_from_uri(self):
stubbed_response.status_code = 200
get.return_value = stubbed_response
- obj = engine.get_from_uri('xyz')
+ obj = engine.get_from_uri('xyz', skip_cache=skip_cache)
assert obj.title == fake_dict['title']
assert obj.content == fake_dict['content']
assert obj._root_url == model_root_url
assert obj._full_url == expected_url
+ @mock.patch('nap.engine.ResourceEngine.get_from_cache')
+ def test_get_from_uri_skip_cache(self, *mocks):
+
+ get_from_cache = mocks[0]
+ get_from_cache.return_value = None
+
+ self.test_get_from_uri(True)
+ assert not get_from_cache.called
+
+ self.test_get_from_uri()
+ assert get_from_cache.called
+
def test_request_no_root_url(self):
engine = self.get_engine()
root_url = engine.model._meta['root_url']
@@ -128,7 +140,7 @@ def test_lookup(self):
engine = self.get_engine()
with mock.patch('nap.engine.ResourceEngine.get_from_uri') as get:
engine.lookup(hello='hello_test', what='what_test')
- get.assert_called_with('hello_test/what_test/')
+ get.assert_called_with('hello_test/what_test/', skip_cache=False)
SampleResourceModel._lookup_urls = []

0 comments on commit 1e59fc7

Please sign in to comment.