fix(traceloop-sdk): avoid calling async json methods in JSONEncoder#3968
fix(traceloop-sdk): avoid calling async json methods in JSONEncoder#3968trinhchien wants to merge 2 commits intotraceloop:mainfrom
Conversation
|
trinhchien seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
📝 WalkthroughWalkthroughAdd synchronous and asynchronous tests that exercise workflow argument serialization for objects exposing a Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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/traceloop-sdk/traceloop/sdk/utils/json_encoder.py`:
- Around line 18-23: The branch handling hasattr(o, "json") currently only
returns a value when o.json is callable; to preserve existing behavior you must
also handle non-callable json attributes: keep the current callable path (use
json_method = o.json, call it when callable and not inspect.iscoroutinefunction,
and return result if not inspect.iscoroutine(result)), and add an else branch
that returns the non-callable o.json value directly (without calling) so it
doesn't fall through to the class-name fallback; ensure these checks use the
same symbols (hasattr(o, "json"), json_method, inspect.iscoroutinefunction,
inspect.iscoroutine) and place this logic before the fallback that returns the
object's class name.
🪄 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: 316c3afc-d5d3-4e32-8875-d4d79cc263d2
📒 Files selected for processing (2)
packages/traceloop-sdk/tests/test_workflows.pypackages/traceloop-sdk/traceloop/sdk/utils/json_encoder.py
max-deygin-traceloop
left a comment
There was a problem hiding this comment.
If possible, please add a regression test for the sync json() method.
This is minor, we can merge without it.
53babf9 to
625bb89
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/traceloop-sdk/tests/test_workflows.py (1)
511-528: Strengthen regression by asserting no unawaited-coroutine warning.The current assertions validate serialized values, but the original bug was the
RuntimeWarningside effect. Add an explicit warning assertion so this cannot regress silently.Proposed test hardening
`@pytest.mark.asyncio` -async def test_async_workflow_with_async_json_method_argument(exporter): +async def test_async_workflow_with_async_json_method_argument(exporter, recwarn): `@workflow`(name="request_workflow") async def request_workflow(request: FakeAsyncRequest): return {"ok": True} await request_workflow(FakeAsyncRequest()) + assert not any( + w.category is RuntimeWarning and "was never awaited" in str(w.message) + for w in recwarn + ) spans = exporter.get_finished_spans() assert [span.name for span in spans] == ["request_workflow.workflow"]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/traceloop-sdk/tests/test_workflows.py` around lines 511 - 528, Wrap the call to await request_workflow(FakeAsyncRequest()) inside a warnings-capture context and assert no RuntimeWarning was emitted so the regression can't slip by; specifically modify the test_async_workflow_with_async_json_method_argument test to capture warnings (e.g., using warnings.catch_warnings(record=True) or pytest.warns(None) around the await) and then assert that none of the captured warnings have category RuntimeWarning, keeping the rest of the assertions (exporter spans, JSON attributes) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/traceloop-sdk/tests/test_workflows.py`:
- Around line 511-528: Wrap the call to await
request_workflow(FakeAsyncRequest()) inside a warnings-capture context and
assert no RuntimeWarning was emitted so the regression can't slip by;
specifically modify the test_async_workflow_with_async_json_method_argument test
to capture warnings (e.g., using warnings.catch_warnings(record=True) or
pytest.warns(None) around the await) and then assert that none of the captured
warnings have category RuntimeWarning, keeping the rest of the assertions
(exporter spans, JSON attributes) unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f789923d-7462-4c8a-aa33-25620db1c49c
📒 Files selected for processing (1)
packages/traceloop-sdk/tests/test_workflows.py
Summary
.json()methods during input serializationjson()methodWhy
JSONEncodercurrently calls any.json()method it finds synchronously. For objects like Starlette/FastAPIRequest,json()is async, which leads toRuntimeWarning: coroutine ... was never awaitedduring workflow input serialization.Testing
pytest packages/traceloop-sdk/tests/test_workflows.py -q -k 'async_json_method_argument'pytest packages/traceloop-sdk/tests/test_workflows.py -q -k 'dataclass_serialization_workflow or async_json_method_argument'Summary by CodeRabbit
Bug Fixes
Tests