Skip to content

fix: Report a distinct User-Agent for the async client - #516

Merged
jsonbailey merged 1 commit into
mainfrom
jb/sdk-2658/async-user-agent
Sep 4, 2026
Merged

fix: Report a distinct User-Agent for the async client#516
jsonbailey merged 1 commit into
mainfrom
jb/sdk-2658/async-user-agent

Conversation

@jsonbailey

@jsonbailey jsonbailey commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Overview

The async client (AsyncLDClient) shipped reusing the synchronous PythonClient/<version> User-Agent, so LaunchDarkly cannot distinguish async traffic from sync. Because sync and async ship in the same package, the User-Agent token is the signal that tells them apart.

This adds a distinct async token PythonAsyncClient and threads it through every async request path.

Changes

  • impl/http.py: add SYNC_USER_AGENT / ASYNC_USER_AGENT constants; _base_headers(config, user_agent=SYNC_USER_AGENT).
  • impl/util.py: _headers(config, user_agent=SYNC_USER_AGENT) passes the token through.
  • Async request sites now pass ASYNC_USER_AGENT:
    • impl/aio/transport.pyAsyncSSEFactory streaming headers
    • impl/datasource/async_feature_requester.py
    • impl/datasourcev2/async_polling.py
    • impl/events/async_event_processor.py
  • .sdk_metadata.json: register the token on the existing python-server-sdk entry → userAgents: ["PythonClient", "PythonAsyncClient"].

Sync behavior is unchanged (the default token is still PythonClient).

Design note

SDK-2658 originally proposed a separate python-server-sdk-async sdk-meta registry entry. We chose to keep a single entry and add the async token to its userAgents array instead, because async has no independent package and is not a separately-tracked feature.

The analytics/event SDK name python-server-sdk-async already ships (async_client.py); billing confirmed it does not key off the User-Agent, so this change is safe and additive.

Tests

New testing/impl/test_user_agent.py locks the exact wire tokens for both sync and async via _base_headers / _headers. mypy / isort / pycodestyle clean; touched-component suites pass.

Implements SDK-2658.


Note

Overview
Async AsyncLDClient traffic previously used the same PythonClient/<version> User-Agent as the sync client, so LaunchDarkly could not tell them apart in one package. This PR introduces PythonAsyncClient and wires it through shared header helpers while keeping sync defaults unchanged.

SYNC_USER_AGENT / ASYNC_USER_AGENT are defined in impl/http.py; _base_headers and _headers take an optional user_agent (default PythonClient). Async paths pass ASYNC_USER_AGENT: SSE in impl/aio/transport.py, FDv1 polling in async_feature_requester.py, FDv2 polling in async_polling.py, and event posts in async_event_processor.py.

.sdk_metadata.json adds PythonAsyncClient to the existing python-server-sdk userAgents list. testing/impl/test_user_agent.py asserts the exact wire User-Agent strings for sync and async.

Reviewed by Cursor Bugbot for commit 32498ce. Bugbot is set up for automated code reviews on this repo. Configure here.

The async client shipped reusing the sync 'PythonClient/<version>' User-Agent,
so LaunchDarkly could not tell async traffic apart from sync. Since sync and
async ship in one package, the User-Agent token is the distinguishing signal.

Add an ASYNC_USER_AGENT token 'PythonAsyncClient' and thread it through the
async request paths (AsyncSSEFactory streaming headers, and the async feature
requester, FDv2 polling, and event processor request headers) by parameterizing
the shared _base_headers / _headers helpers. Sync behavior is unchanged.

Register the new token in .sdk_metadata.json under the existing python-server-sdk
entry, since async has no independent package.

Implements SDK-2658. The analytics/event name 'python-server-sdk-async' already
ships; billing confirmed it does not key off the User-Agent.
@jsonbailey jsonbailey changed the title feat: Report a distinct User-Agent for the async client fix: Report a distinct User-Agent for the async client Sep 3, 2026
@jsonbailey
jsonbailey marked this pull request as ready for review September 3, 2026 14:31
@jsonbailey
jsonbailey requested a review from a team as a code owner September 3, 2026 14:31
@jsonbailey
jsonbailey merged commit 514c467 into main Sep 4, 2026
18 checks passed
@jsonbailey
jsonbailey deleted the jb/sdk-2658/async-user-agent branch September 4, 2026 20:46
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.

2 participants