Skip to content

feat: add on_response_headers_received signal to TraceConfig#12535

Open
ykd007 wants to merge 3 commits into
aio-libs:masterfrom
ykd007:feat/trace-response-headers-received
Open

feat: add on_response_headers_received signal to TraceConfig#12535
ykd007 wants to merge 3 commits into
aio-libs:masterfrom
ykd007:feat/trace-response-headers-received

Conversation

@ykd007
Copy link
Copy Markdown

@ykd007 ykd007 commented May 14, 2026

Closes #7386

Summary

Adds the missing on_response_headers_received signal to TraceConfig, allowing users to observe response headers as soon as they are parsed from the server — before the response body is consumed.

Changes

  • aiohttp/tracing.py — Added TraceResponseHeadersReceivedParams dataclass (method, url, headers: CIMultiDictProxy[str]), on_response_headers_received signal to TraceConfig, and Trace.send_response_headers_received() method
  • aiohttp/client_reqrep.py — Fire the signal in ClientResponse.start() after headers are parsed, before payload is set
  • tests/test_tracing.py — Added TraceResponseHeadersReceivedParams to freeze test + parametrized test_send coverage
  • CHANGES/7386.feature.rst — Towncrier changelog fragment

Signal firing point

Fires in ClientResponse.start() immediately after self._headers = message.headers is set, before self.content = payload. Subscribers receive the full parsed response headers (and status line) but no body bytes yet — symmetric to how on_request_headers_sent fires after request headers are written but before the body.

@ykd007 ykd007 requested review from asvetlov and webknjaz as code owners May 14, 2026 09:48
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label May 14, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.94%. Comparing base (7eb0e80) to head (cb81e5b).
⚠️ Report is 2 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #12535   +/-   ##
=======================================
  Coverage   98.94%   98.94%           
=======================================
  Files         131      131           
  Lines       46622    46638   +16     
  Branches     2414     2416    +2     
=======================================
+ Hits        46132    46148   +16     
  Misses        367      367           
  Partials      123      123           
Flag Coverage Δ
Autobahn 22.45% <46.66%> (+<0.01%) ⬆️
CI-GHA 98.91% <100.00%> (+<0.01%) ⬆️
OS-Linux 98.66% <100.00%> (+<0.01%) ⬆️
OS-Windows 97.03% <100.00%> (+<0.01%) ⬆️
OS-macOS 97.93% <100.00%> (+<0.01%) ⬆️
Py-3.10.11 97.42% <100.00%> (+<0.01%) ⬆️
Py-3.10.20 97.91% <100.00%> (+<0.01%) ⬆️
Py-3.11.15 98.16% <100.00%> (+<0.01%) ⬆️
Py-3.11.9 97.68% <100.00%> (+<0.01%) ⬆️
Py-3.12.10 97.77% <100.00%> (+<0.01%) ⬆️
Py-3.12.13 98.25% <100.00%> (+<0.01%) ⬆️
Py-3.13.13 98.47% <100.00%> (+<0.01%) ⬆️
Py-3.14.4 98.42% <100.00%> (-0.02%) ⬇️
Py-3.14.5 97.48% <100.00%> (?)
Py-3.14.5t 97.54% <100.00%> (+<0.01%) ⬆️
Py-pypy3.11.15-7.3.21 97.41% <100.00%> (-0.02%) ⬇️
VM-macos 97.93% <100.00%> (+<0.01%) ⬆️
VM-ubuntu 98.66% <100.00%> (+<0.01%) ⬆️
VM-windows 97.03% <100.00%> (+<0.01%) ⬆️
cython-coverage 37.96% <94.44%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 14, 2026

Merging this PR will not alter performance

✅ 72 untouched benchmarks
⏩ 69 skipped benchmarks1


Comparing ykd007:feat/trace-response-headers-received (cb81e5b) with master (7eb0e80)2

Open in CodSpeed

Footnotes

  1. 69 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on master (125dfae) during the generation of this report, so 7eb0e80 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Comment thread aiohttp/client_reqrep.py
if self._traces:
for trace in self._traces:
await trace.send_response_headers_received(
self.method, self.url, cast(CIMultiDictProxy[str], self._headers)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why are we casting here?

Comment thread aiohttp/tracing.py

method: str
url: URL
headers: "CIMultiDictProxy[str]"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks like our other ones currently use CIMultiDict. Considering that tracing is going to be in performance-critical paths, I think it should just use whatever the code uses. Judging by your cast(), I'd assume it's actually CIMultiDict like the others.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Alternatively, and probably longer term, we could consider adding a MultiMapping type to multidict that would be compatible with both classes and provide immutability at the typing level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

missing headers_received signal in TraceConfig

2 participants