diff options
author | Jordan Cook <jordan.cook@pioneer.com> | 2021-07-16 11:23:31 -0500 |
---|---|---|
committer | Jordan Cook <jordan.cook@pioneer.com> | 2021-07-16 11:33:27 -0500 |
commit | dc495b372c100e1b25877f658b4cb02dcc98940b (patch) | |
tree | aefcf3c864c1d8abebbaaa5942121121a5bc658d /requests_cache | |
parent | 61c9847d9e431c68bad9980061df4c953ff41d2c (diff) | |
download | requests-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.py | 14 | ||||
-rwxr-xr-x | requests_cache/models/response.py | 15 |
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) |