Last reviewed: November 3, 2026 (Asia/Shanghai).

Direct answer

Pass an explicit bearer authentication handler through Python Requests’ auth= argument when sending CometAPI calls. A manually supplied Authorization header can be replaced by credentials discovered in a worker’s .netrc file. The Requests authentication guide documents that matching netrc credentials override raw authentication headers and cause HTTP Basic authentication.

This can explain why the same application code prepares different authorization under a developer shell and a service account. Verify the prepared request offline before treating an authentication failure as a provider outage. auth=None does not disable lookup, and an empty tuple is also insufficient in the versions checked below.

Setting session.trust_env = False disables netrc lookup too, but also changes environment-derived proxy and CA configuration. Prefer a request-specific bearer handler when the worker should retain its existing approved environment policy. Choose the broader switch only after reviewing those transport dependencies.

Who this is for

This guide is for maintainers of synchronous Python Requests adapters calling CometAPI, especially workers launched under different users or container images. It addresses authentication precedence during request preparation. For concurrent HTTPX handlers whose shared headers mix account identities, use the separate request-local credential guide .

The reproductions use dummy credentials and perform no network sends. They establish local client behavior, rather than a CometAPI incident, current account validity, or provider response status.

Key takeaways

  • Inspect the final prepared authentication behavior instead of relying on the header written in application code.
  • Supply a bearer AuthBase handler on each request so session authentication and netrc discovery cannot silently choose Basic authentication during preparation.
  • Keep redirects disabled; authentication can be rebuilt when redirects are followed.
  • Review proxy and CA inheritance before using trust_env=False as the remedy.
  • Reproduce the problem with a temporary netrc fixture, without reading or printing production credentials.

Contract details to verify

The CometAPI Chat Completions reference documents POST /v1/chat/completions at api.cometapi.com, bearer authentication, and required model and messages fields. A matching hostname in a netrc file is an input to Requests’ local authentication selection; it is not part of this API contract.

Requests searches ~/.netrc, ~/_netrc, or the path selected by the NETRC environment variable. That makes the worker’s actual launch identity and environment relevant. A shell running under another account may not reproduce the service’s preparation behavior. Inventory configuration presence and protected file references without dumping file contents or the process environment.

The maintained Requests session implementation shows the decision in Session.prepare_request: netrc lookup occurs when trust_env is true and neither request authentication nor session authentication is truthy. Requests then prepares the merged headers with the selected authentication. Consequently, setting a bearer header earlier does not ensure that it survives preparation.

Request or session choiceEffect at preparation
Raw bearer header, matching netrc entry, no explicit authNetrc Basic authentication can replace the header
Raw header with auth=NoneLookup remains eligible when session auth is absent
Raw header with auth=()The empty tuple is falsy and does not suppress lookup in the checked versions
Explicit bearer AuthBase handler in auth=The handler supplies bearer authentication and takes precedence over session auth
trust_env=False, no session authNetrc discovery is skipped; separately review the transport configuration

An explicit session authentication setting remains active when environment trust is disabled. Likewise, auth=(username, password) requests Basic authentication; it is not a bearer-token container. Keep the authentication mechanism visible at the call site.

Attach bearer authentication explicitly

The Requests Advanced Usage guide documents custom AuthBase implementations whose call method modifies the request before dispatch. Save this focused adapter example as bearer_boundary.py:

import requests
from requests.auth import AuthBase

CHAT_URL = "https://api.cometapi.com/v1/chat/completions"


class BearerAuth(AuthBase):
    def __init__(self, token):
        if (
            not isinstance(token, str)
            or not token
            or not token.isascii()
            or any(ch.isspace() or not ch.isprintable() for ch in token)
        ):
            raise ValueError("invalid_api_credential")
        self._token = token

    def __call__(self, request):
        request.headers["Authorization"] = f"Bearer {self._token}"
        return request


def post_chat(session, *, token, model, prompt):
    with session.post(
        CHAT_URL,
        auth=BearerAuth(token),
        json={
            "model": model,
            "messages": [{"role": "user", "content": prompt}],
            "stream": False,
        },
        allow_redirects=False,
        timeout=(5, 20),
    ) as response:
        if 300 <= response.status_code < 400:
            raise RuntimeError("unexpected_api_redirect")
        response.raise_for_status()
        return response.json()

Resolve the credential from the authorized server-side binding and create the handler for that attempt. The format check rejects empty or unsafe header values; it does not validate the credential with CometAPI. Keep the handler, its attributes, and complete prepared requests out of logs.

Supply a validated prompt and a model approved for the route. Use a dedicated session with stable transport settings and close it at its owning worker’s shutdown. Request authentication does not remove unrelated session cookies, headers, parameters, hooks, or custom adapter behavior. Review those inputs separately.

The helper demonstrates the authentication boundary. Its timeout tuple specifies connect and read limits, not a total operation deadline. The surrounding adapter still needs bounded response reads, completion-envelope validation, an end-to-end deadline, and controlled retry decisions before returning output to a user.

Redirect control matters here: Requests’ session implementation can apply netrc authentication again while rebuilding authorization after a redirect. The helper rejects a 3xx without following it. Preserve the site’s zero-hop redirect policy through wrappers and proxies as well.

Happy-path operator workflow

Trace the actual worker path from secret resolution to Session.post. Record the Requests version, application revision, credential-version reference, and authentication-handler type. Check for inherited Session.auth, wrappers that replace auth=, and another HTTP client constructed inside a retry branch.

Add explicit request authentication, then run the offline fixture below under the deployed library version. Require the intended dummy bearer value to survive both a matching netrc entry and a conflicting session-auth setting. Those checks test precedence without exposing any real credential.

Next, exercise the deployed adapter against a controlled upstream recorder using synthetic inputs. Assert the selected authentication scheme and dummy marker at that boundary. Check one successful response and one redirect response, requiring exactly one send in each case. This catches wrappers that bypass the helper or follow redirects independently.

After client checks pass, perform a small, separately authorized readiness call using the approved credential and model. Apply the site’s authorization and endpoint checks against the current configuration. Require usable Chat Completions output in addition to transport success; the offline fixture cannot establish account readiness.

Error-path operator workflow

If a worker unexpectedly prepares Basic authentication, hold that route and investigate local precedence. Compare the launch identity, netrc configuration presence, session-auth type, handler path, and code revision. Do not print the discovered login, password, bearer token, raw request, or raw exception object. Basic authentication’s encoded credential value also belongs outside ordinary diagnostics.

Repair preparation before deciding whether another attempt is appropriate. An authentication error is not evidence that a fallback route is healthy. If an earlier request was sent, retain its dispatch state and follow the operation’s existing deadline, replay, and attempt policy; an offline fix does not establish what the earlier recipient processed.

If choosing trust_env=False, first inventory required environment proxies and custom CA bundles. The Requests session implementation gates proxy discovery and REQUESTS_CA_BUNDLE/CURL_CA_BUNDLE selection on this setting. Advanced Usage documents those proxy and certificate inputs. Supply the reviewed equivalents explicitly, retain certificate verification, and verify the actual egress path before rollout. Do not bypass a required proxy or use verify=False to make the authentication change appear successful.

Verify precedence without sending a request

Save this as netrc_probe.py beside the helper. Run python3 netrc_probe.py with Requests installed. It temporarily selects a fixture using NETRC, restores the previous environment afterward, and only calls Session.prepare_request. Use a separate test process, since environment variables are process-wide.

import base64
import os
import tempfile
from pathlib import Path
from unittest.mock import patch

import requests
from bearer_boundary import CHAT_URL, BearerAuth

TOKEN = "dummy-api-key"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
EXPECTED_BASIC = "Basic " + base64.b64encode(
    b"fixture-user:fixture-pass"
).decode("ascii")


def prepared_header(session, **options):
    request = requests.Request("POST", CHAT_URL, headers=HEADERS, **options)
    return session.prepare_request(request).headers["Authorization"]


with tempfile.TemporaryDirectory() as directory:
    netrc = Path(directory) / "fixture.netrc"
    netrc.write_text(
        "machine api.cometapi.com login fixture-user password fixture-pass\n",
        encoding="ascii",
    )
    netrc.chmod(0o600)
    with patch.dict(os.environ, {"NETRC": str(netrc)}):
        with requests.Session() as session:
            assert prepared_header(session) == EXPECTED_BASIC
            assert prepared_header(session, auth=None) == EXPECTED_BASIC
            assert prepared_header(session, auth=()) == EXPECTED_BASIC
            assert prepared_header(session, auth=BearerAuth(TOKEN)) == HEADERS["Authorization"]
            session.auth = ("other-fixture", "other-password")
            assert prepared_header(session, auth=BearerAuth(TOKEN)) == HEADERS["Authorization"]
        with requests.Session() as session:
            session.trust_env = False
            assert prepared_header(session) == HEADERS["Authorization"]

for invalid in ("", "has space", "bad\nvalue", None, "bad\x00value"):
    try:
        BearerAuth(invalid)
    except ValueError:
        pass
    else:
        raise AssertionError("invalid credential accepted")

print(f"Requests {requests.__version__}: all preparation assertions passed")

On November 3, 2026, local runs with Python 3.12.3 and Requests 2.31.0 and 2.34.2 passed all shown assertions. The unprotected header became fixture Basic authentication; the explicit handler retained the dummy bearer value, including with conflicting session auth. Invalid credential inputs were rejected.

A separate in-memory adapter check on both versions exercised the helper with synthetic 200, 302, and 401 responses. Each case made one intercepted send with the intended dummy bearer header; 302 raised the routing exception and 401 raised HTTPError. These observations cover the shown local adapter. They do not test DNS, TLS, network proxies, live keys, or provider processing.

Use Session.prepare_request in this regression: it exercises session merging and netrc selection. Calling Request.prepare() directly skips that session preparation path and can miss the defect. Keep the conflicting-netrc fixture in the adapter’s upgrade checks.

Failure modes

The bearer header is added again in application code. A later preparation step can still replace it. Put the mechanism in auth= and check the prepared result with dummy values.

auth=None is treated as an opt-out. With no session authentication, it leaves netrc lookup eligible. Empty tuples are also insufficient in the checked versions.

Environment inheritance is disabled without transport review. Authentication looks correct, but a required proxy or CA override disappears. Preserve the approved routing and trust configuration deliberately.

A direct preparation test passes while the worker fails. The test did not use the real session path, wrapper, or library version. Exercise the owning adapter and its final synthetic request.

A fallback branch reconstructs an unprotected request. The main path uses explicit bearer auth while recovery returns to raw headers. Apply the same authentication contract to every approved attempt.

FAQ

Does a bearer header automatically suppress netrc lookup?

No. Requests documents that netrc credentials can override raw headers. The lookup condition concerns explicit authentication and environment trust.

Must I disable all environment inheritance?

No. An explicit request bearer handler addresses preparation precedence while leaving the existing environment policy available. Audit redirects, hooks, and custom adapters separately.

Does this require deleting a worker’s netrc file?

No. Establish the API route’s authentication explicitly. Shared files can serve other tools; use a temporary fixture to reproduce the behavior without changing those tools’ configuration.

Reader next step

Choose one Requests adapter and run the matching-netrc fixture against its deployed version. Add explicit bearer authentication, verify the wrapper preserves it, and retain a controlled one-send redirect check. Then Start with CometAPI using the reviewed server-side credential binding and a bounded readiness request.

Sources checked

  • Requests: Authentication — checked November 3, 2026. Documents netrc discovery, precedence over raw authentication headers, Basic authentication, and disabling lookup with trust_env=False.
  • Requests: Advanced Usage — checked November 3, 2026. Documents custom authentication, session preparation, proxy and CA settings, and timeout behavior.
  • Requests: requests.sessions implementation — checked November 3, 2026. Supports the preparation condition, session-auth merging, redirect authentication rebuilding, and environment proxy/CA selection.
  • CometAPI: Create a chat completion — checked November 3, 2026. Supports the API destination, bearer authentication, and required Chat Completions request fields.

These maintained primary references support an evergreen client configuration problem. The Requests documentation identified itself as version 2.34.2 when fetched. The diagnostic workflow and rollout criteria are engineering recommendations; the local observations are limited to the stated Python and Requests versions.