Skip to content

[OPIK-5664] [SDK] feat: global client management API with context-wise propagation and batching warning#6123

Merged
alexkuzmik merged 10 commits intomainfrom
aliaksandrk/OPIK-5664-context-client-and-batching-warning
Apr 8, 2026
Merged

[OPIK-5664] [SDK] feat: global client management API with context-wise propagation and batching warning#6123
alexkuzmik merged 10 commits intomainfrom
aliaksandrk/OPIK-5664-context-client-and-batching-warning

Conversation

@alexkuzmik
Copy link
Copy Markdown
Collaborator

@alexkuzmik alexkuzmik commented Apr 8, 2026

Details

Global Client Management API

Introduces get_global_client(), set_global_client(), reset_global_client(), and get_current_client_raw() to replace the lru_cache-based get_client_cached() singleton. The new API supports context-local client overrides via contextvars, fixing OPIK-5664 where EvaluationSuite.run() ignored the parent Opik client.

Resolution order for get_global_client():

  1. Context-local client (set via set_global_client(client, context_wise=True))
  2. Global singleton (set via set_global_client(client))
  3. Auto-created default client

Key changes:

  • EvaluationSuite stores and propagates the parent Opik client through evaluate_suite()
  • StreamingExecutor sets the client in each worker thread via set_global_client(context_wise=True)
  • All integrations resolve the client lazily at runtime via @property (no more storing at init)
  • ADK patchers no longer require an opik_client argument
  • get_client_cached() kept as a thin delegate for backwards compatibility

Batching Warning

Adds a public batching: bool = True parameter to Opik.__init__ (enabled by default). When update operations (Span.end()/update(), Trace.end()/update(), Opik.update_span()/update_trace()) are called on a client with batching enabled, a warning is emitted — updates can be silently dropped by the server if they arrive before the batched create request is flushed, resulting in data loss.

  • Streamer.use_batching property to check batching state
  • _use_batching deprecated in favor of public batching
  • All internal callsites migrated to batching=True

Test Improvements

  • Unit test teardown uses reset_global_client(end_client=False) — avoids network calls, cut test time from ~44s to ~22s
  • New tests for client propagation through evaluate_suite() and worker threads

Change checklist

  • User facing
  • Documentation update

Issues

  • OPIK-5664

Testing

  • 2769 unit tests pass
  • New tests verify:
    • Explicit client used for experiment creation
    • EvaluationSuite.run() forwards stored client to evaluate_suite()
    • Worker threads see the same client via get_global_client()

Documentation

N/A — no user-facing documentation changes required. The new batching parameter and get_global_client()/set_global_client() APIs are documented via docstrings.

@github-actions github-actions bot added python Pull requests that update Python code tests Including test files, or tests related like configuration. Python SDK labels Apr 8, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

📋 PR Linter Failed

Missing Section. The description is missing the ## Documentation section.

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

📋 PR Linter Failed

Missing Section. The description is missing the ## Documentation section.

@alexkuzmik alexkuzmik force-pushed the aliaksandrk/OPIK-5664-context-client-and-batching-warning branch from fdbbf84 to c8fe29a Compare April 8, 2026 11:22
@alexkuzmik alexkuzmik marked this pull request as ready for review April 8, 2026 12:04
@alexkuzmik alexkuzmik requested a review from a team as a code owner April 8, 2026 12:04
alexkuzmik and others added 7 commits April 8, 2026 14:21
…-wise propagation

Introduce get_global_client(), set_global_client(), reset_global_client(),
and get_current_client_raw() to replace the lru_cache-based get_client_cached()
singleton. The new API supports context-local client overrides via contextvars,
enabling EvaluationSuite.run() and the evaluation engine to propagate an
explicit Opik client to @track decorators and integrations in worker threads.

Key changes:
- EvaluationSuite stores and propagates the parent Opik client
- StreamingExecutor sets the client in each worker thread via set_global_client(context_wise=True)
- All integrations resolve the client lazily at runtime via @Property
- ADK patchers no longer require an opik_client argument
- get_client_cached() kept as a thin delegate for backwards compatibility

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Explicit client is used for experiment creation (not global)
- EvaluationSuite.run() forwards its stored client
- Worker threads see the same client via get_global_client()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The autouse fixture was calling reset_global_client() which ends the
singleton client. Tests that accidentally created a real Opik client
would block on network flush during teardown. Using end_client=False
just clears the slot without network I/O.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add public `batching: bool = True` parameter to Opik.__init__
- Deprecate internal `_use_batching` param
- Warn when Span.end()/update(), Trace.end()/update(),
  Opik.update_span(), Opik.update_trace() are called with batching
  enabled — updates can be silently dropped causing data loss
- Add Streamer.use_batching property to check batching state
- Replace all _use_batching=True callsites with batching=True

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The parameter is accepted but ignored — client resolves lazily via
the _opik_client property.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix batching=False bug: _use_batching default back to False so
  Opik(batching=False) actually disables batching
- Switch batching warnings from LOGGER.warning to warnings.warn so
  they deduplicate automatically (once per callsite per session)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alexkuzmik alexkuzmik force-pushed the aliaksandrk/OPIK-5664-context-client-and-batching-warning branch from c8fe29a to 76c2a5a Compare April 8, 2026 12:24
alexkuzmik and others added 3 commits April 8, 2026 14:31
…tibility

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The workers==1 branch runs tasks inline without set_global_client,
so @track decorators inside the task would fall back to the global
singleton instead of using the explicit client.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alexkuzmik
Copy link
Copy Markdown
Collaborator Author

Addressing baz-reviewer comments

Fixed

Comment File Fix
batching or _use_batching ignores batching=False opik_client.py:111,147 Fixed in 76c2a5a_use_batching default changed to False so Opik(batching=False) works correctly
Single-worker branch missing set_global_client evaluation_tasks_executor.py:212 Fixed in d86baf2workers==1 path now calls set_global_client(client, context_wise=True) before running tasks inline
OpikTracer arg order changed haystack/opik_tracer.py Fixed in 572cadbopik_client kept as first positional param for backwards compatibility

Skipping (by design)

Comment File Rationale
patch_adk dropped opik_client param — callers will crash patchers.py:26 All callers updated in the same PR. patch_adk is internal API, no external consumers.
Duplicated batching warning — extract helper trace_client.py:71, span_client.py:94,95 4 lines per site, a helper adds indirection for no gain. Each callsite passes a different method name.
Warning fires on every call — use log_once opik_client.py:711 Intentional — we want users to see the warning every time to push them to fix the issue.
Race on _global_singleton in get_global_client() opik_client.py:2759 Same race profile as the lru_cache approach it replaced. GIL protects the assignment in CPython. Adding a lock is over-engineering for the same risk.
OpikTracer accepts opik_client but ignores it haystack/opik_tracer.py:34 Intentional — deprecated param kept for backwards compatibility. Client resolves lazily via @property.
_temporary_client_context leaks context-local into global smoke_test.py:127 It uses set_global_client (global, not context-local) and properly restores the previous client in finally. No leak.
Import style (from vs module import) configure.py:13 Style nit, not a bug.
Default batching=True conflicts with _use_batching docs opik_client.py:110 Already fixed — _use_batching now defaults to False and is documented as deprecated.

@baz-reviewer
Copy link
Copy Markdown
Contributor

baz-reviewer bot commented Apr 8, 2026

Thanks for the detailed follow-up and rationale on each point. I appreciate the clarifications, but I can currently only save feedback to memory when it’s attached to specific code review findings, not broader PR-level or general comments like this.

@alexkuzmik alexkuzmik merged commit 691c684 into main Apr 8, 2026
132 checks passed
@alexkuzmik alexkuzmik deleted the aliaksandrk/OPIK-5664-context-client-and-batching-warning branch April 8, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Python SDK python Pull requests that update Python code tests Including test files, or tests related like configuration.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants