Skip to content

fix(qdrant): support qdrant-client v1.12+ and handle removed methods gracefully#4004

Open
Koushik-Salammagari wants to merge 3 commits intotraceloop:mainfrom
Koushik-Salammagari:fix/qdrant-compat-v1-16
Open

fix(qdrant): support qdrant-client v1.12+ and handle removed methods gracefully#4004
Koushik-Salammagari wants to merge 3 commits intotraceloop:mainfrom
Koushik-Salammagari:fix/qdrant-compat-v1-16

Conversation

@Koushik-Salammagari
Copy link
Copy Markdown

@Koushik-Salammagari Koushik-Salammagari commented Apr 16, 2026

Summary

Fixes #3492

  • Removes upload_records from both qdrant_client_methods.json and async_qdrant_client_methods.json — this method was removed in qdrant-client 1.12 and caused an AttributeError on instrumentation startup
  • Wraps wrap_function_wrapper in try/except AttributeError so any future method removals in new qdrant-client releases degrade gracefully (logs a debug message and skips the method) instead of crashing the whole instrumentation
  • Updates the test dependency upper bound from <1.12 to <2 to allow testing against current qdrant-client releases
  • Adds span.record_exception() + StatusCode.ERROR to the wrapped call in wrapper.py (also addresses 🐛 Bug Report: Errors are not logged #412 for qdrant)

Test plan

  • Install qdrant-client>=1.12 and verify QdrantInstrumentor().instrument() completes without AttributeError
  • Verify remaining methods (upsert, search, query, etc.) still produce spans
  • Run existing test suite: npx nx run opentelemetry-instrumentation-qdrant:test

Summary by CodeRabbit

  • Bug Fixes

    • Spans now record exceptions and set error status when operations fail.
    • Instrumentation now gracefully skips missing client methods to avoid runtime failures.
    • Removed instrumentation for the upload_records operation (no span will be created).
  • Chores

    • Test dependency range expanded to allow newer qdrant-client versions (up to, but not including, v2).

…gracefully

- Remove upload_records from method lists (removed in qdrant-client 1.12)
- Wrap wrap_function_wrapper in try/except AttributeError so removed
  methods in future releases do not crash instrumentation on startup
- Update test dependency upper bound from <1.12 to <2
- Add error span recording (record_exception + StatusCode.ERROR) on
  wrapped call failures

Fixes traceloop#3492
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 16, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 16, 2026

📝 Walkthrough

Walkthrough

Guarded wrapt calls to skip missing Qdrant client methods, removed upload_records mappings, adjusted span behavior to record exceptions and set ERROR status on failures, and widened test dependency upper bound for qdrant-client to <2.0.

Changes

Cohort / File(s) Summary
Instrumentation mappings
packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/async_qdrant_client_methods.json, packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/qdrant_client_methods.json
Removed mapping entries for AsyncQdrantClient.upload_records and QdrantClient.upload_records.
Instrumentation init & wrapping
packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/__init__.py, packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py
Wrap calls to wrap_function_wrapper are now guarded with try/except AttributeError and log debug when a target method is absent; span creation now sets record_exception=False and set_status_on_exception=False, execution is wrapped to explicitly record exceptions and set span status to ERROR on failures; removed special-case handling for upload_records.
Testing config
packages/opentelemetry-instrumentation-qdrant/pyproject.toml
Widened qdrant-client test dependency upper bound from <1.12 to <2.0 to allow newer client versions in tests.

Sequence Diagram(s)

sequenceDiagram
  participant App as Application
  participant Instr as QdrantInstrumentor
  participant Wrapt as wrapt
  participant Client as QdrantClient
  participant Tracer as Tracer/Span

  App->>Instr: instrument()
  Instr->>Wrapt: wrap_function_wrapper(target method)
  alt method exists
    Wrapt->>Client: replace method with wrapper
  else method missing
    Wrapt-->>Instr: AttributeError
    Instr-->>App: logger.debug -> continue
  end

  App->>Client: call wrapped method(...)
  Client->>Tracer: start_span(record_exception=False,set_status_on_exception=False)
  Tracer->>Client: execute original method
  alt method raises
    Client-->>Tracer: exception
    Tracer->>Tracer: record_exception + set Status(ERROR)
    Tracer-->>App: re-raise exception
  else success
    Tracer->>Tracer: set Status(OK) if response truthy
    Tracer-->>App: return response
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hop through code, I guard each door,

If a method's gone, I log and explore.
I start a span, and if it cries,
I note the fault and raise it high.
A small soft hop for compatibility.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: supporting qdrant-client v1.12+ and gracefully handling removed methods like upload_records.
Linked Issues check ✅ Passed The PR fully addresses issue #3492 by removing upload_records mappings, wrapping function wrappers with try/except AttributeError, and updating test dependencies to support v1.12+.
Out of Scope Changes check ✅ Passed All changes directly support the stated objectives: removing deprecated methods, adding error handling, updating dependencies, and adding docstrings for coverage.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py`:
- Around line 73-76: In the exception handler in wrapper.py replace the
span.set_status call that includes str(e) with an error-only status (e.g., call
span.set_status(Status(StatusCode.ERROR)) or set_status(StatusCode.ERROR)
depending on the existing API) so only the error code is set while leaving
span.record_exception(e) intact; update the call sites using
span.record_exception and span.set_status (the try/except block containing
span.record_exception(e) and span.set_status(Status(StatusCode.ERROR, str(e))))
to remove the high-cardinality description.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9c48b76-5867-4baf-b9a7-913fd1fdcc92

📥 Commits

Reviewing files that changed from the base of the PR and between 25189ad and 2080866.

📒 Files selected for processing (5)
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/__init__.py
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/async_qdrant_client_methods.json
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/qdrant_client_methods.json
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py
  • packages/opentelemetry-instrumentation-qdrant/pyproject.toml
💤 Files with no reviewable changes (2)
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/async_qdrant_client_methods.json
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/qdrant_client_methods.json

… status

- Add record_exception=False, set_status_on_exception=False to
  start_as_current_span so the manual try/except is the sole handler
- Drop str(e) from Status(StatusCode.ERROR) to avoid sensitive data
  leaking into span status descriptions

Addresses coderabbitai review feedback on traceloop#4004
Adds one-line docstrings to all functions in wrapper.py that were
missing them, bringing coverage from 33% to 100% and satisfying
CodeRabbit's 80% threshold.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py (1)

11-16: ⚠️ Potential issue | 🟡 Minor

Align the docstring with the empty-string guard.

Line 12 says only None is skipped, but the implementation also skips "".

📝 Proposed wording fix
 def _set_span_attribute(span, name, value):
-    """Set a span attribute if the value is not None."""
+    """Set a span attribute if the value is neither None nor an empty string."""
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py`
around lines 11 - 16, Update the docstring for _set_span_attribute to accurately
reflect that the function skips setting attributes when value is None or an
empty string (""), e.g., change "Set a span attribute if the value is not None."
to mention both None and empty-string checks; keep the implementation as-is and
ensure the docstring mentions both conditions and the function's behavior of
returning None.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py`:
- Around line 11-16: Update the docstring for _set_span_attribute to accurately
reflect that the function skips setting attributes when value is None or an
empty string (""), e.g., change "Set a span attribute if the value is not None."
to mention both None and empty-string checks; keep the implementation as-is and
ensure the docstring mentions both conditions and the function's behavior of
returning None.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9bde68db-237c-422f-94fb-b81912756ab1

📥 Commits

Reviewing files that changed from the base of the PR and between 589df61 and c997693.

📒 Files selected for processing (1)
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py

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.

🐛 Bug Report: opentelemetry-instrumentation-qdrant is incompatible with qdrant-client version 1.16.1

2 participants