opentelemetry-instrumentation-vertexai 2.0b0__tar.gz → 2.1b0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of opentelemetry-instrumentation-vertexai might be problematic. Click here for more details.

Files changed (39) hide show
  1. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/PKG-INFO +6 -6
  2. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/pyproject.toml +5 -5
  3. opentelemetry_instrumentation_vertexai-2.1b0/src/opentelemetry/instrumentation/vertexai/__init__.py +173 -0
  4. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/src/opentelemetry/instrumentation/vertexai/events.py +18 -16
  5. opentelemetry_instrumentation_vertexai-2.1b0/src/opentelemetry/instrumentation/vertexai/patch.py +371 -0
  6. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/src/opentelemetry/instrumentation/vertexai/utils.py +136 -21
  7. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/src/opentelemetry/instrumentation/vertexai/version.py +1 -1
  8. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_function_call_choice.yaml +14 -11
  9. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_function_call_choice_no_content.yaml +14 -11
  10. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_generate_content.yaml +23 -7
  11. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_generate_content_all_events.yaml +23 -7
  12. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_generate_content_extra_params.yaml +16 -13
  13. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_generate_content_invalid_role.yaml +2 -2
  14. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_generate_content_invalid_temperature.yaml +2 -2
  15. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_generate_content_missing_model.yaml +2 -2
  16. opentelemetry_instrumentation_vertexai-2.1b0/tests/cassettes/test_generate_content_with_files.yaml +102 -0
  17. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_generate_content_without_events.yaml +23 -7
  18. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_preview_generate_content_all_input_events.yaml +13 -11
  19. opentelemetry_instrumentation_vertexai-2.1b0/tests/cassettes/test_tool_events.yaml +151 -0
  20. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/cassettes/test_tool_events_no_content.yaml +16 -13
  21. opentelemetry_instrumentation_vertexai-2.0b0/tests/cassettes/test_tool_events.yaml → opentelemetry_instrumentation_vertexai-2.1b0/tests/cassettes/test_tool_events_with_completion_hook.yaml +16 -13
  22. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/conftest.py +171 -14
  23. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/requirements.latest.txt +4 -2
  24. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/requirements.oldest.txt +8 -7
  25. opentelemetry_instrumentation_vertexai-2.1b0/tests/shared_test_utils.py +122 -0
  26. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/test_chat_completions.py +97 -87
  27. opentelemetry_instrumentation_vertexai-2.1b0/tests/test_chat_completions_experimental.py +488 -0
  28. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/test_function_calling.py +69 -185
  29. opentelemetry_instrumentation_vertexai-2.1b0/tests/test_function_calling_experimental.py +341 -0
  30. opentelemetry_instrumentation_vertexai-2.1b0/tests/test_instrumentor.py +47 -0
  31. opentelemetry_instrumentation_vertexai-2.0b0/src/opentelemetry/instrumentation/vertexai/__init__.py +0 -96
  32. opentelemetry_instrumentation_vertexai-2.0b0/src/opentelemetry/instrumentation/vertexai/patch.py +0 -142
  33. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/.gitignore +0 -0
  34. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/LICENSE +0 -0
  35. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/README.rst +0 -0
  36. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/src/opentelemetry/instrumentation/vertexai/package.py +0 -0
  37. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/src/opentelemetry/instrumentation/vertexai/py.typed +0 -0
  38. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/__init__.py +0 -0
  39. {opentelemetry_instrumentation_vertexai-2.0b0 → opentelemetry_instrumentation_vertexai-2.1b0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opentelemetry-instrumentation-vertexai
3
- Version: 2.0b0
3
+ Version: 2.1b0
4
4
  Summary: OpenTelemetry Official VertexAI instrumentation
5
5
  Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-vertexai
6
6
  Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib
@@ -12,15 +12,15 @@ Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
15
  Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
19
18
  Classifier: Programming Language :: Python :: 3.12
20
- Requires-Python: >=3.8
21
- Requires-Dist: opentelemetry-api~=1.28
22
- Requires-Dist: opentelemetry-instrumentation~=0.49b0
23
- Requires-Dist: opentelemetry-semantic-conventions~=0.49b0
19
+ Requires-Python: >=3.9
20
+ Requires-Dist: opentelemetry-api~=1.37
21
+ Requires-Dist: opentelemetry-instrumentation~=0.58b0
22
+ Requires-Dist: opentelemetry-semantic-conventions~=0.58b0
23
+ Requires-Dist: opentelemetry-util-genai<0.3b0,>=0.2b0
24
24
  Provides-Extra: instruments
25
25
  Requires-Dist: google-cloud-aiplatform>=1.64; extra == 'instruments'
26
26
  Description-Content-Type: text/x-rst
@@ -8,7 +8,7 @@ dynamic = ["version"]
8
8
  description = "OpenTelemetry Official VertexAI instrumentation"
9
9
  readme = "README.rst"
10
10
  license = "Apache-2.0"
11
- requires-python = ">=3.8"
11
+ requires-python = ">=3.9"
12
12
  authors = [
13
13
  { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" },
14
14
  ]
@@ -18,16 +18,16 @@ classifiers = [
18
18
  "License :: OSI Approved :: Apache Software License",
19
19
  "Programming Language :: Python",
20
20
  "Programming Language :: Python :: 3",
21
- "Programming Language :: Python :: 3.8",
22
21
  "Programming Language :: Python :: 3.9",
23
22
  "Programming Language :: Python :: 3.10",
24
23
  "Programming Language :: Python :: 3.11",
25
24
  "Programming Language :: Python :: 3.12",
26
25
  ]
27
26
  dependencies = [
28
- "opentelemetry-api ~= 1.28",
29
- "opentelemetry-instrumentation ~= 0.49b0",
30
- "opentelemetry-semantic-conventions ~= 0.49b0",
27
+ "opentelemetry-api ~= 1.37",
28
+ "opentelemetry-instrumentation ~= 0.58b0",
29
+ "opentelemetry-semantic-conventions ~= 0.58b0",
30
+ "opentelemetry-util-genai >= 0.2b0, <0.3b0",
31
31
  ]
32
32
 
33
33
  [project.optional-dependencies]
@@ -0,0 +1,173 @@
1
+ # Copyright The OpenTelemetry Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ VertexAI client instrumentation supporting `google-cloud-aiplatform` SDK, it can be enabled by
17
+ using ``VertexAIInstrumentor``.
18
+
19
+ .. _vertexai: https://pypi.org/project/google-cloud-aiplatform/
20
+
21
+ Usage
22
+ -----
23
+
24
+ .. code:: python
25
+
26
+ import vertexai
27
+ from vertexai.generative_models import GenerativeModel
28
+ from opentelemetry.instrumentation.vertexai import VertexAIInstrumentor
29
+
30
+ VertexAIInstrumentor().instrument()
31
+
32
+ vertexai.init()
33
+ model = GenerativeModel("gemini-1.5-flash-002")
34
+ chat_completion = model.generate_content(
35
+ "Write a short poem on OpenTelemetry."
36
+ )
37
+
38
+ API
39
+ ---
40
+ """
41
+
42
+ from __future__ import annotations
43
+
44
+ from typing import Any, Collection
45
+
46
+ from wrapt import (
47
+ wrap_function_wrapper, # type: ignore[reportUnknownVariableType]
48
+ )
49
+
50
+ from opentelemetry._logs import get_logger
51
+ from opentelemetry.instrumentation._semconv import (
52
+ _OpenTelemetrySemanticConventionStability,
53
+ _OpenTelemetryStabilitySignalType,
54
+ _StabilityMode,
55
+ )
56
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
57
+ from opentelemetry.instrumentation.utils import unwrap
58
+ from opentelemetry.instrumentation.vertexai.package import _instruments
59
+ from opentelemetry.instrumentation.vertexai.patch import MethodWrappers
60
+ from opentelemetry.instrumentation.vertexai.utils import is_content_enabled
61
+ from opentelemetry.semconv.schemas import Schemas
62
+ from opentelemetry.trace import get_tracer
63
+ from opentelemetry.util.genai.completion_hook import load_completion_hook
64
+
65
+
66
+ def _methods_to_wrap(
67
+ method_wrappers: MethodWrappers,
68
+ ):
69
+ # This import is very slow, do it lazily in case instrument() is not called
70
+ # pylint: disable=import-outside-toplevel
71
+ from google.cloud.aiplatform_v1.services.prediction_service import (
72
+ async_client,
73
+ client,
74
+ )
75
+ from google.cloud.aiplatform_v1beta1.services.prediction_service import (
76
+ async_client as async_client_v1beta1,
77
+ )
78
+ from google.cloud.aiplatform_v1beta1.services.prediction_service import (
79
+ client as client_v1beta1,
80
+ )
81
+
82
+ for client_class in (
83
+ client.PredictionServiceClient,
84
+ client_v1beta1.PredictionServiceClient,
85
+ ):
86
+ yield (
87
+ client_class,
88
+ client_class.generate_content.__name__, # type: ignore[reportUnknownMemberType]
89
+ method_wrappers.generate_content,
90
+ )
91
+
92
+ for client_class in (
93
+ async_client.PredictionServiceAsyncClient,
94
+ async_client_v1beta1.PredictionServiceAsyncClient,
95
+ ):
96
+ yield (
97
+ client_class,
98
+ client_class.generate_content.__name__, # type: ignore[reportUnknownMemberType]
99
+ method_wrappers.agenerate_content,
100
+ )
101
+
102
+
103
+ class VertexAIInstrumentor(BaseInstrumentor):
104
+ def __init__(self) -> None:
105
+ super().__init__()
106
+ self._methods_to_unwrap: list[tuple[Any, str]] = []
107
+
108
+ def instrumentation_dependencies(self) -> Collection[str]:
109
+ return _instruments
110
+
111
+ def _instrument(self, **kwargs: Any):
112
+ """Enable VertexAI instrumentation."""
113
+ completion_hook = (
114
+ kwargs.get("completion_hook") or load_completion_hook()
115
+ )
116
+ sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
117
+ _OpenTelemetryStabilitySignalType.GEN_AI,
118
+ )
119
+ tracer_provider = kwargs.get("tracer_provider")
120
+ schema = (
121
+ Schemas.V1_28_0.value
122
+ if sem_conv_opt_in_mode == _StabilityMode.DEFAULT
123
+ else Schemas.V1_36_0.value
124
+ )
125
+ tracer = get_tracer(
126
+ __name__,
127
+ "",
128
+ tracer_provider,
129
+ schema_url=schema,
130
+ )
131
+ logger_provider = kwargs.get("logger_provider")
132
+ logger = get_logger(
133
+ __name__,
134
+ "",
135
+ logger_provider=logger_provider,
136
+ schema_url=schema,
137
+ )
138
+ sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
139
+ _OpenTelemetryStabilitySignalType.GEN_AI,
140
+ )
141
+ if sem_conv_opt_in_mode == _StabilityMode.DEFAULT:
142
+ # Type checker now knows sem_conv_opt_in_mode is a Literal[_StabilityMode.DEFAULT]
143
+ method_wrappers = MethodWrappers(
144
+ tracer,
145
+ logger,
146
+ is_content_enabled(sem_conv_opt_in_mode),
147
+ sem_conv_opt_in_mode,
148
+ completion_hook,
149
+ )
150
+ elif sem_conv_opt_in_mode == _StabilityMode.GEN_AI_LATEST_EXPERIMENTAL:
151
+ # Type checker now knows it's the other literal
152
+ method_wrappers = MethodWrappers(
153
+ tracer,
154
+ logger,
155
+ is_content_enabled(sem_conv_opt_in_mode),
156
+ sem_conv_opt_in_mode,
157
+ completion_hook,
158
+ )
159
+ else:
160
+ raise RuntimeError(f"{sem_conv_opt_in_mode} mode not supported")
161
+ for client_class, method_name, wrapper in _methods_to_wrap(
162
+ method_wrappers
163
+ ):
164
+ wrap_function_wrapper(
165
+ client_class,
166
+ name=method_name,
167
+ wrapper=wrapper,
168
+ )
169
+ self._methods_to_unwrap.append((client_class, method_name))
170
+
171
+ def _uninstrument(self, **kwargs: Any) -> None:
172
+ for client_class, method_name in self._methods_to_unwrap:
173
+ unwrap(client_class, method_name)
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ # type: ignore[reportUnknownDeprecated]
16
+
15
17
  """
16
18
  Factories for event types described in
17
19
  https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md#system-event.
@@ -25,7 +27,7 @@ from __future__ import annotations
25
27
  from dataclasses import asdict, dataclass
26
28
  from typing import Any, Iterable, Literal
27
29
 
28
- from opentelemetry._events import Event
30
+ from opentelemetry._logs import LogRecord
29
31
  from opentelemetry.semconv._incubating.attributes import gen_ai_attributes
30
32
  from opentelemetry.util.types import AnyValue
31
33
 
@@ -34,7 +36,7 @@ def user_event(
34
36
  *,
35
37
  role: str = "user",
36
38
  content: AnyValue = None,
37
- ) -> Event:
39
+ ) -> LogRecord:
38
40
  """Creates a User event
39
41
  https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#user-event
40
42
  """
@@ -43,8 +45,8 @@ def user_event(
43
45
  }
44
46
  if content is not None:
45
47
  body["content"] = content
46
- return Event(
47
- name="gen_ai.user.message",
48
+ return LogRecord(
49
+ event_name="gen_ai.user.message",
48
50
  attributes={
49
51
  gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value,
50
52
  },
@@ -56,7 +58,7 @@ def assistant_event(
56
58
  *,
57
59
  role: str = "assistant",
58
60
  content: AnyValue = None,
59
- ) -> Event:
61
+ ) -> LogRecord:
60
62
  """Creates an Assistant event
61
63
  https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#assistant-event
62
64
  """
@@ -65,8 +67,8 @@ def assistant_event(
65
67
  }
66
68
  if content is not None:
67
69
  body["content"] = content
68
- return Event(
69
- name="gen_ai.assistant.message",
70
+ return LogRecord(
71
+ event_name="gen_ai.assistant.message",
70
72
  attributes={
71
73
  gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value,
72
74
  },
@@ -78,7 +80,7 @@ def system_event(
78
80
  *,
79
81
  role: str = "system",
80
82
  content: AnyValue = None,
81
- ) -> Event:
83
+ ) -> LogRecord:
82
84
  """Creates a System event
83
85
  https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#system-event
84
86
  """
@@ -87,8 +89,8 @@ def system_event(
87
89
  }
88
90
  if content is not None:
89
91
  body["content"] = content
90
- return Event(
91
- name="gen_ai.system.message",
92
+ return LogRecord(
93
+ event_name="gen_ai.system.message",
92
94
  attributes={
93
95
  gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value,
94
96
  },
@@ -101,7 +103,7 @@ def tool_event(
101
103
  role: str | None,
102
104
  id_: str,
103
105
  content: AnyValue = None,
104
- ) -> Event:
106
+ ) -> LogRecord:
105
107
  """Creates a Tool message event
106
108
  https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#event-gen_aitoolmessage
107
109
  """
@@ -114,8 +116,8 @@ def tool_event(
114
116
  }
115
117
  if content is not None:
116
118
  body["content"] = content
117
- return Event(
118
- name="gen_ai.tool.message",
119
+ return LogRecord(
120
+ event_name="gen_ai.tool.message",
119
121
  attributes={
120
122
  gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value,
121
123
  },
@@ -156,7 +158,7 @@ def choice_event(
156
158
  index: int,
157
159
  message: ChoiceMessage,
158
160
  tool_calls: Iterable[ChoiceToolCall] = (),
159
- ) -> Event:
161
+ ) -> LogRecord:
160
162
  """Creates a choice event, which describes the Gen AI response message.
161
163
  https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#event-gen_aichoice
162
164
  """
@@ -172,8 +174,8 @@ def choice_event(
172
174
  if tool_calls_list:
173
175
  body["tool_calls"] = tool_calls_list
174
176
 
175
- return Event(
176
- name="gen_ai.choice",
177
+ return LogRecord(
178
+ event_name="gen_ai.choice",
177
179
  attributes={
178
180
  gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value,
179
181
  },