Skip to content
New issue

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

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

Already on GitHub? # to your account

refactor: Made auth_headers and auth_params of APIAuthenticatorBase simple instance attributes instead of decorated properties #2596

Merged
Merged
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
78 changes: 34 additions & 44 deletions singer_sdk/authenticators.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,12 @@


class APIAuthenticatorBase:
"""Base class for offloading API auth."""
"""Base class for offloading API auth.

Attributes:
auth_headers: HTTP headers for authentication.
auth_params: URL query parameters for authentication.
"""

def __init__(self, stream: RESTStream) -> None:
"""Init authenticator.
Expand All @@ -89,8 +94,8 @@
"""
self.tap_name: str = stream.tap_name
self._config: dict[str, t.Any] = dict(stream.config)
self._auth_headers: dict[str, t.Any] = {}
self._auth_params: dict[str, t.Any] = {}
self.auth_headers: dict[str, t.Any] = {}
self.auth_params: dict[str, t.Any] = {}
self.logger: logging.Logger = stream.logger

@property
Expand All @@ -102,24 +107,6 @@
"""
return MappingProxyType(self._config)

@property
def auth_headers(self) -> dict:
"""Get headers.

Returns:
HTTP headers for authentication.
"""
return self._auth_headers or {}

@property
def auth_params(self) -> dict:
"""Get query parameters.

Returns:
URL query parameters for authentication.
"""
return self._auth_params or {}

def authenticate_request(
self,
request: requests.PreparedRequest,
Expand Down Expand Up @@ -177,10 +164,10 @@
auth_headers: Authentication headers.
"""
super().__init__(stream=stream)
if self._auth_headers is None:
self._auth_headers = {}
if self.auth_headers is None:
self.auth_headers = {}

Check warning on line 168 in singer_sdk/authenticators.py

View check run for this annotation

Codecov / codecov/patch

singer_sdk/authenticators.py#L168

Added line #L168 was not covered by tests
if auth_headers:
self._auth_headers.update(auth_headers)
self.auth_headers.update(auth_headers)

Check warning on line 170 in singer_sdk/authenticators.py

View check run for this annotation

Codecov / codecov/patch

singer_sdk/authenticators.py#L170

Added line #L170 was not covered by tests


class APIKeyAuthenticator(APIAuthenticatorBase):
Expand Down Expand Up @@ -218,13 +205,13 @@
raise ValueError(msg)

if location == "header":
if self._auth_headers is None:
self._auth_headers = {}
self._auth_headers.update(auth_credentials)
if self.auth_headers is None:
self.auth_headers = {}
self.auth_headers.update(auth_credentials)

Check warning on line 210 in singer_sdk/authenticators.py

View check run for this annotation

Codecov / codecov/patch

singer_sdk/authenticators.py#L209-L210

Added lines #L209 - L210 were not covered by tests
elif location == "params":
if self._auth_params is None:
self._auth_params = {}
self._auth_params.update(auth_credentials)
if self.auth_params is None:
self.auth_params = {}
self.auth_params.update(auth_credentials)

Check warning on line 214 in singer_sdk/authenticators.py

View check run for this annotation

Codecov / codecov/patch

singer_sdk/authenticators.py#L213-L214

Added lines #L213 - L214 were not covered by tests

@classmethod
def create_for_stream(
Expand Down Expand Up @@ -267,9 +254,9 @@
super().__init__(stream=stream)
auth_credentials = {"Authorization": f"Bearer {token}"}

if self._auth_headers is None:
self._auth_headers = {}
self._auth_headers.update(auth_credentials)
if self.auth_headers is None:
self.auth_headers = {}
self.auth_headers.update(auth_credentials)

Check warning on line 259 in singer_sdk/authenticators.py

View check run for this annotation

Codecov / codecov/patch

singer_sdk/authenticators.py#L258-L259

Added lines #L258 - L259 were not covered by tests

@classmethod
def create_for_stream(
Expand Down Expand Up @@ -326,9 +313,9 @@
auth_token = base64.b64encode(credentials).decode("ascii")
auth_credentials = {"Authorization": f"Basic {auth_token}"}

if self._auth_headers is None:
self._auth_headers = {}
self._auth_headers.update(auth_credentials)
if self.auth_headers is None:
self.auth_headers = {}

Check warning on line 317 in singer_sdk/authenticators.py

View check run for this annotation

Codecov / codecov/patch

singer_sdk/authenticators.py#L317

Added line #L317 was not covered by tests
self.auth_headers.update(auth_credentials)

@classmethod
def create_for_stream(
Expand Down Expand Up @@ -383,20 +370,23 @@
self.last_refreshed: datetime.datetime | None = None
self.expires_in: int | None = None

@property
def auth_headers(self) -> dict:
"""Return a dictionary of auth headers to be applied.
def authenticate_request(
self,
request: requests.PreparedRequest,
) -> requests.PreparedRequest:
"""Authenticate an OAuth request.

These will be merged with any `http_headers` specified in the stream.
Args:
request: A :class:`requests.PreparedRequest` object.

Returns:
HTTP headers for authentication.
The authenticated request object.
"""
if not self.is_token_valid():
self.update_access_token()
result = super().auth_headers
result["Authorization"] = f"Bearer {self.access_token}"
return result

self.auth_headers["Authorization"] = f"Bearer {self.access_token}"
return super().authenticate_request(request)

Check warning on line 389 in singer_sdk/authenticators.py

View check run for this annotation

Codecov / codecov/patch

singer_sdk/authenticators.py#L388-L389

Added lines #L388 - L389 were not covered by tests

@property
def auth_endpoint(self) -> str:
Expand Down
Loading