Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Feat: gzip/decompressed response content handling #584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 63 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
ef6d872
feat: asyncio http request logic and asynchronous credentials log c
anibadde Jul 28, 2020
0a63b3c
feat: all asynchronous credentials types implemented and with tests
anibadde Jul 28, 2020
1fb2bce
included system tests for the asynchronous auth library
anibadde Jul 28, 2020
06606ff
feat: added the private scope for Response class
anibadde Jul 28, 2020
cd57fad
feat: added docstring for Auth Session request method
anibadde Jul 28, 2020
a38e333
fix: Changed initialization of client session to within an async cont…
anibadde Jul 28, 2020
57d6d10
changed aiohttp_requests abbreviation for the async authorized sessio…
anibadde Jul 28, 2020
1db84f2
Merge branch 'auth1' into auth2
anibadde Jul 28, 2020
cc14082
fix: changed abbrevation of the aiohttp_requests file
anibadde Jul 28, 2020
80d005f
Merge branch 'auth2' into auth3
anibadde Jul 28, 2020
aa6ece2
fix: comments on PR regarding shared data between requests and aiohtt…
anibadde Jul 28, 2020
d88839b
fix: fixed noxfile test dependency sharing
anibadde Jul 28, 2020
dfc6251
fix: Made fixes based on comments on first PR
anibadde Jul 28, 2020
c62dd1a
fix: fixed the noxfile dependencies between sync and async unit tests
anibadde Jul 28, 2020
7080d14
fix: cover async dependency
anibadde Jul 28, 2020
8122dbb
Merge branch 'auth1' into auth2
anibadde Jul 28, 2020
b8b585a
Merge branch 'auth2' into auth3
anibadde Jul 28, 2020
77ca4c7
Merge branch 'async' into auth2
anibadde Jul 28, 2020
b4c306f
fix: merge conflict issue with credentials
anibadde Jul 28, 2020
9ddb911
fix: merge conflict #2
anibadde Jul 28, 2020
8f2d0ef
fix: changed duplicated constants for sync-->async inheritance relati…
anibadde Jul 29, 2020
9ec8277
fix: async docstring
anibadde Jul 29, 2020
8f254de
refactoring
anibadde Jul 29, 2020
aa04dc9
fix: refactoring
anibadde Jul 29, 2020
0c4c3b6
fix: first round of comments, refactoring and test duplication changes
anibadde Jul 30, 2020
92175f2
fix: removed duplication in _default_async
anibadde Jul 30, 2020
2b29a54
Merge branch 'auth2' into auth3
anibadde Jul 30, 2020
337c772
compute engine and metadata changes
anibadde Jul 30, 2020
77d7b6e
fix: removed oauth2 client
anibadde Jul 30, 2020
fd30685
added further system tests and refactored
anibadde Jul 31, 2020
0ba2dda
Merge branch 'auth2' into auth3
anibadde Jul 31, 2020
50f7fb7
Merge branch 'async' into auth3
anibadde Jul 31, 2020
1d7c8dc
modified aiohttp request docstring
anibadde Jul 31, 2020
f7b49ed
refactoring and fixing comments
anibadde Jul 31, 2020
dd92972
refactored system tests and re-wrote nox file
anibadde Jul 31, 2020
c8a61c0
metadata typo
anibadde Jul 31, 2020
53567f2
fix: nox file tests added
anibadde Jul 31, 2020
1ed6e11
fix: directory path in app_engine
anibadde Jul 31, 2020
81d77d2
with commented changes for decompressing
anibadde Aug 6, 2020
e3ac25b
fix: gzip
anibadde Aug 6, 2020
440fdcd
add helper, more to do
crwilcox Aug 6, 2020
2795786
simplify encoding check
crwilcox Aug 6, 2020
7dcdd23
fix: gzip autodecompress changes
anibadde Aug 6, 2020
4a16f7c
separate response classes
crwilcox Aug 7, 2020
8c2a10d
fix: mock response with raw/decompressed changes
anibadde Aug 7, 2020
0bc1ff0
Merge branch 'gzip' of https://github.com/AniBadde/google-auth-librar…
anibadde Aug 7, 2020
5e86c23
remove commented code
crwilcox Aug 7, 2020
f234566
add missing methods to complete respons interface
crwilcox Aug 7, 2020
06769c4
fix: changes
anibadde Aug 7, 2020
4facfed
Merge branch 'gzip' of https://github.com/AniBadde/google-auth-librar…
anibadde Aug 7, 2020
5caccea
remove commented code
crwilcox Aug 7, 2020
c0d003b
blacken
crwilcox Aug 7, 2020
74d1c65
lint
crwilcox Aug 7, 2020
111c27b
move _CombinedResponse to resumable media
crwilcox Aug 7, 2020
2fc6c00
Merge branch 'gzip' of https://github.com/AniBadde/google-auth-librar…
anibadde Aug 7, 2020
4b2cfb3
Merge branch 'async' into gzip
anibadde Aug 7, 2020
4980fcc
fix: gzip changes
anibadde Aug 7, 2020
3b56a68
fix: changes for passes
anibadde Aug 7, 2020
1a9b873
fix: current auth state client_async
anibadde Aug 7, 2020
4cebd8f
fix: current state
anibadde Aug 7, 2020
b47cbb6
Update google/oauth2/_client_async.py
anibadde Aug 7, 2020
cce1738
fix: comment addressing
anibadde Aug 7, 2020
6955a69
Merge branch 'gzip' of https://github.com/AniBadde/google-auth-librar…
anibadde Aug 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 74 additions & 9 deletions 83 google/auth/transport/aiohttp_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import asyncio
import functools
import zlib

import aiohttp
import six
Expand All @@ -31,6 +32,57 @@
_DEFAULT_TIMEOUT = 180 # in seconds


class _CombinedResponse(transport.Response):
crwilcox marked this conversation as resolved.
Show resolved Hide resolved
"""
In order to more closely resemble the `requests` interface, where a raw
and deflated content could be accessed at once, this class lazily reads the
stream in `transport.Response` so both return forms can be used.

The gzip and deflate transfer-encodings are automatically decoded for you
because the default parameter for autodecompress into the ClientSession is set
to False, and therefore we add this class to act as a wrapper for a user to be
able to access both the raw and decoded response bodies - mirroring the sync
implementation.
"""

def __init__(self, response):
self._response = response
self._raw_content = None

def _is_compressed(self):
headers = self._client_response.headers
return "Content-Encoding" in headers and (
headers["Content-Encoding"] == "gzip"
or headers["Content-Encoding"] == "deflate"
)

@property
def status(self):
return self._response.status

@property
def headers(self):
return self._response.headers

@property
def data(self):
return self._response.content

async def raw_content(self):
if self._raw_content is None:
self._raw_content = await self._response.content.read()
return self._raw_content

async def content(self):
if self._raw_content is None:
self._raw_content = await self._response.content.read()
if self._is_compressed:
d = zlib.decompressobj(zlib.MAX_WBITS | 32)
decompressed = d.decompress(self._raw_content)
return decompressed
return self._raw_content


class _Response(transport.Response):
"""
Requests transport response adapter.
Expand Down Expand Up @@ -79,7 +131,6 @@ class Request(transport.Request):
"""

def __init__(self, session=None):

self.session = None

async def __call__(
Expand All @@ -89,7 +140,7 @@ async def __call__(
body=None,
headers=None,
timeout=_DEFAULT_TIMEOUT,
**kwargs
**kwargs,
):
"""
Make an HTTP request using aiohttp.
Expand All @@ -115,12 +166,14 @@ async def __call__(

try:
if self.session is None: # pragma: NO COVER
self.session = aiohttp.ClientSession() # pragma: NO COVER
self.session = aiohttp.ClientSession(
auto_decompress=False
) # pragma: NO COVER
requests._LOGGER.debug("Making request: %s %s", method, url)
response = await self.session.request(
method, url, data=body, headers=headers, timeout=timeout, **kwargs
)
return _Response(response)
return _CombinedResponse(response)

except aiohttp.ClientError as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
Expand Down Expand Up @@ -175,6 +228,7 @@ def __init__(
max_refresh_attempts=transport.DEFAULT_MAX_REFRESH_ATTEMPTS,
refresh_timeout=None,
auth_request=None,
auto_decompress=False,
):
super(AuthorizedSession, self).__init__()
self.credentials = credentials
Expand All @@ -186,6 +240,7 @@ def __init__(
self._auth_request_session = None
self._loop = asyncio.get_event_loop()
self._refresh_lock = asyncio.Lock()
self._auto_decompress = auto_decompress

async def request(
self,
Expand All @@ -195,7 +250,8 @@ async def request(
headers=None,
max_allowed_time=None,
timeout=_DEFAULT_TIMEOUT,
**kwargs
auto_decompress=False,
**kwargs,
):

"""Implementation of Authorized Session aiohttp request.
Expand Down Expand Up @@ -230,8 +286,17 @@ async def request(
transmitted. The timout error will be raised after such
request completes.
"""

async with aiohttp.ClientSession() as self._auth_request_session:
# Headers come in as bytes which isn't expected behavior, the resumable
# media libraries in some cases expect a str type for the header values,
# but sometimes the operations return these in bytes types.
if headers:
for key in headers.keys():
crwilcox marked this conversation as resolved.
Show resolved Hide resolved
if type(headers[key]) is bytes:
headers[key] = headers[key].decode("utf-8")

async with aiohttp.ClientSession(
auto_decompress=self._auto_decompress
) as self._auth_request_session:
auth_request = Request(self._auth_request_session)
self._auth_request = auth_request

Expand Down Expand Up @@ -264,7 +329,7 @@ async def request(
data=data,
headers=request_headers,
timeout=timeout,
**kwargs
**kwargs,
crwilcox marked this conversation as resolved.
Show resolved Hide resolved
)

remaining_time = guard.remaining_timeout
Expand Down Expand Up @@ -307,7 +372,7 @@ async def request(
max_allowed_time=remaining_time,
timeout=timeout,
_credential_refresh_attempt=_credential_refresh_attempt + 1,
**kwargs
**kwargs,
)

return response
9 changes: 6 additions & 3 deletions 9 google/auth/transport/mtls.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,12 @@ def default_client_encrypted_cert_source(cert_path, key_path):

def callback():
try:
_, cert_bytes, key_bytes, passphrase_bytes = _mtls_helper.get_client_ssl_credentials(
generate_encrypted_key=True
)
(
_,
cert_bytes,
key_bytes,
passphrase_bytes,
) = _mtls_helper.get_client_ssl_credentials(generate_encrypted_key=True)
with open(cert_path, "wb") as cert_file:
cert_file.write(cert_bytes)
with open(key_path, "wb") as key_file:
Expand Down
3 changes: 2 additions & 1 deletion 3 google/oauth2/_client_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ async def _token_endpoint_request(request, token_uri, body):
method="POST", url=token_uri, headers=headers, body=body
)

response_body1 = await response.data.read()
# Using data.read() resulted in zlib decompression errors. This may require future investigation.
response_body1 = await response.content()

response_body = (
response_body1.decode("utf-8")
Expand Down
7 changes: 6 additions & 1 deletion 7 google/oauth2/credentials_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ async def refresh(self, request):
"token_uri, client_id, and client_secret."
)

access_token, refresh_token, expiry, grant_response = await _client.refresh_grant(
(
access_token,
refresh_token,
expiry,
grant_response,
) = await _client.refresh_grant(
request,
self._token_uri,
self._refresh_token,
Expand Down
1 change: 1 addition & 0 deletions 1 tests_async/oauth2/test__client_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def make_request(response_data, status=http_client.OK):
data = json.dumps(response_data).encode("utf-8")
response.data = mock.AsyncMock(spec=["__call__", "read"])
response.data.read = mock.AsyncMock(spec=["__call__"], return_value=data)
response.content = mock.AsyncMock(spec=["__call__"], return_value=data)
request = mock.AsyncMock(spec=["transport.Request"])
request.return_value = response
return request
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.