diff options
| author | Jordan Cook <jordan.cook@pioneer.com> | 2022-03-10 13:41:26 -0600 |
|---|---|---|
| committer | Jordan Cook <jordan.cook@pioneer.com> | 2022-03-11 09:02:56 -0600 |
| commit | 1489fb286fac60d5caa764e5256e3a3d25ce67ff (patch) | |
| tree | a335ac86410fa64ece8420f77caae9421b4cb902 /requests_cache/session.py | |
| parent | 369f1b13be5a641f4043d64803e1add358f7a3d4 (diff) | |
| download | requests-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.py | 32 |
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) |
