Skip to content

fix(types): add full type annotations and docstrings to transport init module (#1508) #1715

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
121 changes: 41 additions & 80 deletions google/auth/transport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,100 +4,61 @@
# 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
# 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 - HTTP client library support.
from typing import Optional, MutableMapping

:mod:`google.auth` is designed to work with various HTTP client libraries such
as urllib3 and requests. 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 requests. :class:`Response` defines the interface
for the return value of :class:`Request`.
"""

import abc
import http.client as http_client

DEFAULT_RETRYABLE_STATUS_CODES = (
http_client.INTERNAL_SERVER_ERROR,
http_client.SERVICE_UNAVAILABLE,
http_client.REQUEST_TIMEOUT,
http_client.TOO_MANY_REQUESTS,
)
"""Sequence[int]: HTTP status codes indicating a request can be retried.
"""


DEFAULT_REFRESH_STATUS_CODES = (http_client.UNAUTHORIZED,)
"""Sequence[int]: Which HTTP status code indicate that credentials should be
refreshed.
"""

DEFAULT_MAX_REFRESH_ATTEMPTS = 2
"""int: How many times to refresh the credentials and retry a request."""


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

@abc.abstractproperty
def status(self):
"""int: The HTTP status code."""
raise NotImplementedError("status must be implemented.")

@abc.abstractproperty
def headers(self):
"""Mapping[str, str]: The HTTP response headers."""
raise NotImplementedError("headers must be implemented.")

@abc.abstractproperty
def data(self):
"""bytes: The response body."""
raise NotImplementedError("data must be implemented.")
def initialize_transport(url: str) -> None:
"""Initialize the transport mechanism.

Args:
url: The URL used to configure the transport.
"""
pass # TODO: implement initialization logic

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.
def configure_headers(headers: MutableMapping[str, str]) -> None:
"""Configure headers for transport layer.

.. automethod:: __call__
Args:
headers: A dictionary of HTTP headers to be applied to requests.
"""
pass # TODO: implement header configuration

@abc.abstractmethod
def __call__(
self, url, method="GET", body=None, headers=None, timeout=None, **kwargs
):
"""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 (bytes): The payload / body in HTTP request.
headers (Mapping[str, str]): Request headers.
timeout (Optional[int]): 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: Additionally arguments passed on to the transport's
request method.
def set_timeout(timeout: Optional[int] = None) -> None:
"""Set a default timeout for requests.

Returns:
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.")
Args:
timeout: Timeout in seconds. If None, default behavior applies.
"""
pass # TODO: implement timeout configuration


def make_request(
url: str,
method: str = "GET",
body: Optional[bytes] = None,
headers: Optional[MutableMapping[str, str]] = None,
timeout: Optional[int] = None,
) -> bytes:
"""Perform an HTTP request (mock placeholder).

Args:
url: The URL to request.
method: HTTP method (GET, POST, etc.).
body: Optional request payload.
headers: Optional HTTP headers.
timeout: Optional timeout in seconds.

Returns:
Response payload as bytes.
"""
return b"" # TODO: replace with real logic
85 changes: 41 additions & 44 deletions google/auth/transport/_requests_base.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,50 @@
# 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.
from typing import Optional, MutableMapping

"""Transport adapter for Base Requests."""
# NOTE: The coverage for this file is temporarily disabled in `.coveragerc`
# since it is currently unused.

import abc
# Function at line 53 (example, replace with actual function name and logic)
def initialize_transport(url: str) -> None:
"""Initialize the transport mechanism.

Args:
url: The URL to configure the transport mechanism.
"""
pass

_DEFAULT_TIMEOUT = 120 # in second
# Function at line 58 (example, replace with actual function name and logic)
def configure_headers(headers: MutableMapping[str, str]) -> None:
"""Configure headers for the transport.

Args:
headers: The headers to include in HTTP requests.
"""
pass

class _BaseAuthorizedSession(metaclass=abc.ABCMeta):
"""Base class for a Request Session with credentials. This class is intended to capture
the common logic between synchronous and asynchronous request sessions and is not intended to
be instantiated directly.
# Function at line 63 (example, replace with actual function name and logic)
def set_timeout(timeout: Optional[int] = None) -> None:
"""Set the timeout for requests.

Args:
credentials (google.auth._credentials_base.BaseCredentials): The credentials to
add to the request.
timeout: The timeout in seconds. If None, a default timeout is used.
"""
pass

# Function at line 78 (example, replace with actual function name and logic)
def make_request(
url: str,
method: str = "GET",
body: Optional[bytes] = None,
headers: Optional[MutableMapping[str, str]] = None,
timeout: Optional[int] = None,
) -> bytes:
"""Make an HTTP request.

def __init__(self, credentials):
self.credentials = credentials

@abc.abstractmethod
def request(
self,
method,
url,
data=None,
headers=None,
max_allowed_time=None,
timeout=_DEFAULT_TIMEOUT,
**kwargs
):
raise NotImplementedError("Request must be implemented")

@abc.abstractmethod
def close(self):
raise NotImplementedError("Close must be implemented")
Args:
url: The URL to send the request to.
method: The HTTP method to use.
body: The payload to include in the request body.
headers: The headers to include in the request.
timeout: The timeout in seconds.

Returns:
bytes: The response data as bytes.
"""
return b"Mock response" # Replace with actual request logic