about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/google/auth/aio
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/google/auth/aio')
-rw-r--r--.venv/lib/python3.12/site-packages/google/auth/aio/__init__.py25
-rw-r--r--.venv/lib/python3.12/site-packages/google/auth/aio/credentials.py143
-rw-r--r--.venv/lib/python3.12/site-packages/google/auth/aio/transport/__init__.py144
-rw-r--r--.venv/lib/python3.12/site-packages/google/auth/aio/transport/aiohttp.py184
-rw-r--r--.venv/lib/python3.12/site-packages/google/auth/aio/transport/sessions.py268
5 files changed, 764 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/google/auth/aio/__init__.py b/.venv/lib/python3.12/site-packages/google/auth/aio/__init__.py
new file mode 100644
index 00000000..331708cb
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/google/auth/aio/__init__.py
@@ -0,0 +1,25 @@
+# Copyright 2024 Google LLC
+#
+# 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.
+
+"""Google Auth AIO Library for Python."""
+
+import logging
+
+from google.auth import version as google_auth_version
+
+
+__version__ = google_auth_version.__version__
+
+# Set default logging handler to avoid "No handler found" warnings.
+logging.getLogger(__name__).addHandler(logging.NullHandler())
diff --git a/.venv/lib/python3.12/site-packages/google/auth/aio/credentials.py b/.venv/lib/python3.12/site-packages/google/auth/aio/credentials.py
new file mode 100644
index 00000000..3bc6a5a6
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/google/auth/aio/credentials.py
@@ -0,0 +1,143 @@
+# Copyright 2024 Google LLC
+#
+# 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.
+
+
+"""Interfaces for asynchronous credentials."""
+
+
+from google.auth import _helpers
+from google.auth import exceptions
+from google.auth._credentials_base import _BaseCredentials
+
+
+class Credentials(_BaseCredentials):
+    """Base class for all asynchronous credentials.
+
+    All credentials have a :attr:`token` that is used for authentication and
+    may also optionally set an :attr:`expiry` to indicate when the token will
+    no longer be valid.
+
+    Most credentials will be :attr:`invalid` until :meth:`refresh` is called.
+    Credentials can do this automatically before the first HTTP request in
+    :meth:`before_request`.
+
+    Although the token and expiration will change as the credentials are
+    :meth:`refreshed <refresh>` and used, credentials should be considered
+    immutable. Various credentials will accept configuration such as private
+    keys, scopes, and other options. These options are not changeable after
+    construction. Some classes will provide mechanisms to copy the credentials
+    with modifications such as :meth:`ScopedCredentials.with_scopes`.
+    """
+
+    def __init__(self):
+        super(Credentials, self).__init__()
+
+    async def apply(self, headers, token=None):
+        """Apply the token to the authentication header.
+
+        Args:
+            headers (Mapping): The HTTP request headers.
+            token (Optional[str]): If specified, overrides the current access
+                token.
+        """
+        self._apply(headers, token=token)
+
+    async def refresh(self, request):
+        """Refreshes the access token.
+
+        Args:
+            request (google.auth.aio.transport.Request): The object used to make
+                HTTP requests.
+
+        Raises:
+            google.auth.exceptions.RefreshError: If the credentials could
+                not be refreshed.
+        """
+        raise NotImplementedError("Refresh must be implemented")
+
+    async def before_request(self, request, method, url, headers):
+        """Performs credential-specific before request logic.
+
+        Refreshes the credentials if necessary, then calls :meth:`apply` to
+        apply the token to the authentication header.
+
+        Args:
+            request (google.auth.aio.transport.Request): The object used to make
+                HTTP requests.
+            method (str): The request's HTTP method or the RPC method being
+                invoked.
+            url (str): The request's URI or the RPC service's URI.
+            headers (Mapping): The request's headers.
+        """
+        await self.apply(headers)
+
+
+class StaticCredentials(Credentials):
+    """Asynchronous Credentials representing an immutable access token.
+
+    The credentials are considered immutable except the tokens which can be
+    configured in the constructor ::
+
+        credentials = StaticCredentials(token="token123")
+
+    StaticCredentials does not support :meth `refresh` and assumes that the configured
+    token is valid and not expired. StaticCredentials will never attempt to
+    refresh the token.
+    """
+
+    def __init__(self, token):
+        """
+        Args:
+            token (str): The access token.
+        """
+        super(StaticCredentials, self).__init__()
+        self.token = token
+
+    @_helpers.copy_docstring(Credentials)
+    async def refresh(self, request):
+        raise exceptions.InvalidOperation("Static credentials cannot be refreshed.")
+
+    # Note: before_request should never try to refresh access tokens.
+    # StaticCredentials intentionally does not support it.
+    @_helpers.copy_docstring(Credentials)
+    async def before_request(self, request, method, url, headers):
+        await self.apply(headers)
+
+
+class AnonymousCredentials(Credentials):
+    """Asynchronous Credentials that do not provide any authentication information.
+
+    These are useful in the case of services that support anonymous access or
+    local service emulators that do not use credentials.
+    """
+
+    async def refresh(self, request):
+        """Raises :class:``InvalidOperation``, anonymous credentials cannot be
+        refreshed."""
+        raise exceptions.InvalidOperation("Anonymous credentials cannot be refreshed.")
+
+    async def apply(self, headers, token=None):
+        """Anonymous credentials do nothing to the request.
+
+        The optional ``token`` argument is not supported.
+
+        Raises:
+            google.auth.exceptions.InvalidValue: If a token was specified.
+        """
+        if token is not None:
+            raise exceptions.InvalidValue("Anonymous credentials don't support tokens.")
+
+    async def before_request(self, request, method, url, headers):
+        """Anonymous credentials do nothing to the request."""
+        pass
diff --git a/.venv/lib/python3.12/site-packages/google/auth/aio/transport/__init__.py b/.venv/lib/python3.12/site-packages/google/auth/aio/transport/__init__.py
new file mode 100644
index 00000000..166a3be5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/google/auth/aio/transport/__init__.py
@@ -0,0 +1,144 @@
+# Copyright 2024 Google LLC
+#
+# 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.
+
+"""Transport - Asynchronous HTTP client library support.
+
+:mod:`google.auth.aio` is designed to work with various asynchronous client libraries such
+as aiohttp. In order to work across these libraries with different
+interfaces some abstraction is needed.
+
+This module provides two interfaces that are implemented by transport adapters
+to support HTTP libraries. :class:`Request` defines the interface expected by
+:mod:`google.auth` to make asynchronous requests. :class:`Response` defines the interface
+for the return value of :class:`Request`.
+"""
+
+import abc
+from typing import AsyncGenerator, Mapping, Optional
+
+import google.auth.transport
+
+
+_DEFAULT_TIMEOUT_SECONDS = 180
+
+DEFAULT_RETRYABLE_STATUS_CODES = google.auth.transport.DEFAULT_RETRYABLE_STATUS_CODES
+"""Sequence[int]:  HTTP status codes indicating a request can be retried.
+"""
+
+
+DEFAULT_MAX_RETRY_ATTEMPTS = 3
+"""int: How many times to retry a request."""
+
+
+class Response(metaclass=abc.ABCMeta):
+    """Asynchronous HTTP Response Interface."""
+
+    @property
+    @abc.abstractmethod
+    def status_code(self) -> int:
+        """
+        The HTTP response status code.
+
+        Returns:
+            int: The HTTP response status code.
+
+        """
+        raise NotImplementedError("status_code must be implemented.")
+
+    @property
+    @abc.abstractmethod
+    def headers(self) -> Mapping[str, str]:
+        """The HTTP response headers.
+
+        Returns:
+            Mapping[str, str]: The HTTP response headers.
+        """
+        raise NotImplementedError("headers must be implemented.")
+
+    @abc.abstractmethod
+    async def content(self, chunk_size: int) -> AsyncGenerator[bytes, None]:
+        """The raw response content.
+
+        Args:
+            chunk_size (int): The size of each chunk.
+
+        Yields:
+            AsyncGenerator[bytes, None]: An asynchronous generator yielding
+            response chunks as bytes.
+        """
+        raise NotImplementedError("content must be implemented.")
+
+    @abc.abstractmethod
+    async def read(self) -> bytes:
+        """Read the entire response content as bytes.
+
+        Returns:
+            bytes: The entire response content.
+        """
+        raise NotImplementedError("read must be implemented.")
+
+    @abc.abstractmethod
+    async def close(self):
+        """Close the response after it is fully consumed to resource."""
+        raise NotImplementedError("close must be implemented.")
+
+
+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.
+
+    .. automethod:: __call__
+    """
+
+    @abc.abstractmethod
+    async def __call__(
+        self,
+        url: str,
+        method: str,
+        body: Optional[bytes],
+        headers: Optional[Mapping[str, str]],
+        timeout: float,
+        **kwargs
+    ) -> Response:
+        """Make an HTTP request.
+
+        Args:
+            url (str): The URI to be requested.
+            method (str): The HTTP method to use for the request. Defaults
+                to 'GET'.
+            body (Optional[bytes]): The payload / body in HTTP request.
+            headers (Mapping[str, str]): Request headers.
+            timeout (float): The number of seconds to wait for a
+                response from the server. If not specified or if None, the
+                transport-specific default timeout will be used.
+            kwargs: Additional arguments passed on to the transport's
+                request method.
+
+        Returns:
+            google.auth.aio.transport.Response: The HTTP response.
+
+        Raises:
+            google.auth.exceptions.TransportError: If any exception occurred.
+        """
+        # pylint: disable=redundant-returns-doc, missing-raises-doc
+        # (pylint doesn't play well with abstract docstrings.)
+        raise NotImplementedError("__call__ must be implemented.")
+
+    async def close(self) -> None:
+        """
+        Close the underlying session.
+        """
+        raise NotImplementedError("close must be implemented.")
diff --git a/.venv/lib/python3.12/site-packages/google/auth/aio/transport/aiohttp.py b/.venv/lib/python3.12/site-packages/google/auth/aio/transport/aiohttp.py
new file mode 100644
index 00000000..074d1491
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/google/auth/aio/transport/aiohttp.py
@@ -0,0 +1,184 @@
+# Copyright 2024 Google LLC
+#
+# 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.
+
+"""Transport adapter for Asynchronous HTTP Requests based on aiohttp.
+"""
+
+import asyncio
+from typing import AsyncGenerator, Mapping, Optional
+
+try:
+    import aiohttp  # type: ignore
+except ImportError as caught_exc:  # pragma: NO COVER
+    raise ImportError(
+        "The aiohttp library is not installed from please install the aiohttp package to use the aiohttp transport."
+    ) from caught_exc
+
+from google.auth import _helpers
+from google.auth import exceptions
+from google.auth.aio import transport
+
+
+class Response(transport.Response):
+    """
+    Represents an HTTP response and its data. It is returned by ``google.auth.aio.transport.sessions.AsyncAuthorizedSession``.
+
+    Args:
+        response (aiohttp.ClientResponse): An instance of aiohttp.ClientResponse.
+
+    Attributes:
+        status_code (int): The HTTP status code of the response.
+        headers (Mapping[str, str]): The HTTP headers of the response.
+    """
+
+    def __init__(self, response: aiohttp.ClientResponse):
+        self._response = response
+
+    @property
+    @_helpers.copy_docstring(transport.Response)
+    def status_code(self) -> int:
+        return self._response.status
+
+    @property
+    @_helpers.copy_docstring(transport.Response)
+    def headers(self) -> Mapping[str, str]:
+        return {key: value for key, value in self._response.headers.items()}
+
+    @_helpers.copy_docstring(transport.Response)
+    async def content(self, chunk_size: int = 1024) -> AsyncGenerator[bytes, None]:
+        try:
+            async for chunk in self._response.content.iter_chunked(
+                chunk_size
+            ):  # pragma: no branch
+                yield chunk
+        except aiohttp.ClientPayloadError as exc:
+            raise exceptions.ResponseError(
+                "Failed to read from the payload stream."
+            ) from exc
+
+    @_helpers.copy_docstring(transport.Response)
+    async def read(self) -> bytes:
+        try:
+            return await self._response.read()
+        except aiohttp.ClientResponseError as exc:
+            raise exceptions.ResponseError("Failed to read the response body.") from exc
+
+    @_helpers.copy_docstring(transport.Response)
+    async def close(self):
+        self._response.close()
+
+
+class Request(transport.Request):
+    """Asynchronous Requests request adapter.
+
+    This class is used internally for making requests using aiohttp
+    in a consistent way. If you use :class:`google.auth.aio.transport.sessions.AsyncAuthorizedSession`
+    you do not need to construct or use this class directly.
+
+    This class can be useful if you want to configure a Request callable
+    with a custom ``aiohttp.ClientSession`` in :class:`AuthorizedSession` or if
+    you want to manually refresh a :class:`~google.auth.aio.credentials.Credentials` instance::
+
+        import aiohttp
+        import google.auth.aio.transport.aiohttp
+
+        # Default example:
+        request = google.auth.aio.transport.aiohttp.Request()
+        await credentials.refresh(request)
+
+        # Custom aiohttp Session Example:
+        session = session=aiohttp.ClientSession(auto_decompress=False)
+        request = google.auth.aio.transport.aiohttp.Request(session=session)
+        auth_sesion = google.auth.aio.transport.sessions.AsyncAuthorizedSession(auth_request=request)
+
+    Args:
+        session (aiohttp.ClientSession): An instance :class:`aiohttp.ClientSession` used
+            to make HTTP requests. If not specified, a session will be created.
+
+    .. automethod:: __call__
+    """
+
+    def __init__(self, session: aiohttp.ClientSession = None):
+        self._session = session
+        self._closed = False
+
+    async def __call__(
+        self,
+        url: str,
+        method: str = "GET",
+        body: Optional[bytes] = None,
+        headers: Optional[Mapping[str, str]] = None,
+        timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        **kwargs,
+    ) -> transport.Response:
+        """
+        Make an HTTP request using aiohttp.
+
+        Args:
+            url (str): The URL to be requested.
+            method (Optional[str]):
+                The HTTP method to use for the request. Defaults to 'GET'.
+            body (Optional[bytes]):
+                The payload or body in HTTP request.
+            headers (Optional[Mapping[str, str]]):
+                Request headers.
+            timeout (float): The number of seconds to wait for a
+                response from the server. If not specified or if None, the
+                requests default timeout will be used.
+            kwargs: Additional arguments passed through to the underlying
+                aiohttp :meth:`aiohttp.Session.request` method.
+
+        Returns:
+            google.auth.aio.transport.Response: The HTTP response.
+
+        Raises:
+            - google.auth.exceptions.TransportError: If the request fails or if the session is closed.
+            - google.auth.exceptions.TimeoutError: If the request times out.
+        """
+
+        try:
+            if self._closed:
+                raise exceptions.TransportError("session is closed.")
+
+            if not self._session:
+                self._session = aiohttp.ClientSession()
+
+            client_timeout = aiohttp.ClientTimeout(total=timeout)
+            response = await self._session.request(
+                method,
+                url,
+                data=body,
+                headers=headers,
+                timeout=client_timeout,
+                **kwargs,
+            )
+            return Response(response)
+
+        except aiohttp.ClientError as caught_exc:
+            client_exc = exceptions.TransportError(f"Failed to send request to {url}.")
+            raise client_exc from caught_exc
+
+        except asyncio.TimeoutError as caught_exc:
+            timeout_exc = exceptions.TimeoutError(
+                f"Request timed out after {timeout} seconds."
+            )
+            raise timeout_exc from caught_exc
+
+    async def close(self) -> None:
+        """
+        Close the underlying aiohttp session to release the acquired resources.
+        """
+        if not self._closed and self._session:
+            await self._session.close()
+        self._closed = True
diff --git a/.venv/lib/python3.12/site-packages/google/auth/aio/transport/sessions.py b/.venv/lib/python3.12/site-packages/google/auth/aio/transport/sessions.py
new file mode 100644
index 00000000..fea7cbbb
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/google/auth/aio/transport/sessions.py
@@ -0,0 +1,268 @@
+# Copyright 2024 Google LLC
+#
+# 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.
+
+import asyncio
+from contextlib import asynccontextmanager
+import functools
+import time
+from typing import Mapping, Optional
+
+from google.auth import _exponential_backoff, exceptions
+from google.auth.aio import transport
+from google.auth.aio.credentials import Credentials
+from google.auth.exceptions import TimeoutError
+
+try:
+    from google.auth.aio.transport.aiohttp import Request as AiohttpRequest
+
+    AIOHTTP_INSTALLED = True
+except ImportError:  # pragma: NO COVER
+    AIOHTTP_INSTALLED = False
+
+
+@asynccontextmanager
+async def timeout_guard(timeout):
+    """
+    timeout_guard is an asynchronous context manager to apply a timeout to an asynchronous block of code.
+
+    Args:
+        timeout (float): The time in seconds before the context manager times out.
+
+    Raises:
+        google.auth.exceptions.TimeoutError: If the code within the context exceeds the provided timeout.
+
+    Usage:
+        async with timeout_guard(10) as with_timeout:
+            await with_timeout(async_function())
+    """
+    start = time.monotonic()
+    total_timeout = timeout
+
+    def _remaining_time():
+        elapsed = time.monotonic() - start
+        remaining = total_timeout - elapsed
+        if remaining <= 0:
+            raise TimeoutError(
+                f"Context manager exceeded the configured timeout of {total_timeout}s."
+            )
+        return remaining
+
+    async def with_timeout(coro):
+        try:
+            remaining = _remaining_time()
+            response = await asyncio.wait_for(coro, remaining)
+            return response
+        except (asyncio.TimeoutError, TimeoutError) as e:
+            raise TimeoutError(
+                f"The operation {coro} exceeded the configured timeout of {total_timeout}s."
+            ) from e
+
+    try:
+        yield with_timeout
+
+    finally:
+        _remaining_time()
+
+
+class AsyncAuthorizedSession:
+    """This is an asynchronous implementation of :class:`google.auth.requests.AuthorizedSession` class.
+    We utilize an instance of a class that implements :class:`google.auth.aio.transport.Request` configured
+    by the caller or otherwise default to `google.auth.aio.transport.aiohttp.Request` if the external aiohttp
+    package is installed.
+
+    A Requests Session class with credentials.
+
+    This class is used to perform asynchronous requests to API endpoints that require
+    authorization::
+
+        import aiohttp
+        from google.auth.aio.transport import sessions
+
+        async with sessions.AsyncAuthorizedSession(credentials) as authed_session:
+            response = await authed_session.request(
+                'GET', 'https://www.googleapis.com/storage/v1/b')
+
+    The underlying :meth:`request` implementation handles adding the
+    credentials' headers to the request and refreshing credentials as needed.
+
+    Args:
+        credentials (google.auth.aio.credentials.Credentials):
+            The credentials to add to the request.
+        auth_request (Optional[google.auth.aio.transport.Request]):
+            An instance of a class that implements
+            :class:`~google.auth.aio.transport.Request` used to make requests
+            and refresh credentials. If not passed,
+            an instance of :class:`~google.auth.aio.transport.aiohttp.Request`
+            is created.
+
+    Raises:
+        - google.auth.exceptions.TransportError: If `auth_request` is `None`
+            and the external package `aiohttp` is not installed.
+        - google.auth.exceptions.InvalidType: If the provided credentials are
+            not of type `google.auth.aio.credentials.Credentials`.
+    """
+
+    def __init__(
+        self, credentials: Credentials, auth_request: Optional[transport.Request] = None
+    ):
+        if not isinstance(credentials, Credentials):
+            raise exceptions.InvalidType(
+                f"The configured credentials of type {type(credentials)} are invalid and must be of type `google.auth.aio.credentials.Credentials`"
+            )
+        self._credentials = credentials
+        _auth_request = auth_request
+        if not _auth_request and AIOHTTP_INSTALLED:
+            _auth_request = AiohttpRequest()
+        if _auth_request is None:
+            raise exceptions.TransportError(
+                "`auth_request` must either be configured or the external package `aiohttp` must be installed to use the default value."
+            )
+        self._auth_request = _auth_request
+
+    async def request(
+        self,
+        method: str,
+        url: str,
+        data: Optional[bytes] = None,
+        headers: Optional[Mapping[str, str]] = None,
+        max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        **kwargs,
+    ) -> transport.Response:
+        """
+        Args:
+                method (str): The http method used to make the request.
+                url (str): The URI to be requested.
+                data (Optional[bytes]): The payload or body in HTTP request.
+                headers (Optional[Mapping[str, str]]): Request headers.
+                timeout (float):
+                The amount of time in seconds to wait for the server response
+                with each individual request.
+                max_allowed_time (float):
+                If the method runs longer than this, a ``Timeout`` exception is
+                automatically raised. Unlike the ``timeout`` parameter, this
+                value applies to the total method execution time, even if
+                multiple requests are made under the hood.
+
+                Mind that it is not guaranteed that the timeout error is raised
+                at ``max_allowed_time``. It might take longer, for example, if
+                an underlying request takes a lot of time, but the request
+                itself does not timeout, e.g. if a large file is being
+                transmitted. The timout error will be raised after such
+                request completes.
+
+        Returns:
+                google.auth.aio.transport.Response: The HTTP response.
+
+        Raises:
+                google.auth.exceptions.TimeoutError: If the method does not complete within
+                the configured `max_allowed_time` or the request exceeds the configured
+                `timeout`.
+        """
+
+        retries = _exponential_backoff.AsyncExponentialBackoff(
+            total_attempts=transport.DEFAULT_MAX_RETRY_ATTEMPTS
+        )
+        async with timeout_guard(max_allowed_time) as with_timeout:
+            await with_timeout(
+                # Note: before_request will attempt to refresh credentials if expired.
+                self._credentials.before_request(
+                    self._auth_request, method, url, headers
+                )
+            )
+            # Workaround issue in python 3.9 related to code coverage by adding `# pragma: no branch`
+            # See https://github.com/googleapis/gapic-generator-python/pull/1174#issuecomment-1025132372
+            async for _ in retries:  # pragma: no branch
+                response = await with_timeout(
+                    self._auth_request(url, method, data, headers, timeout, **kwargs)
+                )
+                if response.status_code not in transport.DEFAULT_RETRYABLE_STATUS_CODES:
+                    break
+        return response
+
+    @functools.wraps(request)
+    async def get(
+        self,
+        url: str,
+        data: Optional[bytes] = None,
+        headers: Optional[Mapping[str, str]] = None,
+        max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        **kwargs,
+    ) -> transport.Response:
+        return await self.request(
+            "GET", url, data, headers, max_allowed_time, timeout, **kwargs
+        )
+
+    @functools.wraps(request)
+    async def post(
+        self,
+        url: str,
+        data: Optional[bytes] = None,
+        headers: Optional[Mapping[str, str]] = None,
+        max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        **kwargs,
+    ) -> transport.Response:
+        return await self.request(
+            "POST", url, data, headers, max_allowed_time, timeout, **kwargs
+        )
+
+    @functools.wraps(request)
+    async def put(
+        self,
+        url: str,
+        data: Optional[bytes] = None,
+        headers: Optional[Mapping[str, str]] = None,
+        max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        **kwargs,
+    ) -> transport.Response:
+        return await self.request(
+            "PUT", url, data, headers, max_allowed_time, timeout, **kwargs
+        )
+
+    @functools.wraps(request)
+    async def patch(
+        self,
+        url: str,
+        data: Optional[bytes] = None,
+        headers: Optional[Mapping[str, str]] = None,
+        max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        **kwargs,
+    ) -> transport.Response:
+        return await self.request(
+            "PATCH", url, data, headers, max_allowed_time, timeout, **kwargs
+        )
+
+    @functools.wraps(request)
+    async def delete(
+        self,
+        url: str,
+        data: Optional[bytes] = None,
+        headers: Optional[Mapping[str, str]] = None,
+        max_allowed_time: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        timeout: float = transport._DEFAULT_TIMEOUT_SECONDS,
+        **kwargs,
+    ) -> transport.Response:
+        return await self.request(
+            "DELETE", url, data, headers, max_allowed_time, timeout, **kwargs
+        )
+
+    async def close(self) -> None:
+        """
+        Close the underlying auth request session.
+        """
+        await self._auth_request.close()