requests-cache / aiohttp-client-cache

An async persistent cache for aiohttp requests

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CacheMixin doesn't pass kwargs to ClientSession when Sentry is used

domin4815 opened this issue · comments

The problem

CachedSession constructor doesn't pass kwargs to ClientSession when Sentry is used in the project. When CacheMixin init method calls session_kwargs = get_valid_kwargs(super().__init__, {**kwargs, 'base_url': base_url}) it gets an empty dict. This is because super().__init__ checks Sentry's AioHttpIntegration signature, not CachedSession.

Expected behavior

The CachedSession should pass all kwargs to ClientSession even if Sentry's AioHttpIntegration stands in between.

Steps to reproduce the behavior

Workarounds

If we change CacheMixin in aiohttp_client_cache/session.py and skip get_valid_kwargs, just pass all the args, it works as expected.

Environment

  • aiohttp-client-cache version: 0.8.2
  • Python version: 3.11.4
  • Platform: macOS
  • sentry-sdk = { version = "^1.25.1", extras = ["fastapi"]}

Could you provide a complete code example that reproduces the problem? I am not familiar with how Sentry interfaces with aiohttp's ClientSession.

@JWCook
Hi
I've created a basic example that demonstrates this behavior. It sends two identical requests using, one before initializing Sentry, and a second one after initializing Sentry. The expected behavior is for the client to use the specified request class. But only the first request use CustomRequest as seen by the printed output

Dependencies:

python = "^3.11"
sentry-sdk = "^1.29.2"
aiohttp = "^3.8.5"
aiohttp-client-cache = {extras = ["all"], version = "^0.8.2"}

Code:

import asyncio

import sentry_sdk
from aiohttp import ClientRequest, ClientResponse
from aiohttp.connector import Connection
from aiohttp_client_cache import CachedSession


class CustomRequest(ClientRequest):
    async def send(self, conn: Connection) -> ClientResponse:
        print("Custom request class used!")
        return await super().send(conn)


async def send_request():
    print("Sending a request")
    async with CachedSession(request_class=CustomRequest) as session:
        await session.get('https://example.org/')
    print("Request completed\n")


if __name__ == '__main__':
    asyncio.run(send_request())

    print("Initializing Sentry and sending another request")
    sentry_sdk.init()
    asyncio.run(send_request())

stdout:

Sending a request
Custom request class used!
Request completed

Initializing Sentry and sending another request
Sending a request
Request completed

Hope this helps

Thank you for the details!

It's a bit hard to follow exactly how sentry_sdk.init() modifies the session, but I can at least confirm that it changes the init signature to __init__(*args, **kwargs). I think we can handle this during inspection by checking for the Parameter.VAR_KEYWORD type.

Changes are in main and will be included in the next release.

These changes are available in v0.9.