GET /v1/stream connection open in the background. Whenever the Nexus backend emits a change event (config.updated, flag.toggled, secret.created, resync, …), the SDK triggers an immediate full sync - so the cache is updated within milliseconds of the change, instead of waiting for the next TTL tick.
Both NexusClient and AsyncNexusClient support SSE; they just use different concurrency primitives (a daemon thread vs an asyncio.Task).
Auth
Python uses theX-Nexus-API-Key header on all endpoints, including /stream, via httpx’s streaming support. The key is never passed as a ?key= query parameter. (All Nexus SDKs send the key in this header - the browser SDKs do too, using fetch-based streaming rather than the EventSource API.)
Enabling it
The stream starts automatically after the initial sync (stream=True is the default in NexusConfig).
What happens under the hood
- The SDK opens an HTTP streaming response via
httpx.Client.stream("GET", ...)(orAsyncClient.streamfor async) withAccept: text/event-streamand theX-Nexus-API-Keyheader. - The server immediately sends a
resyncevent, which causes the SDK to callsync()once to align with the current state. - The connection stays open. Every change event triggers another full sync.
- While the stream is up, the polling TTL is bumped to 60 s as a safety net.
Reconnection
Any transport error (server restart, TCP drop, network blip) triggers a reconnect with exponential backoff: 1s - 2s - 4s - 8s - 16s - 30s (capped at 30s). After three consecutive transport errors the SDK does not fall back permanently. Instead it sleeps thesse_reconnect_cooldown schedule (default 5 - 10 - 20 - 40 - 60 minutes, staying at 60 minutes thereafter) and then retries the SSE connection automatically. Your application is never notified, and stream_connected stays False during the cooldown period.
sse_reconnect_cooldown in NexusConfig. See Configuration for details.
429 Too Many Requests
Every project tier has a per-service stream connection limit:
Behaviour (v0.6.0+)
The Python SDK handles 429 with presence-conditional refinement ofRetry-After:
- With a parseable
Retry-After: the SDK parses the delta-seconds value, clamps it to[5, 300]seconds, firesobserver.on_fallback(FALLBACK_REASON_RATE_LIMITED), sleeps the indicated delay on the stream’s stop event, and then resumes the reconnect loop. The 429 does not count toward_MAX_STREAM_ERRORS. - Without a parseable
Retry-After: the SDK firesobserver.on_fallback(FALLBACK_REASON_RATE_LIMITED)and schedules a reconnect using thesse_reconnect_cooldownschedule (default 5 - 10 - 20 - 40 - 60 minutes). TTL polling covers the gap during the cooldown, and the stream retries automatically.
AsyncNexusClient-await asyncio.wait_for(self._stream_stop.wait(), timeout=retry_after), so an in-flightclose()/disconnect_stream()wakes the sleeping task immediately.NexusClient(sync) -self._stream_stop.wait(timeout=retry_after)on athreading.Event, with the same prompt-shutdown property.
Disabling SSE at runtime
connect_stream() (sync) or nexus.connect_stream() (async).
What events trigger a sync
Lifecycle
The SSE thread (sync) or task (async) is bound to the client. Callingclose() stops it cleanly along with the rest of the client teardown. Always call close() on shutdown:
