PYCO-92: Add JWT authenticator#12
Conversation
There was a problem hiding this comment.
Pull request overview
Adds JWT-based authentication and runtime credential rotation to the Couchbase Analytics Python SDK, shifting HTTP auth to a request-time header injection model so credential updates take effect without rebuilding the underlying httpx client.
Changes:
- Introduces
Credential.from_jwt()andCredentialType, withCredentialprecomputing anAuthorizationheader for both password and JWT credentials. - Replaces
httpx.BasicAuthusage withDynamicCredentialAuth, which reads the current credential from_ConnectionDetailson each request. - Adds sync/async
Cluster.set_credential()APIs plus adapter support to rotate credentials at runtime (rejecting credential-type switches), and adds unit tests for the new behavior.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| couchbase_analytics/common/credential.py | Adds JWT credential support, credential typing, and precomputed Authorization header generation. |
| couchbase_analytics/protocol/_core/auth.py | New httpx.Auth implementation that injects the current credential’s Authorization header at request time. |
| couchbase_analytics/protocol/_core/client_adapter.py | Switches from BasicAuth to DynamicCredentialAuth; adds runtime credential update method. |
| couchbase_analytics/protocol/connection.py | Stores Credential directly in _ConnectionDetails (instead of a username/password tuple). |
| couchbase_analytics/protocol/cluster.py | Adds Cluster.set_credential() (protocol layer) delegating to the adapter. |
| couchbase_analytics/protocol/cluster.pyi | Exposes set_credential() in protocol cluster typing. |
| couchbase_analytics/cluster.py | Adds public sync Cluster.set_credential() API and documentation. |
| couchbase_analytics/cluster.pyi | Exposes set_credential() in public sync cluster typing. |
| acouchbase_analytics/protocol/_core/client_adapter.py | Mirrors sync adapter: uses DynamicCredentialAuth; adds async credential update method. |
| acouchbase_analytics/protocol/cluster.py | Adds async protocol set_credential() delegating to the adapter. |
| acouchbase_analytics/protocol/cluster.pyi | Exposes async set_credential() in protocol typing. |
| acouchbase_analytics/cluster.py | Adds public async Cluster.set_credential() API and documentation. |
| acouchbase_analytics/cluster.pyi | Exposes set_credential() in public async cluster typing. |
| couchbase_analytics/tests/credential_t.py | New sync unit tests covering JWT credentials, header formatting/redaction, dynamic auth, and rotation/type-switch rejection. |
| acouchbase_analytics/tests/credential_t.py | New async unit tests covering the same behaviors for async adapter/cluster. |
| conftest.py | Registers the new credential unit test suites in the unit test list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 33 out of 33 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 34 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
e6d44eb to
62e1a19
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
couchbase_analytics/common/credential.py:162
Credential.__repr__renders JWT credentials asCredential(token=****), but the public constructor parameter and factory method usejwt_token/from_jwt. Using a different label inreprmakes debugging harder (it looks like a different API). Consider changing this toCredential(jwt_token=****)(orCredential(jwt=****)) to match the public naming.
def __repr__(self) -> str:
if self._kind == 'password':
return f'Credential(username={self._username!r}, password=****)'
return 'Credential(token=****)'
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
# Conflicts: # acouchbase_analytics/cluster.py # acouchbase_analytics/cluster.pyi # acouchbase_analytics/protocol/_core/client_adapter.py # couchbase_analytics/cluster.py # couchbase_analytics/cluster.pyi # couchbase_analytics/protocol/_core/client_adapter.py # couchbase_analytics/protocol/cluster.pyi
The test adapters subclass _ClientAdapter / _AsyncClientAdapter and override __init__ to wrap an existing adapter, copying its private attributes. After the _CredentialHolder refactor, the new _credential_holder attribute also needs to be copied or test_server tests fail with AttributeError.
Credential.from_jwt(token); sendsAuthorization: Bearer <jwt>on every HTTP request.BasicAuthwith aDynamicCredentialAuthflow that reads the current credential at request time, so credential rotation takes effect without rebuilding the HTTP client.Cluster.set_credential()(sync + async) to rotate credentials at runtime. Switching credential types at runtime is rejected.Authorizationheader onCredentialconstruction so per-request dispatch is a cheap attribute read.