Created
September 21, 2018 00:48
-
-
Save medmunds/ad47a5001729040d7743ae20d32786e1 to your computer and use it in GitHub Desktop.
Monkey-patch botocore to improve performance on large API requests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Monkeypatch botocore.awsrequest.AWSRequest.body to improve performance by caching result. | |
# Usage: import this file once, at some point before making boto3 requests | |
# See https://github.com/boto/botocore/issues/1561 | |
import six | |
from botocore.awsrequest import AWSRequest | |
# Monkeypatch AWSRequest.body to improve performance by caching result. | |
# - AWSRequest.body is accessed multiple times during request signing. | |
# (See also https://github.com/boto/botocore/pull/1478.) | |
# - AWSPreparedRequest.prepare_body uses urlencode, which is lengthy on large strings | |
# (specifically quote_plus/quote_from_bytes). | |
# - The botocore 1.12.3 AWSRequest.body implementation needlessly runs prepare_body | |
# twice in a row (because AWSPreparedRequest.__init__ also calls prepare_body). | |
def request_body(self): | |
if not hasattr(self, "_cached_body") or self.data != self._cached_body_data: | |
body = self.prepare().body | |
if isinstance(body, six.text_type): | |
body = body.encode('utf-8') | |
# Note: if self.data is mutable (e.g., POST data dict), this could conceivably | |
# miss changes to the data and return a stale body. As a practical matter, | |
# though, the only botocore code that modifies AWSRequest.data after creation is | |
# auth.SigV4QueryAuth, which might replace a data dict with an empty string. | |
# (So there's no need to implement more robust--and expensive--caching here.) | |
self._cached_body_data = self.data | |
self._cached_body = body | |
return self._cached_body | |
setattr(AWSRequest, "body", property(request_body)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment