summaryrefslogtreecommitdiff
path: root/requests_cache/session.py
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-03-10 13:41:26 -0600
committerJordan Cook <jordan.cook@pioneer.com>2022-03-11 09:02:56 -0600
commit1489fb286fac60d5caa764e5256e3a3d25ce67ff (patch)
treea335ac86410fa64ece8420f77caae9421b4cb902 /requests_cache/session.py
parent369f1b13be5a641f4043d64803e1add358f7a3d4 (diff)
downloadrequests-cache-1489fb286fac60d5caa764e5256e3a3d25ce67ff.tar.gz
Add separate revalidate ('soft refresh') option, support revalidation for no-cache and must-revalidate, and related refactoring
Diffstat (limited to 'requests_cache/session.py')
-rw-r--r--requests_cache/session.py32
1 files changed, 20 insertions, 12 deletions
diff --git a/requests_cache/session.py b/requests_cache/session.py
index d8ba1e3..6292bbb 100644
--- a/requests_cache/session.py
+++ b/requests_cache/session.py
@@ -73,7 +73,7 @@ class CacheMixin(MIXIN_BASE):
session_kwargs = get_valid_kwargs(super().__init__, kwargs)
super().__init__(**session_kwargs) # type: ignore
- def request( # type: ignore # Note: An extra param (expire_after) is added here
+ def request( # type: ignore
self,
method: str,
url: str,
@@ -81,12 +81,13 @@ class CacheMixin(MIXIN_BASE):
expire_after: ExpirationTime = None,
headers: MutableMapping[str, str] = None,
refresh: bool = False,
+ revalidate: bool = False,
**kwargs,
) -> AnyResponse:
"""This method prepares and sends a request while automatically performing any necessary
caching operations. This will be called by any other method-specific ``requests`` functions
- (get, post, etc.). This does not include prepared requests, which will still be cached via
- ``send()``.
+ (get, post, etc.). This is not used by :py:class:`~requests.PreparedRequest` objects, which
+ are handled by :py:meth:`send()`.
See :py:meth:`requests.Session.request` for parameters. Additional parameters:
@@ -94,7 +95,8 @@ class CacheMixin(MIXIN_BASE):
expire_after: Expiration time to set only for this request; see details below.
Overrides ``CachedSession.expire_after``. Accepts all the same values as
``CachedSession.expire_after``. Use ``-1`` to disable expiration.
- refresh: Always make a new request, and overwrite any previously cached response.
+ refresh: Always make a new request, and overwrite any previously cached response
+ revalidate: Revalidate with the server before using a cached response (e.g., a "soft refresh")
Returns:
Either a new or cached response
@@ -109,11 +111,14 @@ class CacheMixin(MIXIN_BASE):
6. :py:meth:`requests.Session.send` (if not previously cached)
7. :py:meth:`.BaseCache.save_response` (if not previously cached)
"""
- # Set any extra options as request headers to be handled in send()
+ # Set extra options as headers to be handled in send(), since we can't pass args directly
+ headers = headers or {}
if expire_after is not None:
headers = append_directive(headers, f'max-age={get_expiration_seconds(expire_after)}')
+ if revalidate:
+ headers = append_directive(headers, 'no-cache')
if refresh:
- headers = append_directive(headers, 'no-cache') # Skip cache read, but not write
+ headers['requests-cache-refresh'] = 'true'
kwargs['headers'] = headers
with patch_form_boundary(**kwargs):
@@ -124,6 +129,7 @@ class CacheMixin(MIXIN_BASE):
request: PreparedRequest,
expire_after: ExpirationTime = None,
refresh: bool = False,
+ revalidate: bool = False,
**kwargs,
) -> AnyResponse:
"""Send a prepared request, with caching. See :py:meth:`.request` for notes on behavior, and
@@ -131,7 +137,8 @@ class CacheMixin(MIXIN_BASE):
Args:
expire_after: Expiration time to set only for this request
- refresh: Always make a new request, and overwrite any previously cached response.
+ refresh: Always make a new request, and overwrite any previously cached response
+ revalidate: Revalidate with the server before using a cached response (e.g., a "soft refresh")
"""
# Determine which actions to take based on request info and cache settings
cache_key = self.cache.create_key(request, **kwargs)
@@ -142,10 +149,10 @@ class CacheMixin(MIXIN_BASE):
session_expire_after=self.expire_after,
urls_expire_after=self.urls_expire_after,
cache_control=self.cache_control,
+ refresh=refresh,
+ revalidate=revalidate,
**kwargs,
)
- if refresh:
- actions.skip_read = True
# Attempt to fetch a cached response
cached_response: Optional[CachedResponse] = None
@@ -155,8 +162,8 @@ class CacheMixin(MIXIN_BASE):
is_expired = getattr(cached_response, 'is_expired', False)
# If the response is expired or missing, or the cache is disabled, then fetch a new response
- if cached_response is None:
- response = self._send_and_cache(request, actions, **kwargs)
+ if cached_response is None or actions.revalidate:
+ response = self._send_and_cache(request, actions, cached_response, **kwargs)
elif is_expired and self.stale_if_error:
response = self._resend_and_ignore(request, actions, cached_response, **kwargs)
elif is_expired:
@@ -197,7 +204,8 @@ class CacheMixin(MIXIN_BASE):
If applicable, also add headers to make a conditional request. If we get a 304 Not Modified
response, return the stale cache item.
"""
- request.headers.update(actions.validation_headers)
+ if actions.revalidate:
+ request.headers.update(actions.validation_headers)
response = super().send(request, **kwargs)
actions.update_from_response(response)