pythonpython-3.xloggingtraceaiohttp

Can I add a custom TraceConfig to an existing aiohttp ClientSession?


I have a code which uses an existing aiohttp.ClientSession. I want to add custom tracing for this session.

Tried doing something like (not working):

from aiohttp import ClientSession, TraceConfig

async def on_request_start_debug(
        session: aiohttp.ClientSession,
        context, params: aiohttp.TraceRequestStartParams):
    logger.debug(f'HTTP {params.method}: {params.url}')


class MyClient:
    def __init__(self, session: ClientSession):
        trace_config = TraceConfig()
        trace_config.on_request_start.append(on_request_start_debug)
        session.trace_configs.append(trace_config)
        
        self._session = session
        # ...
        # ...

But when I try to run it - I'm getting RuntimeError: Cannot send non-frozen signal.:

...
    resp = await session.get(url=url, headers=headers, timeout=timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python3.12/site-packages/aiohttp/client.py", line 500, in _request
    await trace.send_request_start(method, url.update_query(params), headers)
  File ".../python3.12/site-packages/aiohttp/tracing.py", line 356, in send_request_start
    return await self._trace_config.on_request_start.send(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python3.12/site-packages/aiosignal/__init__.py", line 33, in send
    raise RuntimeError("Cannot send non-frozen signal.")
RuntimeError: Cannot send non-frozen signal.

Solution

  • As @sam-bull mentioned in his comment, the documentation and suggestion is to create and modify the TraceConfig during construction time.

    My case is an edge case and this answer should be taken with caution.

    It seems that the issue in my case was that the TraceConfig object wasn't frozen whereas the handlers of the list[TraceConfig] in client_session.trace_configs expects all TraceConfigs to be frozen.

    So, I ended up just using trace_config.freeze().

    i.e.:

            trace_config = aiohttp.TraceConfig()
            trace_config.on_request_start.append(on_request_start_debug)
            trace_config.freeze()
            session.trace_configs.append(trace_config)