Skip to content

feat(quart): Add span streaming support to Quart integration#6502

Merged
ericapisani merged 20 commits into
masterfrom
py-2352-migrate-quart
Jun 12, 2026
Merged

feat(quart): Add span streaming support to Quart integration#6502
ericapisani merged 20 commits into
masterfrom
py-2352-migrate-quart

Conversation

@ericapisani

Copy link
Copy Markdown
Member

Add span streaming support for the Quart integration when the
trace_lifecycle stream experiment is enabled. Sets HTTP request
attributes (method, headers, URL, query, client IP) on the segment
span and uses the correct source constant from sentry_sdk.traces
for span-first mode.

Depends on #6501
being merged first.

Fixes PY-2352
Fixes #6050

Move http.query and client.address attribute collection inside the
should_send_default_pii() check so sensitive values are not captured
by default.

Fixes PY-2514
Fixes #6499
Add span streaming support for the Quart integration when the
trace_lifecycle stream experiment is enabled. Sets HTTP request
attributes (method, headers, URL, query, client IP) on the segment
span and uses the correct source constant from sentry_sdk.traces
for span-first mode.

Depends on #6501
being merged first.

Fixes PY-2352
Fixes #6050
@linear-code

linear-code Bot commented Jun 4, 2026

Copy link
Copy Markdown

PY-2352

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

90550 passed | ⏭️ 6031 skipped | Total: 96581 | Pass Rate: 93.76% | Execution Time: 322m 24s

📊 Comparison with Base Branch

Metric Change
Total Tests 📈 +112
Passed Tests 📈 +112
Failed Tests
Skipped Tests

All tests are passing successfully.

✅ Patch coverage is 91.84%. Project has 2418 uncovered lines.
✅ Project coverage is 89.75%. Comparing base (base) to head (head).

Files with missing lines (1)
File Patch % Lines
sentry_sdk/integrations/quart.py 91.84% ⚠️ 4 Missing and 7 partials
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    89.74%    89.75%    +0.01%
==========================================
  Files          192       192         —
  Lines        23548     23583       +35
  Branches      8094      8116       +22
==========================================
+ Hits         21132     21165       +33
- Misses        2416      2418        +2
- Partials      1330      1334        +4

Generated by Codecov Action

@ericapisani ericapisani marked this pull request as ready for review June 4, 2026 14:11
@ericapisani ericapisani requested a review from a team as a code owner June 4, 2026 14:11
Comment thread sentry_sdk/integrations/quart.py Outdated
Comment thread sentry_sdk/integrations/quart.py
Comment thread sentry_sdk/integrations/quart.py Outdated
Comment on lines 123 to 125

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We'll need a streaming counterpart for this piece of code, something like:

client = sentry_sdk.get_client()

if has_span_streaming_enabled(client.options):
    span = get_current_span()
    if span is not None:
        span._segment._update_active_thread()

Comment thread sentry_sdk/integrations/quart.py Outdated
Comment thread sentry_sdk/integrations/quart.py
SENTRY_PYTHON_TEST_POSTGRES_USER: postgres
SENTRY_PYTHON_TEST_POSTGRES_PASSWORD: sentry
SENTRY_PYTHON_TEST_MYSQL_USER: root
SENTRY_PYTHON_TEST_MYSQL_PASSWORD: sentry

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing MySQL host env variable

Medium Severity

The DB CI job sets SENTRY_PYTHON_TEST_POSTGRES_HOST to postgres for Python 3.6/3.7 container runs but does not set SENTRY_PYTHON_TEST_MYSQL_HOST the same way for the new MySQL service. tests/integrations/aiomysql reads that variable and defaults to localhost, which is unreachable from the job container network.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit dde12e6. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't know where this came from 🤔

Comment thread sentry_sdk/integrations/starlette.py
SENTRY_PYTHON_TEST_POSTGRES_USER: postgres
SENTRY_PYTHON_TEST_POSTGRES_PASSWORD: sentry
SENTRY_PYTHON_TEST_MYSQL_USER: root
SENTRY_PYTHON_TEST_MYSQL_PASSWORD: sentry

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing MySQL host container env

Medium Severity

The new MySQL CI env sets SENTRY_PYTHON_TEST_MYSQL_USER and password but not SENTRY_PYTHON_TEST_MYSQL_HOST. For Python 3.6/3.7 jobs that run inside a service-linked container, tests/integrations/aiomysql defaults to localhost, unlike Postgres and Redis which use the mysql service hostname in that layout.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e5eb0b3. Configure here.

Base automatically changed from py-2514-gate-asgi-values-behind-pii to master June 11, 2026 14:51
Comment thread sentry_sdk/integrations/quart.py Outdated
Comment thread tests/integrations/quart/test_quart.py
Comment thread tests/integrations/quart/test_quart.py Outdated
Comment thread sentry_sdk/integrations/quart.py Outdated
Comment thread sentry_sdk/integrations/quart.py

@sentrivana sentrivana left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two small things, please see comments, otherwise LGTM

Comment thread sentry_sdk/integrations/quart.py Outdated
Comment on lines +215 to +220
segment.set_attribute(
"client.address", request_websocket.access_route[0]
)
segment.set_attribute(
"user.ip_address", request_websocket.access_route[0]
)

@sentrivana sentrivana Jun 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These should be set in user_properties instead, like ip_address is -- if they're set on the scope via set_user, they'll be set on all spans (including the segment) automatically

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The client.address didn't appear on the list of common attribute keys which is why I didn't add it (not sure if this is potentially a mistake?) but at the very least I can clean up lines 218-220 since it's being added on the scope.

Comment thread sentry_sdk/integrations/quart.py Outdated
Comment on lines +228 to +232
current_scope = sentry_sdk.get_current_scope()
existing_user_properties = current_scope._user or {}
current_scope.set_user(
{**existing_user_properties, **user_properties}
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we want to merge like this, this should interact with the isolation scope. The top-level set_user API sets the user on the isolation scope, so if there is any user data set by the user, it'll be on the isolation scope.

Suggested change
current_scope = sentry_sdk.get_current_scope()
existing_user_properties = current_scope._user or {}
current_scope.set_user(
{**existing_user_properties, **user_properties}
)
isolation_scope = sentry_sdk.get_isolation_scope()
existing_user_properties = isolation_scope._user or {}
isolation_scope.set_user(
{**existing_user_properties, **user_properties}
)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sounds good! I realized looking at this again that there's a reference to the isolation scope above so I'll use that here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6411bda. Configure here.

try:
return quart_auth.current_user._auth_id
except Exception:
return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Quart auth access unguarded

Medium Severity

Replacing _add_user_to_event with _get_current_user_id_from_quart drops the prior capture_internal_exceptions guard around reading quart_auth.current_user. In the span-streaming request_started path that helper runs outside any internal-exception handler, so a misconfigured or broken Quart Auth accessor can abort request startup instead of being ignored like before.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6411bda. Configure here.

@ericapisani ericapisani merged commit 9cbf51f into master Jun 12, 2026
144 checks passed
@ericapisani ericapisani deleted the py-2352-migrate-quart branch June 12, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate quart to span first

2 participants