Repository: meltano/sdk (python)

Issue:
[Feature]: Allow built-in request authentication helpers to be used
### Feature scope

Taps (catalog, state, stream maps, etc.)

### Description

Some of these are nice, and would at least remove from duplication on our side:

- [requests.auth.HTTPBasicAuth(username, password)](https://requests.readthedocs.io/en/latest/_modules/requests/auth/#HTTPBasicAuth)
Attaches HTTP Basic Authentication to the given Request object.

- [requests.auth.HTTPProxyAuth(username, password)](https://requests.readthedocs.io/en/latest/_modules/requests/auth/#HTTPProxyAuth)
Attaches HTTP Proxy Authentication to a given Request object.

- [requests.auth.HTTPDigestAuth(username, password)](https://requests.readthedocs.io/en/latest/_modules/requests/auth/#HTTPDigestAuth)
Attaches HTTP Digest Authentication to the given Request object.

https://requests.readthedocs.io/en/latest/api/#authentication

Custom authenticators are also interesting, and developers would be able to leverage existing auth packages in the wild:

- https://github.com/tedder/requests-aws4auth
- https://github.com/pyauth/requests-http-signature
- https://github.com/Colin-b/requests_auth

https://requests.readthedocs.io/en/latest/user/advanced/#custom-authentication

---

The implementation seems easy enough as we already did most of the work in https://github.com/meltano/sdk/pull/842. We'd only need to add a `__call__` method to the base auth class:

```python
class APIAuthenticatorBase:
    def __call__(self, request):
        return self.authenticate_request(request)
```

and also set the `auth` attribute of the session:

```python
class RESTStream:
    def build_prepared_request(
        self,
        *args: Any,
        **kwargs: Any,
    ) -> requests.PreparedRequest:
        ...
        self.requests_session.auth = self.authenticator
        return self.requests_session.prepare_request(request)
```

Pull request:
feat: Support `requests.auth` authenticators
Closes #1105 

<!-- readthedocs-preview meltano-sdk start -->
----
:books: Documentation preview :books:: https://meltano-sdk--1109.org.readthedocs.build/en/1109/

<!-- readthedocs-preview meltano-sdk end -->

Patch:
diff --git a/docs/_templates/class.rst b/docs/_templates/class.rst
index f1b00ed5..4ebc9be0 100644
--- a/docs/_templates/class.rst
+++ b/docs/_templates/class.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: {{ name }}
     :members:
-    :special-members: __init__
+    :special-members: __init__, __call__
diff --git a/docs/classes/singer_sdk.BatchSink.rst b/docs/classes/singer_sdk.BatchSink.rst
index 22933fca..ea6f276f 100644
--- a/docs/classes/singer_sdk.BatchSink.rst
+++ b/docs/classes/singer_sdk.BatchSink.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: BatchSink
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.GraphQLStream.rst b/docs/classes/singer_sdk.GraphQLStream.rst
index 8dc8d106..41953196 100644
--- a/docs/classes/singer_sdk.GraphQLStream.rst
+++ b/docs/classes/singer_sdk.GraphQLStream.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: GraphQLStream
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.InlineMapper.rst b/docs/classes/singer_sdk.InlineMapper.rst
index a6e8b5e7..1ebc3744 100644
--- a/docs/classes/singer_sdk.InlineMapper.rst
+++ b/docs/classes/singer_sdk.InlineMapper.rst
@@ -7,4 +7,4 @@
     :members:
     :show-inheritance:
     :inherited-members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
diff --git a/docs/classes/singer_sdk.RESTStream.rst b/docs/classes/singer_sdk.RESTStream.rst
index 3486f5cc..9710c630 100644
--- a/docs/classes/singer_sdk.RESTStream.rst
+++ b/docs/classes/singer_sdk.RESTStream.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: RESTStream
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.RecordSink.rst b/docs/classes/singer_sdk.RecordSink.rst
index b1767cf8..1f087079 100644
--- a/docs/classes/singer_sdk.RecordSink.rst
+++ b/docs/classes/singer_sdk.RecordSink.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: RecordSink
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.SQLConnector.rst b/docs/classes/singer_sdk.SQLConnector.rst
index 76fe2672..d4d097f8 100644
--- a/docs/classes/singer_sdk.SQLConnector.rst
+++ b/docs/classes/singer_sdk.SQLConnector.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: SQLConnector
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.SQLSink.rst b/docs/classes/singer_sdk.SQLSink.rst
index 53a2ac4a..60b8b14a 100644
--- a/docs/classes/singer_sdk.SQLSink.rst
+++ b/docs/classes/singer_sdk.SQLSink.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: SQLSink
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.SQLStream.rst b/docs/classes/singer_sdk.SQLStream.rst
index d178a0ed..f7289408 100644
--- a/docs/classes/singer_sdk.SQLStream.rst
+++ b/docs/classes/singer_sdk.SQLStream.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: SQLStream
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.SQLTap.rst b/docs/classes/singer_sdk.SQLTap.rst
index 84433750..c2d9d4cf 100644
--- a/docs/classes/singer_sdk.SQLTap.rst
+++ b/docs/classes/singer_sdk.SQLTap.rst
@@ -7,4 +7,4 @@
     :members:
     :show-inheritance:
     :inherited-members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
diff --git a/docs/classes/singer_sdk.SQLTarget.rst b/docs/classes/singer_sdk.SQLTarget.rst
index 5c16f3f3..e685855d 100644
--- a/docs/classes/singer_sdk.SQLTarget.rst
+++ b/docs/classes/singer_sdk.SQLTarget.rst
@@ -7,4 +7,4 @@
     :members:
     :show-inheritance:
     :inherited-members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
diff --git a/docs/classes/singer_sdk.Sink.rst b/docs/classes/singer_sdk.Sink.rst
index 0f1c6c78..79062c29 100644
--- a/docs/classes/singer_sdk.Sink.rst
+++ b/docs/classes/singer_sdk.Sink.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: Sink
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.Stream.rst b/docs/classes/singer_sdk.Stream.rst
index b56744ba..db028a91 100644
--- a/docs/classes/singer_sdk.Stream.rst
+++ b/docs/classes/singer_sdk.Stream.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: Stream
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.Tap.rst b/docs/classes/singer_sdk.Tap.rst
index cd6702fb..da353658 100644
--- a/docs/classes/singer_sdk.Tap.rst
+++ b/docs/classes/singer_sdk.Tap.rst
@@ -7,4 +7,4 @@
     :members:
     :show-inheritance:
     :inherited-members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
diff --git a/docs/classes/singer_sdk.Target.rst b/docs/classes/singer_sdk.Target.rst
index 15347935..a1b1456d 100644
--- a/docs/classes/singer_sdk.Target.rst
+++ b/docs/classes/singer_sdk.Target.rst
@@ -7,4 +7,4 @@
     :members:
     :show-inheritance:
     :inherited-members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
diff --git a/docs/classes/singer_sdk.authenticators.APIAuthenticatorBase.rst b/docs/classes/singer_sdk.authenticators.APIAuthenticatorBase.rst
index e88561e4..1b3b608c 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__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.authenticators.APIKeyAuthenticator.rst b/docs/classes/singer_sdk.authenticators.APIKeyAuthenticator.rst
index ca48e5d4..28b0d795 100644
--- a/docs/classes/singer_sdk.authenticators.APIKeyAuthenticator.rst
+++ b/docs/classes/singer_sdk.authenticators.APIKeyAuthenticator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: APIKeyAuthenticator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.authenticators.BasicAuthenticator.rst b/docs/classes/singer_sdk.authenticators.BasicAuthenticator.rst
index 1c803715..e944212a 100644
--- a/docs/classes/singer_sdk.authenticators.BasicAuthenticator.rst
+++ b/docs/classes/singer_sdk.authenticators.BasicAuthenticator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: BasicAuthenticator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.authenticators.BearerTokenAuthenticator.rst b/docs/classes/singer_sdk.authenticators.BearerTokenAuthenticator.rst
index 5475fa2b..add92a27 100644
--- a/docs/classes/singer_sdk.authenticators.BearerTokenAuthenticator.rst
+++ b/docs/classes/singer_sdk.authenticators.BearerTokenAuthenticator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: BearerTokenAuthenticator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.authenticators.OAuthAuthenticator.rst b/docs/classes/singer_sdk.authenticators.OAuthAuthenticator.rst
index 1f3b9bff..7600d45d 100644
--- a/docs/classes/singer_sdk.authenticators.OAuthAuthenticator.rst
+++ b/docs/classes/singer_sdk.authenticators.OAuthAuthenticator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: OAuthAuthenticator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.authenticators.OAuthJWTAuthenticator.rst b/docs/classes/singer_sdk.authenticators.OAuthJWTAuthenticator.rst
index 883cf01a..4fa2d3ea 100644
--- a/docs/classes/singer_sdk.authenticators.OAuthJWTAuthenticator.rst
+++ b/docs/classes/singer_sdk.authenticators.OAuthJWTAuthenticator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: OAuthJWTAuthenticator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.authenticators.SimpleAuthenticator.rst b/docs/classes/singer_sdk.authenticators.SimpleAuthenticator.rst
index 40b2859d..e83ef6fa 100644
--- a/docs/classes/singer_sdk.authenticators.SimpleAuthenticator.rst
+++ b/docs/classes/singer_sdk.authenticators.SimpleAuthenticator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: SimpleAuthenticator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.ConfigValidationError.rst b/docs/classes/singer_sdk.exceptions.ConfigValidationError.rst
index db945cdd..79f316f9 100644
--- a/docs/classes/singer_sdk.exceptions.ConfigValidationError.rst
+++ b/docs/classes/singer_sdk.exceptions.ConfigValidationError.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: ConfigValidationError
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.FatalAPIError.rst b/docs/classes/singer_sdk.exceptions.FatalAPIError.rst
index 764ff0bb..954b42f9 100644
--- a/docs/classes/singer_sdk.exceptions.FatalAPIError.rst
+++ b/docs/classes/singer_sdk.exceptions.FatalAPIError.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: FatalAPIError
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.InvalidStreamSortException.rst b/docs/classes/singer_sdk.exceptions.InvalidStreamSortException.rst
index 86a87f25..e9bac24a 100644
--- a/docs/classes/singer_sdk.exceptions.InvalidStreamSortException.rst
+++ b/docs/classes/singer_sdk.exceptions.InvalidStreamSortException.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: InvalidStreamSortException
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.MapExpressionError.rst b/docs/classes/singer_sdk.exceptions.MapExpressionError.rst
index 0b82e5c4..21e54348 100644
--- a/docs/classes/singer_sdk.exceptions.MapExpressionError.rst
+++ b/docs/classes/singer_sdk.exceptions.MapExpressionError.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: MapExpressionError
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.MaxRecordsLimitException.rst b/docs/classes/singer_sdk.exceptions.MaxRecordsLimitException.rst
index c0532248..8492707f 100644
--- a/docs/classes/singer_sdk.exceptions.MaxRecordsLimitException.rst
+++ b/docs/classes/singer_sdk.exceptions.MaxRecordsLimitException.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: MaxRecordsLimitException
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.RecordsWithoutSchemaException.rst b/docs/classes/singer_sdk.exceptions.RecordsWithoutSchemaException.rst
index 4948ee12..10d11cef 100644
--- a/docs/classes/singer_sdk.exceptions.RecordsWithoutSchemaException.rst
+++ b/docs/classes/singer_sdk.exceptions.RecordsWithoutSchemaException.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: RecordsWithoutSchemaException
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.RetriableAPIError.rst b/docs/classes/singer_sdk.exceptions.RetriableAPIError.rst
index 5a0e7f2e..38f5c18e 100644
--- a/docs/classes/singer_sdk.exceptions.RetriableAPIError.rst
+++ b/docs/classes/singer_sdk.exceptions.RetriableAPIError.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: RetriableAPIError
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.StreamMapConfigError.rst b/docs/classes/singer_sdk.exceptions.StreamMapConfigError.rst
index 52f436a0..fc27ddec 100644
--- a/docs/classes/singer_sdk.exceptions.StreamMapConfigError.rst
+++ b/docs/classes/singer_sdk.exceptions.StreamMapConfigError.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: StreamMapConfigError
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.TapStreamConnectionFailure.rst b/docs/classes/singer_sdk.exceptions.TapStreamConnectionFailure.rst
index c172787d..4876e501 100644
--- a/docs/classes/singer_sdk.exceptions.TapStreamConnectionFailure.rst
+++ b/docs/classes/singer_sdk.exceptions.TapStreamConnectionFailure.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: TapStreamConnectionFailure
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.exceptions.TooManyRecordsException.rst b/docs/classes/singer_sdk.exceptions.TooManyRecordsException.rst
index 3ebbb8d9..ab9ddeb8 100644
--- a/docs/classes/singer_sdk.exceptions.TooManyRecordsException.rst
+++ b/docs/classes/singer_sdk.exceptions.TooManyRecordsException.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: TooManyRecordsException
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.BaseAPIPaginator.rst b/docs/classes/singer_sdk.pagination.BaseAPIPaginator.rst
index 38af9ca9..dfbfbc42 100644
--- a/docs/classes/singer_sdk.pagination.BaseAPIPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.BaseAPIPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: BaseAPIPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.BaseHATEOASPaginator.rst b/docs/classes/singer_sdk.pagination.BaseHATEOASPaginator.rst
index a8247e93..1581fb72 100644
--- a/docs/classes/singer_sdk.pagination.BaseHATEOASPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.BaseHATEOASPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: BaseHATEOASPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.BaseOffsetPaginator.rst b/docs/classes/singer_sdk.pagination.BaseOffsetPaginator.rst
index 5e05fb80..1321997c 100644
--- a/docs/classes/singer_sdk.pagination.BaseOffsetPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.BaseOffsetPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: BaseOffsetPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.BasePageNumberPaginator.rst b/docs/classes/singer_sdk.pagination.BasePageNumberPaginator.rst
index 10c52275..15821f06 100644
--- a/docs/classes/singer_sdk.pagination.BasePageNumberPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.BasePageNumberPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: BasePageNumberPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.HeaderLinkPaginator.rst b/docs/classes/singer_sdk.pagination.HeaderLinkPaginator.rst
index b6c5599e..8820562b 100644
--- a/docs/classes/singer_sdk.pagination.HeaderLinkPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.HeaderLinkPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: HeaderLinkPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.JSONPathPaginator.rst b/docs/classes/singer_sdk.pagination.JSONPathPaginator.rst
index 1491ebd9..ded926d7 100644
--- a/docs/classes/singer_sdk.pagination.JSONPathPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.JSONPathPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: JSONPathPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.LegacyPaginatedStreamProtocol.rst b/docs/classes/singer_sdk.pagination.LegacyPaginatedStreamProtocol.rst
index 82054de5..153d8348 100644
--- a/docs/classes/singer_sdk.pagination.LegacyPaginatedStreamProtocol.rst
+++ b/docs/classes/singer_sdk.pagination.LegacyPaginatedStreamProtocol.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: LegacyPaginatedStreamProtocol
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.LegacyStreamPaginator.rst b/docs/classes/singer_sdk.pagination.LegacyStreamPaginator.rst
index 4be63ca6..3510a485 100644
--- a/docs/classes/singer_sdk.pagination.LegacyStreamPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.LegacyStreamPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: LegacyStreamPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.SimpleHeaderPaginator.rst b/docs/classes/singer_sdk.pagination.SimpleHeaderPaginator.rst
index 487c6a16..494b92aa 100644
--- a/docs/classes/singer_sdk.pagination.SimpleHeaderPaginator.rst
+++ b/docs/classes/singer_sdk.pagination.SimpleHeaderPaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: SimpleHeaderPaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/classes/singer_sdk.pagination.SinglePagePaginator.rst b/docs/classes/singer_sdk.pagination.SinglePagePaginator.rst
index 5f9b5011..332e86de 100644
--- a/docs/classes/singer_sdk.pagination.SinglePagePaginator.rst
+++ b/docs/classes/singer_sdk.pagination.SinglePagePaginator.rst
@@ -5,4 +5,4 @@
 
 .. autoclass:: SinglePagePaginator
     :members:
-    :special-members: __init__
\ No newline at end of file
+    :special-members: __init__, __call__
\ No newline at end of file
diff --git a/docs/code_samples.md b/docs/code_samples.md
index e76db4d4..90d9682e 100644
--- a/docs/code_samples.md
+++ b/docs/code_samples.md
@@ -255,6 +255,34 @@ class CachedAuthStream(RESTStream):
         return APIAuthenticatorBase(stream=self)
 ```
 
+### Use one of `requests`'s built-in authenticators
+
+```python
+from requests.auth import HTTPDigestAuth
+from singer_sdk.streams import RESTStream
+
+class DigestAuthStream(RESTStream):
+    """A stream with digest authentication."""
+
+    @property
+    def authenticator(self) -> HTTPDigestAuth:
+        """Stream authenticator."""
+        return HTTPDigestAuth(
+            username=self.config["username"],
+            password=self.config["password"],
+        )
+```
+
+[`HTTPBasicAuth`](https://requests.readthedocs.io/en/latest/api/#requests.auth.HTTPBasicAuth) and
+[`HTTPProxyAuth`](https://requests.readthedocs.io/en/latest/api/#requests.auth.HTTPProxyAuth)
+are also available in `requests.auth`. In addition to `requests.auth` classes, the community
+has published a few packages with custom authenticator classes, which are compatible with the SDK.
+For example:
+
+- [`requests-aws4auth`](https://github.com/tedder/requests-aws4auth): AWS v4 authentication
+- [`requests_auth`](https://github.com/Colin-b/requests_auth): A collection of authenticators
+  for various services and protocols including Azure, Okta and NTLM.
+
 ### Custom response validation
 
 Some APIs deviate from HTTP status codes to report failures. For those cases,
diff --git a/singer_sdk/authenticators.py b/singer_sdk/authenticators.py
index f6bac064..09c0d36f 100644
--- a/singer_sdk/authenticators.py
+++ b/singer_sdk/authenticators.py
@@ -8,6 +8,7 @@ import math
 from datetime import datetime, timedelta
 from types import MappingProxyType
 from typing import Any, Mapping
+from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
 
 import jwt
 import requests
@@ -18,6 +19,30 @@ from singer_sdk.helpers._util import utc_now
 from singer_sdk.streams import Stream as RESTStreamBase
 
 
+def _add_parameters(initial_url: str, extra_parameters: dict) -> str:
+    """Add parameters to an URL and return the new URL.
+
+    Args:
+        initial_url: The URL to add parameters to.
+        extra_parameters: The parameters to add.
+
+    Returns:
+        The new URL with the parameters added.
+    """
+    scheme, netloc, path, query_string, fragment = urlsplit(initial_url)
+    query_params = parse_qs(query_string)
+    query_params.update(
+        {
+            parameter_name: [parameter_value]
+            for parameter_name, parameter_value in extra_parameters.items()
+        }
+    )
+
+    new_query_string = urlencode(query_params, doseq=True)
+
+    return urlunsplit((scheme, netloc, path, new_query_string, fragment))
+
+
 class SingletonMeta(type):
     """A general purpose singleton metaclass."""
 
@@ -94,17 +119,45 @@ class APIAuthenticatorBase:
         """
         return self._auth_params or {}
 
-    def authenticate_request(self, request: requests.Request) -> None:
+    def authenticate_request(
+        self,
+        request: requests.PreparedRequest,
+    ) -> requests.PreparedRequest:
         """Authenticate a request.
 
         Args:
             request: A `request object`_.
 
+        Returns:
+            The authenticated request object.
+
         .. _request object:
-            https://requests.readthedocs.io/en/latest/api/#requests.Request
+            https://requests.readthedocs.io/en/latest/api/#requests.PreparedRequest
         """
         request.headers.update(self.auth_headers)
-        request.params.update(self.auth_params)
+
+        if request.url:
+            request.url = _add_parameters(request.url, self.auth_params)
+
+        return request
+
+    def __call__(self, r: requests.PreparedRequest) -> requests.PreparedRequest:
+        """Authenticate a request.
+
+        Calls
+        :meth:`~singer_sdk.authenticators.APIAuthenticatorBase.authenticate_request`
+        and returns the result.
+
+        Args:
+            r: A `request object`_.
+
+        Returns:
+            The authenticated request object.
+
+        .. _request object:
+            https://requests.readthedocs.io/en/latest/api/#requests.PreparedRequest
+        """
+        return self.authenticate_request(r)
 
 
 class SimpleAuthenticator(APIAuthenticatorBase):
diff --git a/singer_sdk/streams/rest.py b/singer_sdk/streams/rest.py
index db2f33d6..ee0a0c47 100644
--- a/singer_sdk/streams/rest.py
+++ b/singer_sdk/streams/rest.py
@@ -5,6 +5,7 @@ from __future__ import annotations
 import abc
 import copy
 import logging
+import sys
 from datetime import datetime
 from typing import TYPE_CHECKING, Any, Callable, Generator, Generic, Iterable, TypeVar
 from urllib.parse import urlparse
@@ -15,7 +16,7 @@ import requests
 
 from singer_sdk import metrics
 from singer_sdk._singerlib import Schema
-from singer_sdk.authenticators import APIAuthenticatorBase, SimpleAuthenticator
+from singer_sdk.authenticators import SimpleAuthenticator
 from singer_sdk.exceptions import FatalAPIError, RetriableAPIError
 from singer_sdk.helpers.jsonpath import extract_jsonpath
 from singer_sdk.pagination import (
@@ -27,6 +28,11 @@ from singer_sdk.pagination import (
 from singer_sdk.plugin_base import PluginBase as TapBaseClass
 from singer_sdk.streams.core import Stream
 
+if sys.version_info >= (3, 10):
+    from typing import TypeAlias
+else:
+    from typing_extensions import TypeAlias
+
 if TYPE_CHECKING:
     from backoff.types import Details
 
@@ -34,6 +40,7 @@ DEFAULT_PAGE_SIZE = 1000
 DEFAULT_REQUEST_TIMEOUT = 300  # 5 minutes
 
 _TToken = TypeVar("_TToken")
+_Auth: TypeAlias = Callable[[requests.PreparedRequest], requests.PreparedRequest]
 
 
 class RESTStream(Stream, Generic[_TToken], metaclass=abc.ABCMeta):
@@ -294,11 +301,7 @@ class RESTStream(Stream, Generic[_TToken], metaclass=abc.ABCMeta):
             https://requests.readthedocs.io/en/latest/api/#requests.Request
         """
         request = requests.Request(*args, **kwargs)
-
-        if self.authenticator:
-            authenticator = self.authenticator
-            authenticator.authenticate_request(request)
-
+        self.requests_session.auth = self.authenticator
         return self.requests_session.prepare_request(request)
 
     def prepare_request(
@@ -559,7 +562,7 @@ class RESTStream(Stream, Generic[_TToken], metaclass=abc.ABCMeta):
     # Abstract methods:
 
     @property
-    def authenticator(self) -> APIAuthenticatorBase | None:
+    def authenticator(self) -> _Auth:
         """Return or set the authenticator for managing HTTP auth headers.
 
         If an authenticator is not specified, REST-based taps will simply pass


Test patch:
diff --git a/tests/core/rest/conftest.py b/tests/core/rest/conftest.py
index 0ee924f3..8a09e302 100644
--- a/tests/core/rest/conftest.py
+++ b/tests/core/rest/conftest.py
@@ -2,6 +2,7 @@
 
 import pytest
 from memoization.memoization import cached
+from requests.auth import HTTPProxyAuth
 
 from singer_sdk.authenticators import APIAuthenticatorBase, SingletonMeta
 from singer_sdk.streams import RESTStream
@@ -51,6 +52,15 @@ class CachedAuthStream(SimpleRESTStream):
         return NaiveAuthenticator(stream=self)
 
 
+class ProxyAuthStream(SimpleRESTStream):
+    """A stream with digest authentication."""
+
+    @property
+    def authenticator(self):
+        """Stream authenticator."""
+        return HTTPProxyAuth("username", "password")
+
+
 class SimpleTap(Tap):
     """A REST tap for testing."""
 
@@ -65,6 +75,7 @@ class SimpleTap(Tap):
             SingletonAuthStream(self, name="reused_single_auth_stream"),
             CachedAuthStream(self, name="cached_auth_stream"),
             CachedAuthStream(self, name="other_cached_auth_stream"),
+            ProxyAuthStream(self, name="proxy_auth_stream"),
         ]
 
 
diff --git a/tests/core/rest/test_authenticators.py b/tests/core/rest/test_authenticators.py
index 9d18a772..3ca03861 100644
--- a/tests/core/rest/test_authenticators.py
+++ b/tests/core/rest/test_authenticators.py
@@ -16,6 +16,7 @@ from cryptography.hazmat.primitives.serialization import (
     PrivateFormat,
     PublicFormat,
 )
+from requests.auth import HTTPProxyAuth, _basic_auth_str
 
 from singer_sdk.authenticators import OAuthAuthenticator, OAuthJWTAuthenticator
 from singer_sdk.streams import RESTStream
@@ -182,3 +183,12 @@ def test_oauth_jwt_authenticator_payload(
     token = payload["assertion"]
 
     assert jwt.decode(token, public_key_string, algorithms=["RS256"]) == body
+
+
+def test_requests_library_auth(rest_tap: Tap):
+    """Validate that a requests.auth object can be used as an authenticator."""
+    stream: RESTStream = rest_tap.streams["proxy_auth_stream"]
+    r = stream.prepare_request(None, None)
+
+    assert isinstance(stream.authenticator, HTTPProxyAuth)
+    assert r.headers["Proxy-Authorization"] == _basic_auth_str("username", "password")