Skip to content

Overly aggressive httpx client type check conflicts with opentelemetry instrumentation in some cases #943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
micahjsmith opened this issue Apr 17, 2025 · 0 comments

Comments

@micahjsmith
Copy link

I've found that it is impossible to call client.with_options if anthropic is imported before opentelemetry httpx instrumentor is run. This is because anthropic has a reference to the original/unpatched httpx.Client via inheritance whereas at runtime the isinstance comparison happens against the instrumented client via otel.

I recognize that this error is probably a "user error" and devs can and should take care to run all of their instrumentation/patching before other imports happen.

However there are a few points I'd make to see whether you'd consider addressing within this repo.

I believe this type check in _base_client can be removed entirely as it is the user's responsibility to ensure they pass in an http client with type that is acceptable per the type annotations.

anthropic 0.48.0
opentelemetry-instrumentation-httpx 0.48b0

this works when patching fully happens before anthropic sdk is imported

$ poetry run python
Python 3.11.11 (main, Dec  3 2024, 17:20:40) [Clang 16.0.0 (clang-1600.0.26.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
>>> HTTPXClientInstrumentor().instrument()
>>> import anthropic
>>> client = anthropic.Anthropic()
>>> client = client.with_options(timeout=1.0)
>>> ^D

this fails when patching happens after anthropic sdk is imported

$ poetry run python
Python 3.11.11 (main, Dec  3 2024, 17:20:40) [Clang 16.0.0 (clang-1600.0.26.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import anthropic
>>> from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
>>> HTTPXClientInstrumentor().instrument()
>>> client = anthropic.Anthropic()
>>> client = client.with_options(timeout=1.0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/micahsmith/workspace/.venv/lib/python3.11/site-packages/anthropic/_client.py", line 221, in copy
    return self.__class__(
           ^^^^^^^^^^^^^^^
  File "/Users/micahsmith/workspace/.venv/lib/python3.11/site-packages/anthropic/_client.py", line 110, in __init__
    super().__init__(
  File "/Users/micahsmith/workspace/.venv/lib/python3.11/site-packages/anthropic/_base_client.py", line 899, in __init__
    raise TypeError(
TypeError: Invalid `http_client` argument; Expected an instance of `httpx.Client` but got <class 'anthropic._base_client.SyncHttpxClientWrapper'>
>>> httpx.Client.mro()
[<class 'opentelemetry.instrumentation.httpx._InstrumentedClient'>, <class 'httpx.Client'>, <class 'httpx._client.BaseClient'>, <class 'object'>]
>>> type(client._client).mro()
[<class 'anthropic._base_client.SyncHttpxClientWrapper'>, <class 'anthropic._DefaultHttpxClient'>, <class 'httpx.Client'>, <class 'httpx._client.BaseClient'>, <class 'object'>]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant