summaryrefslogtreecommitdiff
path: root/requests_cache
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2021-07-16 11:23:31 -0500
committerJordan Cook <jordan.cook@pioneer.com>2021-07-16 11:33:27 -0500
commitdc495b372c100e1b25877f658b4cb02dcc98940b (patch)
treeaefcf3c864c1d8abebbaaa5942121121a5bc658d /requests_cache
parent61c9847d9e431c68bad9980061df4c953ff41d2c (diff)
downloadrequests-cache-dc495b372c100e1b25877f658b4cb02dcc98940b.tar.gz
Add support for Response.next when 302 responses are cached directly
Diffstat (limited to 'requests_cache')
-rw-r--r--requests_cache/models/request.py14
-rwxr-xr-xrequests_cache/models/response.py15
2 files changed, 25 insertions, 4 deletions
diff --git a/requests_cache/models/request.py b/requests_cache/models/request.py
index af21f6d..c72aadb 100644
--- a/requests_cache/models/request.py
+++ b/requests_cache/models/request.py
@@ -22,12 +22,24 @@ class CachedRequest:
url: str = field(default=None)
@classmethod
- def from_request(cls, original_request: PreparedRequest):
+ def from_request(cls, original_request: PreparedRequest) -> 'CachedRequest':
"""Create a CachedRequest based on an original request object"""
kwargs = {k: getattr(original_request, k, None) for k in fields_dict(cls).keys()}
kwargs['cookies'] = getattr(original_request, '_cookies', None)
return cls(**kwargs)
+ def prepare(self) -> PreparedRequest:
+ """Convert the CachedRequest back into a PreparedRequest"""
+ prepared_request = PreparedRequest()
+ prepared_request.prepare(
+ cookies=self.cookies,
+ data=self.body,
+ headers=self.headers,
+ method=self.method,
+ url=self.url,
+ )
+ return prepared_request
+
@property
def _cookies(self):
"""For compatibility with PreparedRequest, which has an attribute named '_cookies', and a
diff --git a/requests_cache/models/response.py b/requests_cache/models/response.py
index b6c558d..a0efb72 100755
--- a/requests_cache/models/response.py
+++ b/requests_cache/models/response.py
@@ -28,6 +28,7 @@ class CachedResponse(Response):
"""
_content: bytes = field(default=None)
+ _next: Optional[CachedRequest] = field(default=None)
url: str = field(default=None)
status_code: int = field(default=0)
cookies: RequestsCookieJar = field(factory=RequestsCookieJar)
@@ -36,9 +37,9 @@ class CachedResponse(Response):
expires: Optional[datetime] = field(default=None)
encoding: str = field(default=None)
headers: CaseInsensitiveDict = field(factory=dict)
- history: List['CachedResponse'] = field(factory=list)
+ history: List['CachedResponse'] = field(factory=list) # type: ignore
reason: str = field(default=None)
- request: CachedRequest = field(factory=CachedRequest)
+ request: CachedRequest = field(factory=CachedRequest) # type: ignore
raw: CachedHTTPResponse = field(factory=CachedHTTPResponse, repr=False)
def __attrs_post_init__(self):
@@ -55,9 +56,12 @@ class CachedResponse(Response):
for k in Response.__attrs__:
setattr(obj, k, getattr(original_response, k, None))
- # Store request and raw response
+ # Store request, raw response, and next response (if it's a redirect response)
obj.request = CachedRequest.from_request(original_response.request)
obj.raw = CachedHTTPResponse.from_response(original_response)
+ obj._next = (
+ CachedRequest.from_request(original_response.next) if original_response.next else None
+ )
# Store response body, which will have been read & decoded by requests.Response by now
obj._content = original_response.content
@@ -88,6 +92,11 @@ class CachedResponse(Response):
"""Determine if this cached response is expired"""
return self.expires is not None and datetime.utcnow() >= self.expires
+ @property
+ def next(self) -> Optional[PreparedRequest]:
+ """Returns a PreparedRequest for the next request in a redirect chain, if there is one."""
+ return self._next.prepare() if self._next else None
+
def revalidate(self, expire_after: ExpirationTime) -> bool:
"""Set a new expiration for this response, and determine if it is now expired"""
self.expires = get_expiration_datetime(expire_after)