From 4dd0bba7687f7ab70e0cb973ac588a850a9e99b2 Mon Sep 17 00:00:00 2001 From: Roger Yang <80478925+RogerHYang@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:24:26 -0700 Subject: [PATCH] fix: remove anthropic dependency (#1094) --- .../pyproject.toml | 9 +--- .../instrumentation/anthropic/__init__.py | 2 +- .../instrumentation/anthropic/_stream.py | 44 ++++++++++--------- .../test-requirements.txt | 4 ++ python/tox.ini | 5 ++- 5 files changed, 35 insertions(+), 29 deletions(-) create mode 100644 python/instrumentation/openinference-instrumentation-anthropic/test-requirements.txt diff --git a/python/instrumentation/openinference-instrumentation-anthropic/pyproject.toml b/python/instrumentation/openinference-instrumentation-anthropic/pyproject.toml index f8a926148..f8ffec76f 100644 --- a/python/instrumentation/openinference-instrumentation-anthropic/pyproject.toml +++ b/python/instrumentation/openinference-instrumentation-anthropic/pyproject.toml @@ -36,13 +36,7 @@ dependencies = [ [project.optional-dependencies] instruments = [ - "anthropic >= 0.25.0", -] -test = [ - "anthropic >= 0.25.0", - "opentelemetry-sdk", - "pytest-asyncio", - "pytest.recording" + "anthropic >= 0.30.0", ] [project.urls] @@ -61,6 +55,7 @@ packages = ["src/openinference"] [tool.pytest.ini_options] asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" testpaths = [ "tests", ] diff --git a/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/__init__.py b/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/__init__.py index f03132c02..eb9367a95 100644 --- a/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/__init__.py +++ b/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/__init__.py @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) -_instruments = ("anthropic >= 0.25.0",) +_instruments = ("anthropic >= 0.30.0",) class AnthropicInstrumentor(BaseInstrumentor): # type: ignore[misc] diff --git a/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/_stream.py b/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/_stream.py index a05254853..2e450d043 100644 --- a/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/_stream.py +++ b/python/instrumentation/openinference-instrumentation-anthropic/src/openinference/instrumentation/anthropic/_stream.py @@ -1,6 +1,7 @@ from collections import defaultdict from copy import deepcopy from typing import ( + TYPE_CHECKING, Any, AsyncIterator, Callable, @@ -19,17 +20,6 @@ from opentelemetry.util.types import AttributeValue from wrapt import ObjectProxy -from anthropic import Stream -from anthropic.types import ( - Completion, - RawMessageStreamEvent, -) -from anthropic.types.raw_content_block_delta_event import RawContentBlockDeltaEvent -from anthropic.types.raw_content_block_start_event import RawContentBlockStartEvent -from anthropic.types.raw_message_delta_event import RawMessageDeltaEvent -from anthropic.types.raw_message_start_event import RawMessageStartEvent -from anthropic.types.text_block import TextBlock -from anthropic.types.tool_use_block import ToolUseBlock from openinference.instrumentation import safe_json_dumps from openinference.instrumentation.anthropic._utils import ( _as_output_attributes, @@ -44,6 +34,13 @@ ToolCallAttributes, ) +if TYPE_CHECKING: + from anthropic import Stream + from anthropic.types import Completion, RawMessageStreamEvent + from anthropic.types.raw_content_block_delta_event import RawContentBlockDeltaEvent + from anthropic.types.text_block import TextBlock + from anthropic.types.tool_use_block import ToolUseBlock + class _Stream(ObjectProxy): # type: ignore __slots__ = ( @@ -54,14 +51,14 @@ class _Stream(ObjectProxy): # type: ignore def __init__( self, - stream: Stream[Completion], + stream: "Stream[Completion]", with_span: _WithSpan, ) -> None: super().__init__(stream) self._response_accumulator = _ResponseAccumulator() self._with_span = with_span - def __iter__(self) -> Iterator[Completion]: + def __iter__(self) -> Iterator["Completion"]: try: for item in self.__wrapped__: self._response_accumulator.process_chunk(item) @@ -80,7 +77,7 @@ def __iter__(self) -> Iterator[Completion]: ) self._finish_tracing(status=status) - async def __aiter__(self) -> AsyncIterator[Completion]: + async def __aiter__(self) -> AsyncIterator["Completion"]: try: async for item in self.__wrapped__: self._response_accumulator.process_chunk(item) @@ -124,7 +121,7 @@ def __init__(self) -> None: stop_reason=_SimpleStringReplace(), ) - def process_chunk(self, chunk: Completion) -> None: + def process_chunk(self, chunk: "Completion") -> None: self._is_null = False values = chunk.model_dump(exclude_unset=True, warnings=False) self._values += values @@ -168,14 +165,14 @@ class _MessagesStream(ObjectProxy): # type: ignore def __init__( self, - stream: Stream[RawMessageStreamEvent], + stream: "Stream[RawMessageStreamEvent]", with_span: _WithSpan, ) -> None: super().__init__(stream) self._response_accumulator = _MessageResponseAccumulator() self._with_span = with_span - def __iter__(self) -> Iterator[RawMessageStreamEvent]: + def __iter__(self) -> Iterator["RawMessageStreamEvent"]: try: for item in self.__wrapped__: self._response_accumulator.process_chunk(item) @@ -194,7 +191,7 @@ def __iter__(self) -> Iterator[RawMessageStreamEvent]: ) self._finish_tracing(status=status) - async def __aiter__(self) -> AsyncIterator[RawMessageStreamEvent]: + async def __aiter__(self) -> AsyncIterator["RawMessageStreamEvent"]: try: async for item in self.__wrapped__: self._response_accumulator.process_chunk(item) @@ -237,7 +234,7 @@ class _MessageResponseAccumulator: def __init__(self) -> None: self._is_null = True self._current_message_idx = -1 - self._current_content_block_type: Union[TextBlock, ToolUseBlock, None] = None + self._current_content_block_type: Union["TextBlock", "ToolUseBlock", None] = None self._values = _ValuesAccumulator( messages=_IndexedAccumulator( lambda: _ValuesAccumulator( @@ -257,7 +254,14 @@ def __init__(self) -> None: ), ) - def process_chunk(self, chunk: RawContentBlockDeltaEvent) -> None: + def process_chunk(self, chunk: "RawContentBlockDeltaEvent") -> None: + from anthropic.types.raw_content_block_delta_event import RawContentBlockDeltaEvent + from anthropic.types.raw_content_block_start_event import RawContentBlockStartEvent + from anthropic.types.raw_message_delta_event import RawMessageDeltaEvent + from anthropic.types.raw_message_start_event import RawMessageStartEvent + from anthropic.types.text_block import TextBlock + from anthropic.types.tool_use_block import ToolUseBlock + self._is_null = False if isinstance(chunk, RawMessageStartEvent): self._current_message_idx += 1 diff --git a/python/instrumentation/openinference-instrumentation-anthropic/test-requirements.txt b/python/instrumentation/openinference-instrumentation-anthropic/test-requirements.txt new file mode 100644 index 000000000..ab2e88dbc --- /dev/null +++ b/python/instrumentation/openinference-instrumentation-anthropic/test-requirements.txt @@ -0,0 +1,4 @@ +anthropic==0.30.0 +opentelemetry-sdk +pytest-asyncio +pytest.recording diff --git a/python/tox.ini b/python/tox.ini index 6a03e1047..68aca3a18 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -76,7 +76,10 @@ commands_pre = litellm-latest: uv pip install -U litellm ; instructor: uv pip install --reinstall {toxinidir}/instrumentation/openinference-instrumentation-instructor[test] ; instructor-latest: uv pip install -U instructor - anthropic: uv pip install --reinstall {toxinidir}/instrumentation/openinference-instrumentation-anthropic[test] + anthropic: uv pip uninstall -r test-requirements.txt + anthropic: uv pip install --reinstall-package openinference-instrumentation-anthropic . + anthropic: python -c 'import openinference.instrumentation.anthropic' + anthropic: uv pip install -r test-requirements.txt anthropic-latest: uv pip install -U anthropic commands = ruff: ruff format {posargs:.}