From b30f5a69226310b11a7979d19e63e3b0aa873737 Mon Sep 17 00:00:00 2001 From: Matthew Tang Date: Tue, 12 Mar 2024 14:55:00 -0700 Subject: [PATCH] feat: Add custom tool context manager for telemetry PiperOrigin-RevId: 615181941 --- google/cloud/aiplatform/initializer.py | 5 +++ google/cloud/aiplatform/telemetry.py | 60 ++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 google/cloud/aiplatform/telemetry.py diff --git a/google/cloud/aiplatform/initializer.py b/google/cloud/aiplatform/initializer.py index 16a8249558..e3275cb8e2 100644 --- a/google/cloud/aiplatform/initializer.py +++ b/google/cloud/aiplatform/initializer.py @@ -36,6 +36,7 @@ from google.cloud.aiplatform.metadata import metadata from google.cloud.aiplatform.utils import resource_manager_utils from google.cloud.aiplatform.tensorboard import tensorboard_resource +from google.cloud.aiplatform import telemetry from google.cloud.aiplatform.compat.types import ( encryption_spec as gca_encryption_spec_compat, @@ -478,6 +479,10 @@ def create_client( except Exception: # pylint: disable=broad-exception-caught pass + if telemetry._tool_names_to_append: + # Must append to gapic_version due to b/259738581. + gapic_version = f"{gapic_version}+tools+{'+'.join(telemetry._tool_names_to_append[::-1])}" + user_agent = f"{constants.USER_AGENT_PRODUCT}/{gapic_version}" if appended_user_agent: user_agent = f"{user_agent} {' '.join(appended_user_agent)}" diff --git a/google/cloud/aiplatform/telemetry.py b/google/cloud/aiplatform/telemetry.py new file mode 100644 index 0000000000..f8002de007 --- /dev/null +++ b/google/cloud/aiplatform/telemetry.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import contextlib + +_tool_names_to_append = [] + + +@contextlib.contextmanager +def tool_context_manager(tool_name: str) -> None: + """Context manager for appending tool name to client instantiations. + + Most client instantiations occur at construction time. There are a few + exceptions such as generate_content that uses lazy instantiation at + inference time (b/328511605). + + Example Usage: + + aiplatform.init(...) + with telemetry.tool_context_manager('ClientName'): + model = GenerativeModel("gemini-pro") + responses = model.generate_content("Why is the sky blue?", stream=True) + + Args: + tool_name: The name of the client library to attribute usage to + + Returns: + None + """ + _append_tool_name(tool_name) + try: + yield + finally: + _pop_tool_name(tool_name) + + +def _append_tool_name(tool_name: str) -> None: + _tool_names_to_append.append(tool_name) + + +def _pop_tool_name(tool_name: str) -> None: + if not _tool_names_to_append or _tool_names_to_append[-1] != tool_name: + raise RuntimeError( + "Tool context error detected. This can occur due to parallelization." + ) + _tool_names_to_append.pop()