From 7192febc5ce1f5fcc2a9e2720bedbafacb9d61e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez-Mondrag=C3=B3n?= Date: Fri, 2 Feb 2024 16:06:13 -0600 Subject: [PATCH] refactor: `Deprecate singer_sdk.authenticators.BasicAuthenticator` in favor of `requests.auth.HTTPBasicAuth` Closes https://github.com/meltano/sdk/issues/2040 --- .pre-commit-config.yaml | 4 ++-- .../{{cookiecutter.library_name}}/rest-client.py | 7 +++---- .../singer_sdk.authenticators.APIAuthenticatorBase.rst | 2 +- pyproject.toml | 8 ++++---- singer_sdk/authenticators.py | 5 ++++- singer_sdk/helpers/_flattening.py | 2 +- singer_sdk/pagination.py | 1 - singer_sdk/streams/core.py | 6 +++--- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0501629fb2..345a262e3e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,14 +42,14 @@ repos: )$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.27.3 + rev: 0.27.4 hooks: - id: check-dependabot - id: check-github-workflows - id: check-readthedocs - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.14 + rev: v0.2.0 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix, --show-fixes] diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py index 26c1447c92..16ad9d23f0 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/{{cookiecutter.library_name}}/rest-client.py @@ -22,7 +22,7 @@ from singer_sdk.streams import {{ cookiecutter.stream_type }}Stream {% elif cookiecutter.auth_method == "Basic Auth" -%} -from singer_sdk.authenticators import BasicAuthenticator +from requests.auth import HTTPBasicAuth from singer_sdk.helpers.jsonpath import extract_jsonpath from singer_sdk.pagination import BaseAPIPaginator # noqa: TCH002 from singer_sdk.streams import {{ cookiecutter.stream_type }}Stream @@ -110,14 +110,13 @@ def authenticator(self) -> BearerTokenAuthenticator: {%- elif cookiecutter.auth_method == "Basic Auth" %} @property - def authenticator(self) -> BasicAuthenticator: + def authenticator(self) -> HTTPBasicAuth: """Return a new authenticator object. Returns: An authenticator instance. """ - return BasicAuthenticator.create_for_stream( - self, + return HTTPBasicAuth( username=self.config.get("username", ""), password=self.config.get("password", ""), ) diff --git a/docs/classes/singer_sdk.authenticators.APIAuthenticatorBase.rst b/docs/classes/singer_sdk.authenticators.APIAuthenticatorBase.rst index 70e9a127fb..1b3b608c5a 100644 --- a/docs/classes/singer_sdk.authenticators.APIAuthenticatorBase.rst +++ b/docs/classes/singer_sdk.authenticators.APIAuthenticatorBase.rst @@ -5,4 +5,4 @@ .. autoclass:: APIAuthenticatorBase :members: - :special-members: __init__, __call__ + :special-members: __init__, __call__ \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 2da0373225..e214d12c7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -247,6 +247,10 @@ jsonl = "singer_sdk.contrib.batch_encoder_jsonl:JSONLinesBatcher" parquet = "singer_sdk.contrib.batch_encoder_parquet:ParquetBatcher" [tool.ruff] +extend-exclude = [ + "cookiecutter/*", + "*simpleeval*", +] line-length = 88 src = ["samples", "singer_sdk", "tests"] target-version = "py38" @@ -255,10 +259,6 @@ target-version = "py38" docstring-code-format = true [tool.ruff.lint] -exclude = [ - "cookiecutter/*", - "*simpleeval*", -] ignore = [ "ANN101", # Missing type annotation for `self` in method "ANN102", # Missing type annotation for `cls` in class method diff --git a/singer_sdk/authenticators.py b/singer_sdk/authenticators.py index 82e0556bc3..70004efbea 100644 --- a/singer_sdk/authenticators.py +++ b/singer_sdk/authenticators.py @@ -297,7 +297,10 @@ def create_for_stream( class BasicAuthenticator(APIAuthenticatorBase): """Implements basic authentication for REST Streams. - This Authenticator implements basic authentication by concatinating a + .. deprecated:: 0.36.0 + Use :class:`requests.auth.HTTPBasicAuth` instead. + + This Authenticator implements basic authentication by concatenating a username and password then base64 encoding the string. The resulting token will be merged with any HTTP headers specified on the stream. """ diff --git a/singer_sdk/helpers/_flattening.py b/singer_sdk/helpers/_flattening.py index 83cda211d2..1abf5369fb 100644 --- a/singer_sdk/helpers/_flattening.py +++ b/singer_sdk/helpers/_flattening.py @@ -33,7 +33,7 @@ def get_flattening_options( Returns: A new FlatteningOptions object or None if flattening is disabled. """ - if "flattening_enabled" in plugin_config and plugin_config["flattening_enabled"]: + if plugin_config.get("flattening_enabled", False): return FlatteningOptions(max_level=int(plugin_config["flattening_max_depth"])) return None diff --git a/singer_sdk/pagination.py b/singer_sdk/pagination.py index 82e02d6b77..5dc36575d3 100644 --- a/singer_sdk/pagination.py +++ b/singer_sdk/pagination.py @@ -387,7 +387,6 @@ def get_next_page_token( response: API response object. previous_token: Previous page token. """ - ... # pragma: no cover class LegacyStreamPaginator( diff --git a/singer_sdk/streams/core.py b/singer_sdk/streams/core.py index 064b78361a..5ef631bf11 100644 --- a/singer_sdk/streams/core.py +++ b/singer_sdk/streams/core.py @@ -1072,7 +1072,6 @@ def _sync_records( # noqa: C901 record_counter.context = context_element timer.context = context_element - partition_record_index = 0 current_context = context_element or None state = self.get_context_state(current_context) state_partition_context = self._get_state_partition_context( @@ -1083,7 +1082,9 @@ def _sync_records( # noqa: C901 None if current_context is None else copy.copy(current_context) ) - for record_result in self.get_records(current_context): + for partition_record_index, record_result in enumerate( + self.get_records(current_context), + ): self._check_max_record_limit(current_record_index=record_index) if isinstance(record_result, tuple): @@ -1123,7 +1124,6 @@ def _sync_records( # noqa: C901 yield record record_index += 1 - partition_record_index += 1 if current_context == state_partition_context: # Finalize per-partition state only if 1:1 with context