diff options
author | Jordan Cook <jordan.cook@pioneer.com> | 2021-04-23 19:09:11 -0500 |
---|---|---|
committer | Jordan Cook <jordan.cook@pioneer.com> | 2021-04-23 20:43:34 -0500 |
commit | c51cc8886588faa96fb08ceeb798d8ecefaa6508 (patch) | |
tree | 8bfa291bc8ddd269f7aa424aec5035fba300e282 | |
parent | ea7f2369110cd93428bfa997618f0963cee19fb1 (diff) | |
download | requests-cache-c51cc8886588faa96fb08ceeb798d8ecefaa6508.tar.gz |
Include this behavior in old_data_on_error instead, to avoid complications
-rw-r--r-- | HISTORY.md | 3 | ||||
-rw-r--r-- | docs/user_guide.rst | 27 | ||||
-rw-r--r-- | requests_cache/patcher.py | 2 | ||||
-rw-r--r-- | requests_cache/session.py | 6 | ||||
-rw-r--r-- | tests/unit/test_cache.py | 23 |
5 files changed, 27 insertions, 34 deletions
@@ -4,8 +4,7 @@ * Add a filesystem backend that stores responses as local files * Add option to manually cache response objects * Add `use_temp` option to both SQLite and filesystem backends to store files in a temp directory -* Add `raise_for_status` option, to enable using stale cache data for error response codes - (in combination with `old_data_on_error`) +* Update `old_data_on_error` option to also handle error response codes * Use thread-local connections for SQLite backend * Fix `DynamoDbDict.__iter__` to return keys instead of values diff --git a/docs/user_guide.rst b/docs/user_guide.rst index 8631af7..12517fb 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -227,7 +227,7 @@ is used: To set expiration for a single request: - >>> session.get('http://httpbin.org/get', expire_after=360) + >>> session.get('https://httpbin.org/get', expire_after=360) URL Patterns ~~~~~~~~~~~~ @@ -273,11 +273,26 @@ revalidate the cache with the new expiration time: Error Handling -------------- -There are a couple different options for customizing error-handling behavior. - -TODO: document behavior for: -* old_data_on_error -* raise_for_status +In some cases, you might cache a response, have it expire, but then encounter an error when +retrieving a new response. If you would like to use expired response data in these cases, use the +``old_data_on_error`` option: + + >>> # Cache a test response that will expire immediately + >>> session = CachedSession(old_data_on_error=True) + >>> session.get('https://httpbin.org/get', expire_after=0.001) + >>> time.sleep(0.001) + +Afterward, let's say the page has moved and you get a 404, or the site is experiencing downtime and +you get a 500. You will then get the expired cache data instead: + + >>> response = session.get('https://httpbin.org/get') + >>> print(response.from_cache, response.is_expired) + True, True + +In addition to error codes, ``old_data_on_error`` also applies to exceptions (typically a +:py:exc:`~requests.RequestException`). See requests documentation on +`Errors and Exceptions <https://2.python-requests.org/en/master/user/quickstart/#errors-and-exceptions>`_ +for more details on request errors in general. Potential Issues ---------------- diff --git a/requests_cache/patcher.py b/requests_cache/patcher.py index 0313e8b..7d89acc 100644 --- a/requests_cache/patcher.py +++ b/requests_cache/patcher.py @@ -25,7 +25,6 @@ def install_cache( allowable_methods: Iterable['str'] = ('GET', 'HEAD'), filter_fn: Callable = None, old_data_on_error: bool = False, - raise_for_status: bool = False, session_factory: Type[OriginalSession] = CachedSession, **kwargs, ): @@ -54,7 +53,6 @@ def install_cache( allowable_methods=allowable_methods, filter_fn=filter_fn, old_data_on_error=old_data_on_error, - raise_for_status=raise_for_status, **kwargs, ) diff --git a/requests_cache/session.py b/requests_cache/session.py index 9530f78..d34a114 100644 --- a/requests_cache/session.py +++ b/requests_cache/session.py @@ -32,7 +32,6 @@ class CacheMixin: allowable_methods: Iterable['str'] = ('GET', 'HEAD'), filter_fn: Callable = None, old_data_on_error: bool = False, - raise_for_status: bool = False, **kwargs, ): self.cache = init_backend(backend, cache_name, **kwargs) @@ -42,7 +41,6 @@ class CacheMixin: self.urls_expire_after = urls_expire_after self.filter_fn = filter_fn or (lambda r: True) self.old_data_on_error = old_data_on_error - self.raise_for_status = raise_for_status self._cache_name = cache_name self._request_expire_after: ExpirationTime = None @@ -147,7 +145,7 @@ class CacheMixin: logger.debug('Expired response; attempting to re-send request') try: new_response = self._send_and_cache(request, cache_key, **kwargs) - if self.raise_for_status: + if self.old_data_on_error: new_response.raise_for_status() return new_response # Return the expired/invalid response on error, if specified; otherwise reraise @@ -250,8 +248,6 @@ class CachedSession(CacheMixin, OriginalSession): returns a boolean indicating whether or not that response should be cached. Will be applied to both new and previously cached responses. old_data_on_error: Return stale cache data if a new request raises an exception - raise_for_status: Raise exceptions for error response codes (4xx or 5xx). Can be used in - combination with ``old_data_on_error``. secret_key: Optional secret key used to sign cache items for added security """ diff --git a/tests/unit/test_cache.py b/tests/unit/test_cache.py index 8397140..0044893 100644 --- a/tests/unit/test_cache.py +++ b/tests/unit/test_cache.py @@ -342,8 +342,8 @@ def test_expired_request_error(mock_session): assert len(mock_session.cache.responses) == 0 -def test_old_data_on_error(mock_session): - """With old_data_on_error, expect to get old cache data if there is an error during a request""" +def test_old_data_on_error__exception(mock_session): + """With old_data_on_error, expect to get old cache data if there is an exception during a request""" mock_session.old_data_on_error = True mock_session.expire_after = 0.2 @@ -355,24 +355,9 @@ def test_old_data_on_error(mock_session): assert response.from_cache is True and response.is_expired is True -def test_raise_for_status(mock_session): - """Simulate getting a valid response, expiring, and then getting a 404 for the same request""" - mock_session.raise_for_status = True - mock_session.expire_after = 0.01 - mock_session.allowable_codes = (200, 404) - - mock_session.get(MOCKED_URL_404) - time.sleep(0.01) - with pytest.raises(requests.RequestException): - mock_session.get(MOCKED_URL_404) - - -def test_raise_for_status_and_old_data(mock_session): - """Simulate getting a valid response, expiring, and then getting a 404 for the same request - with old_data_on_error - """ +def test_old_data_on_error__error_code(mock_session): + """With old_data_on_error, expect to get old cache data if a response has an error status code""" mock_session.old_data_on_error = True - mock_session.raise_for_status = True mock_session.expire_after = 0.2 mock_session.allowable_codes = (200, 404) |