Skip to content

Omit Authorization header when api_key is empty - #1

Open
devin-ai-integration[bot] wants to merge 2 commits into
upstream-mainfrom
devin/1786641698-optional-auth
Open

Omit Authorization header when api_key is empty#1
devin-ai-integration[bot] wants to merge 2 commits into
upstream-mainfrom
devin/1786641698-optional-auth

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

cohere.Client(api_key="") (and ClientV2/AsyncClient/AsyncClientV2) now sends no Authorization header, so the client can point at a proxy / self-hosted deployment that performs its own auth. A non-empty key — including a callable/async token supplier — behaves exactly as before.

No generated file changes: the patch lives entirely in the already-handwritten, already-.fernignored src/cohere/overrides.py, which wraps the generated header builders at import time:

def patched_get_headers(self):
    headers = get_headers(self)
    if not self._get_token():          # covers str and callable tokens
        headers.pop("Authorization", None)
    return headers

The async variant keys off the rendered value ("Bearer ") because async_get_headers re-sets the header from self._async_token() after get_headers() runs. The patch is idempotent (guarded by BaseClientWrapper._omits_empty_authorization) since run_overrides() can be invoked more than once.

Note on the base branch: this targets upstream-main, a branch I pushed at current cohere-ai/cohere-python main (050f9c0), because this fork's main is from 2024 and conflicts with upstream — that keeps the diff to just these two files. Happy to re-open against a fresh fern-demo/cohere-python fork.

Verification (tests/test_optional_auth.py, header inspection only, no live calls): empty key omits the header on sync/async v1/v2 and for api_key=lambda: ""; api_key="n/a" still yields Bearer n/a. pytest tests/test_optional_auth.py tests/test_client_init.py → 4 passed, 1 skipped (boto3); mypy src/cohere/overrides.py clean. Reverting the empty-token check fails exactly the 2 relevant tests.

Link to Devin session: https://app.devin.ai/sessions/56fc23472ad04e0cbadf0e7f45d0893b

@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

patched_get_headers called _get_token() a second time, after get_headers()
had already called it. For the documented callable api_key form this invoked
the supplier twice per request, and a supplier whose value changed between the
two calls produced the wrong header: returning "real-token" then "" stripped
the Authorization header despite a valid token, and the reverse sent
"Bearer " while a valid token was available. Both yield a 401.

Inspect the header get_headers() already built instead, matching what
patched_async_get_headers has been doing.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant