Skip to content
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

feat: asyncio support and aiohttp transport #465

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions docs/reference/google.auth.aio.credentials.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
google.auth.aio.credentials module
==================================

.. automodule:: google.auth.aio.credentials
:members:
:inherited-members:
:show-inheritance:
14 changes: 14 additions & 0 deletions docs/reference/google.auth.aio.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
google.auth.aio package
=======================

.. automodule:: google.auth.aio
:members:
:inherited-members:
:show-inheritance:

Submodules
----------

.. toctree::

google.auth.aio.credentials
1 change: 1 addition & 0 deletions docs/reference/google.auth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Subpackages

.. toctree::

google.auth.aio
google.auth.compute_engine
google.auth.crypt
google.auth.transport
Expand Down
7 changes: 7 additions & 0 deletions docs/reference/google.auth.transport.aio.aiohttp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
google.auth.transport.aio.aiohttp module
========================================

.. automodule:: google.auth.transport.aio.aiohttp
:members:
:inherited-members:
:show-inheritance:
14 changes: 14 additions & 0 deletions docs/reference/google.auth.transport.aio.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
google.auth.transport.aio package
=================================

.. automodule:: google.auth.transport.aio
:members:
:inherited-members:
:show-inheritance:

Submodules
----------

.. toctree::

google.auth.transport.aio.aiohttp
7 changes: 7 additions & 0 deletions docs/reference/google.auth.transport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ google.auth.transport package
:inherited-members:
:show-inheritance:

Subpackages
-----------

.. toctree::

google.auth.transport.aio

Submodules
----------

Expand Down
7 changes: 7 additions & 0 deletions docs/reference/google.oauth2.aio.credentials.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
google.oauth2.aio.credentials module
====================================

.. automodule:: google.oauth2.aio.credentials
:members:
:inherited-members:
:show-inheritance:
15 changes: 15 additions & 0 deletions docs/reference/google.oauth2.aio.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
google.oauth2.aio package
=========================

.. automodule:: google.oauth2.aio
:members:
:inherited-members:
:show-inheritance:

Submodules
----------

.. toctree::

google.oauth2.aio.credentials
google.oauth2.aio.service_account
7 changes: 7 additions & 0 deletions docs/reference/google.oauth2.aio.service_account.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
google.oauth2.aio.service\_account module
=========================================

.. automodule:: google.oauth2.aio.service_account
:members:
:inherited-members:
:show-inheritance:
7 changes: 7 additions & 0 deletions docs/reference/google.oauth2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ google.oauth2 package
:inherited-members:
:show-inheritance:

Subpackages
-----------

.. toctree::

google.oauth2.aio

Submodules
----------

Expand Down
1 change: 1 addition & 0 deletions docs/requirements-docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ sphinx-docstring-typing
urllib3
requests
requests-oauthlib
aiohttp
19 changes: 19 additions & 0 deletions docs/user-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,22 @@ to a gRPC service::
http://www.grpc.io/docs/guides/wire.html
.. _Call Credentials:
http://www.grpc.io/docs/guides/auth.html

aiohttp
+++++++

:mod:`aiohttp` is an HTTP library for use with asyncio.
:mod:`google.auth.transport.aio.aiohttp` presents a coroutine interface for
authenticated request headers::

import aiohttp
from google.auth.transport.aio import aiohttp as aiohttp_transport

session = aiohttp.ClientSession()
headers = {}
request = aiohttp_transport.Request(session)
await aio_credentials.before_request(
request, 'get', 'https//www.googleapis.com/storage/v1/b')
with session.get(
'https//www.googleapis.com/storage/v1/b', headers=headers) as resp:
...
Empty file added google/auth/aio/__init__.py
Empty file.
66 changes: 66 additions & 0 deletions google/auth/aio/credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Lint as: python3
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Credentials supporting asynchronous transports.

Overrides credentials base methods with asynchronous versions.
"""

import abc
from typing import Any, Mapping, Text

from google.auth import credentials
import google.auth.transport.aio


class Credentials(credentials.Credentials):
"""Base credentials class for asynchronous applications."""

@abc.abstractmethod
async def refresh(self, request: google.auth.transport.aio.Request):
"""Refreshes the access token.

Args:
request: HTTP request client.

Raises:
google.auth.exceptions.RefreshError: If credentials could not be
refreshed.
"""

async def before_request(
self,
request: google.auth.transport.aio.Request,
method: Text,
url: Text,
headers: Mapping[Any, Any],
):
"""Performs credential-specific request pre-processing.

Schedules the credentials to be refreshed if necessary, then calls
:meth:`apply` to apply the token to the authentication header.


Args:
request: The object used to make HTTP requests.
method: The request's HTTP method or the RPC method being invoked.
url: The request's URI or the RPC service's URI.
headers (Mapping): The request's headers.
"""
del method
del url
if not self.valid:
await self.refresh(request)
self.apply(headers)
77 changes: 77 additions & 0 deletions google/auth/transport/aio/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Lint as: python3
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Async HTTP client library support.

Interfaces for asynchronous HTTP libraries. This provides a request adapter for
libraries built on top of asyncio, where HTTP requests are written as
coroutines.
"""

import abc
from typing import Any, Mapping, Text

from google.auth import transport


class Response(metaclass=abc.ABCMeta):
"""HTTP Response data."""

def __init__(
self,
status: int = None,
headers: Mapping[Text, Text] = None,
data: bytes = None,
):
self.status = status
self.headers = headers
self.data = data


class Request(metaclass=abc.ABCMeta):
"""Interface for a callable that makes HTTP requests.

Specific transport implementations should provide an implementation of
this that adapts their specific request / response API.
"""

@abc.abstractmethod
async def __call__(
self,
url: Text,
method: Text = "get",
body: Any = None,
headers: Mapping[Text, Text] = None,
**kwargs
) -> transport.Response:
"""Make an HTTP request.

Same as google.auth.transport.Request, but without
a timeout parameter as asyncio.wait_for should be used instead.

Args:
url: The URI to be requested.
method: The HTTP method to use for the request. Defaults to 'GET'.
body: The payload / body in HTTP request.
headers: Request headers.
**kwargs: Additionally arguments passed on to the transport's request
method.

Returns:
Response: The HTTP response.

Raises:
google.auth.exceptions.TransportError: If any exception occurred.
"""
83 changes: 83 additions & 0 deletions google/auth/transport/aio/aiohttp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Lint as: python3
# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
"""Aiohttp adapter transport adapter.

Uses aiohttp as an http client for refreshing credentials.
"""

from typing import Any, Mapping, Optional, Text

import aiohttp

from google.auth import exceptions
import google.auth.transport.aio as aio_transport


class Request(aio_transport.Request):
"""Aiohttp transport request adapter."""

def __init__(self, session: Optional[aiohttp.ClientSession] = None):
"""Aiohttp request constructor.

Aiohttp recommends using application-wide sessions, so a ClientSession can
be optionally passed into the creation of these requests. If no session is
provided, the basic API will be used instead.

Args:
session: ClientSession which will be used in requests if provided.
"""
self._session = session

async def __call__(
self,
url: Text,
method: Text = "get",
body: Any = None,
headers: Mapping[Text, Text] = None,
**kwargs
) -> aio_transport.Response:
"""Make an HTTP request.

Same as google.auth.transport.Request, but without
a timeout parameter as asyncio.wait_for should be used instead.

Args:
url: The URI to be requested.
method: The HTTP method to use for the request. Defaults to 'GET'.
body: The payload / body in HTTP request.
headers: Request headers.
**kwargs: Additionally arguments passed on to the transport's request
method.

Returns:
Response: The HTTP response.

Raises:
google.auth.exceptions.TransportError: If any exception occurred.
"""
request = self._session.request if self._session else aiohttp.request
try:
async with request(
method, url, data=body, headers=headers, **kwargs
) as resp:
status = resp.status
headers = resp.headers
content = await resp.read()
return aio_transport.Response(status, headers, content)
except aiohttp.ClientError as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
raise new_exc from caught_exc
Empty file added google/oauth2/aio/__init__.py
Empty file.
Loading