-
Notifications
You must be signed in to change notification settings - Fork 704
Add support for async and streaming responses in the Google GenAI instrumentation #3298
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
Merged
aabmass
merged 87 commits into
open-telemetry:main
from
michaelsafyan:async_and_streaming
Mar 3, 2025
Merged
Changes from 78 commits
Commits
Show all changes
87 commits
Select commit
Hold shift + click to select a range
b72b4cd
Begin instrumentation of GenAI SDK.
michaelsafyan 74a648a
Merge branch 'open-telemetry:main' into genaisdk_instrumentation
michaelsafyan a850642
Snapshot current state.
michaelsafyan 257da64
Created minimal tests and got first test to pass.
michaelsafyan 3244258
Added test for span attributes.
michaelsafyan 431fdf5
Ensure that token counts work.
michaelsafyan b6068e2
Add more tests.
michaelsafyan 5ac2108
Make it easy to turn off instrumentation for streaming and async to a…
michaelsafyan f503787
Merge branch 'open-telemetry:main' into genaisdk_instrumentation
michaelsafyan 7fcbd8c
Add licenses and fill out main README.rst.
michaelsafyan 6ecd69c
Add a changelog file.
michaelsafyan 5bcb73a
Fill out 'requirements.txt' and 'README.rst' for the manual instrumen…
michaelsafyan 65241b0
Add missing exporter dependency for the manual instrumentation example.
michaelsafyan 44f5081
Fill out rest of the zero-code example.
michaelsafyan 5e5f226
Add minimal tests for async, streaming cases.
michaelsafyan 7b3805c
Update sync test to use indirection on top of 'client.models.generate…
michaelsafyan 3ee8dd1
Fix ruff check issues.
michaelsafyan 6b66fe4
Add subproject to top-level project build mechanism.
michaelsafyan 06ab153
Simplify invocation of pylint.
michaelsafyan 9f73c64
Fix 'make test' command and lint issues.
michaelsafyan 319f0a5
Add '.dev' suffix to version per feedback on pull request #3256
michaelsafyan 493689e
Fix README.rst files for the examples.
michaelsafyan 368a3cc
Add specific versions for the examples.
michaelsafyan 4682521
Merge branch 'main' into genaisdk_instrumentation
michaelsafyan e2afc4e
Merge branch 'open-telemetry:main' into genaisdk_instrumentation
michaelsafyan a157e2e
Revamp 'make test' to not require local 'tox.ini' configuration.
michaelsafyan dd606c2
Extend separators per review comment.
michaelsafyan a2ec3fb
Fix version conflict caused by non-hermetic requirements.
michaelsafyan 1304fed
Fix typo on the comment line.
michaelsafyan 07cbf2f
Merge branch 'open-telemetry:main' into genaisdk_instrumentation
michaelsafyan 159418e
Add test for the use of the 'vertex_ai' system, and improve how this …
michaelsafyan bf98bba
Factor out testing logic to enable sharing with the async code.
michaelsafyan e4386ad
Addressed minor lint issues.
michaelsafyan e6420b2
Make it clearer that nonstreaming_base is a helper module that is not…
michaelsafyan 86a6f0e
Merge branch 'open-telemetry:main' into genaisdk_instrumentation
michaelsafyan 23fe105
Merge branch 'open-telemetry:main' into genaisdk_instrumentation
michaelsafyan 97494b5
Integrate feedback from related pull request #3268.
michaelsafyan c006346
Update workflows with 'tox -e generate-workflows'.
michaelsafyan 038f90e
Improve data model and add some rudimentary type checking.
michaelsafyan 7647992
Accept only 'true' for a true value to align with other code.
michaelsafyan e678135
Merge branch 'main' into genaisdk_instrumentation
michaelsafyan c834e97
Update the scope name used.
michaelsafyan 6ae0525
Add **kwargs to patched methods to prevent future breakage due to the…
michaelsafyan 1a8cad9
Remove redundant list conversion in call to "sorted".
michaelsafyan 00d2d9f
Reformat with 'tox -e ruff'.
michaelsafyan f0ca9ae
Fix failing lint workflow.
michaelsafyan 016596e
Fix failing lint workflow.
michaelsafyan 19c2627
Exclude Google GenAI instrumentation from the bootstrap code for now.
michaelsafyan d2a42bd
Minor improvements to the tooling shell files.
michaelsafyan ab36068
Fix typo flagged by codespell spellchecker.
michaelsafyan 117c811
Increase alignment with broader repo practices.
michaelsafyan a761858
Add more TODOs and documentation to clarify the intended work scope.
michaelsafyan 94ee68b
Remove unneeded accessor from OTelWrapper.
michaelsafyan fe5a19c
Add more comments to the tests.
michaelsafyan 3fc667e
Reformat with ruff.
michaelsafyan f240b85
Change 'desireable' to 'desirable' per codespell spellchecker.
michaelsafyan b263ae7
Make tests pass without pythonpath
aabmass 567adc6
Fix new lint errors showing up after change
aabmass 62c4963
Revert "Fix new lint errors showing up after change"
aabmass 918341f
Merge pull request #1 from aabmass/genaisdk_instrumentation-pythonpat…
michaelsafyan 82c832b
Add TODO item required/requested from code review.
michaelsafyan a8e8739
Resolve merge conflict.
michaelsafyan 25aa401
Simplify changelog per PR feedback.
michaelsafyan 4adef35
Remove square brackets from model name in span name per PR feedback.
michaelsafyan 08c84bb
Merge branch 'main' into genaisdk_instrumentation
michaelsafyan 654c0d9
Merge branch 'main' into genaisdk_instrumentation
michaelsafyan e654b89
Merge branch 'open-telemetry:main' into genaisdk_instrumentation
michaelsafyan 1415f2c
Checkpoint current state.
michaelsafyan 1a01b79
Misc test cleanup. Now that scripts are invoked solely through pytest…
michaelsafyan 194f0b0
Improve quality of event logging.
michaelsafyan 51bd151
Resolve merge conflict.
michaelsafyan 5129b6f
Implement streaming support in RequestsMocker, get tests passing again.
michaelsafyan c492776
Add test with multiple responses.
michaelsafyan cce005d
Remove support for async and streaming from TODOs, since this is now …
michaelsafyan 1403bdf
Increase testing coverage for streaming.
michaelsafyan da9a98d
Resolve merge conflicts.
michaelsafyan 8c8b204
Reformat with ruff.
michaelsafyan 980bf1a
Add minor version bump with changelog.
michaelsafyan 119505f
Merge branch 'open-telemetry:main' into async_and_streaming
michaelsafyan 19146a5
Change TODOs to bulleted list.
michaelsafyan ae289d5
Update per PR feedback
michaelsafyan 94d1cd2
Restructure streaming async logic to begin execution earlier.
michaelsafyan 4b1f244
Reformat with ruff.
michaelsafyan f0e4574
Merge branch 'main' into async_and_streaming
michaelsafyan 3dc2734
Disable pylint check for catching broad exception. Should be allowed …
michaelsafyan 0d64c2f
Simplify async streaming solution per PR comment.
michaelsafyan 523000c
Merge branch 'main' into async_and_streaming
aabmass File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
...genai/opentelemetry-instrumentation-google-genai/tests/generate_content/streaming_base.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Copyright The OpenTelemetry Authors | ||
# | ||
# 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 unittest | ||
|
||
from ..common.base import TestCase | ||
from .util import create_valid_response | ||
|
||
|
||
class StreamingTestCase(TestCase): | ||
# The "setUp" function is defined by "unittest.TestCase" and thus | ||
# this name must be used. Uncertain why pylint doesn't seem to | ||
# recognize that this is a unit test class for which this is inherited. | ||
def setUp(self): # pylint: disable=invalid-name | ||
super().setUp() | ||
if self.__class__ == StreamingTestCase: | ||
raise unittest.SkipTest("Skipping testcase base.") | ||
|
||
def generate_content(self, *args, **kwargs): | ||
raise NotImplementedError("Must implement 'generate_content'.") | ||
|
||
@property | ||
def expected_function_name(self): | ||
raise NotImplementedError("Must implement 'expected_function_name'.") | ||
|
||
def configure_valid_response(self, *args, **kwargs): | ||
self.requests.add_response(create_valid_response(*args, **kwargs)) | ||
|
||
def test_instrumentation_does_not_break_core_functionality(self): | ||
self.configure_valid_response(response_text="Yep, it works!") | ||
responses = self.generate_content( | ||
model="gemini-2.0-flash", contents="Does this work?" | ||
) | ||
self.assertEqual(len(responses), 1) | ||
response = responses[0] | ||
self.assertEqual(response.text, "Yep, it works!") | ||
|
||
def test_handles_multiple_ressponses(self): | ||
self.configure_valid_response(response_text="First response") | ||
self.configure_valid_response(response_text="Second response") | ||
responses = self.generate_content( | ||
model="gemini-2.0-flash", contents="Does this work?" | ||
) | ||
self.assertEqual(len(responses), 2) | ||
self.assertEqual(responses[0].text, "First response") | ||
self.assertEqual(responses[1].text, "Second response") | ||
choice_events = self.otel.get_events_named("gen_ai.choice") | ||
self.assertEqual(len(choice_events), 2) | ||
|
||
def test_includes_token_counts_in_span_aggregated_from_responses(self): | ||
# Configure multiple responses whose input/output tokens should be | ||
# accumulated together when summarizing the end-to-end request. | ||
# | ||
# Input: 1 + 3 + 5 => 4 + 5 => 9 | ||
# Output: 2 + 4 + 6 => 6 + 6 => 12 | ||
self.configure_valid_response(input_tokens=1, output_tokens=2) | ||
self.configure_valid_response(input_tokens=3, output_tokens=4) | ||
self.configure_valid_response(input_tokens=5, output_tokens=6) | ||
|
||
self.generate_content(model="gemini-2.0-flash", contents="Some input") | ||
|
||
self.otel.assert_has_span_named("generate_content gemini-2.0-flash") | ||
span = self.otel.get_span_named("generate_content gemini-2.0-flash") | ||
self.assertEqual(span.attributes["gen_ai.usage.input_tokens"], 9) | ||
self.assertEqual(span.attributes["gen_ai.usage.output_tokens"], 12) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.