Tags: annotell/kognic-auth-python
Tags
fix: retry the OAuth token fetch in both API clients (#103) * fix: retry the OAuth token fetch in both API clients The token endpoint is fetched with POST, so it stopped being retried once POST was excluded from the retry policy. A single transient 502 from the auth server would then fail every caller holding a client, with no second attempt. Unlike an ordinary POST the token endpoint is safe to replay: a client credentials grant leaves no state behind beyond the token it returns. Both clients now retry it on 502/503/504, the async one through the existing request wrapper and the sync one through a retry adapter mounted on the OAuth session, which never had one. Caller-issued POST and PATCH are unaffected and still surface the first failure. * fix: scope the token fetch retry to the token endpoint The retry adapter was mounted per scheme on the OAuth session. authlib makes that session the object RequestsAuthSession.session hands back, so a caller issuing their own POST through it had the request replayed. Mount it on the token URL instead, which requests selects by longest matching prefix. Turn off raise_on_status as well, so an exhausted retry surfaces the auth server's own response instead of a urllib3 RetryError that discards the error body. * Desplop comments
fix(cli): forward environment scopes when requesting token in kog (#85) * fix(cli): forward environment scopes when requesting token in kog kog never passed the resolved environment's scopes to make_token_provider, so tokens were minted with the client's full default grant even when the environment was configured with restricted scopes (e.g. api:read). This made read-locked environments write-capable. Pass scopes=env.scopes, matching get_access_token and BaseApiClient.from_env. env.scopes defaults to [], which make_token_provider treats as "no scopes", so behavior is unchanged for environments that don't set the field. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix(cli): forward env scopes as `env.scopes or None` to preserve creds-file fallback Passing the raw env.scopes (which defaults to [] when unset) suppressed the credentials-file scope fallback in RequestsAuthSession, which is guarded on `scopes is None`, not falsiness. For an environment without configured scopes but a credentials file that declares scopes, this widened the grant to the full default instead of the creds-file scopes. Forward `env.scopes or None` so an unset environment falls through to the creds-file fallback exactly as before, matching get_access_token and BaseApiClient.from_env. Add behavioral tests in test_requests_auth.py locking in the None-vs-empty-list contract at the make_token_provider level. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * test(auth): cover multi-scope space-join in make_token_provider Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Bump pygments from 2.19.2 to 2.20.0 (#68) Bumps [pygments](https://github.com/pygments/pygments) from 2.19.2 to 2.20.0. - [Release notes](https://github.com/pygments/pygments/releases) - [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES) - [Commits](pygments/pygments@2.19.2...2.20.0) --- updated-dependencies: - dependency-name: pygments dependency-version: 2.20.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Add --decode flag to get-access-token CLI (#66) * Add --decode flag to get-access-token CLI to unpack JWT payload Co-Authored-By: Claude Opus 4.6 <[email protected]> * Include header, payload, and signature in --decode output Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
Add created/expires fields to ApiCredentials with expiry check (#62) * Add created/expires fields to ApiCredentials with expiry check ApiCredentials now carries optional created and expires fields as timezone-aware datetimes, parsed from the ISO 8601 strings in the credentials JSON (including Z suffix and nanosecond precision). Expiry is checked when an auth session is constructed (_check_expiry called after _resolve_credentials in RequestsAuthSession and HttpxAuthAsyncClient), so loading/storing credentials never fails due to expiry — only actually using them does. Keyring storage serialises the datetime fields back to ISO strings via .isoformat(). Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * Fix test mocks and ruff exclude after credentials refactor Update test_base_client_sync.py to patch _resolve_credentials (renamed from resolve_credentials) and return ApiCredentials instead of tuples. Exclude generated _version.py from ruff. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --------- Co-authored-by: Claude Sonnet 4.6 <[email protected]>
Refactor cred mgmt (#61) * resolve full ApiCredential, with anonymous credentials when no credentials file * auth config fixes * fix * Fix resolve_credentials ignoring explicit credentials and add keyring mock to test Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --------- Co-authored-by: Claude Sonnet 4.6 <[email protected]>
PreviousNext