diff --git a/alloydb/notebooks/noxfile_config.py b/alloydb/notebooks/noxfile_config.py index f5bc1ea9e2f..7f53f031cd7 100644 --- a/alloydb/notebooks/noxfile_config.py +++ b/alloydb/notebooks/noxfile_config.py @@ -14,7 +14,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.11", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/alloydb/notebooks/requirements-test.txt b/alloydb/notebooks/requirements-test.txt index ba12393197f..0a11cd35d0d 100644 --- a/alloydb/notebooks/requirements-test.txt +++ b/alloydb/notebooks/requirements-test.txt @@ -1,6 +1,6 @@ -google-cloud-alloydb-connector[asyncpg]==1.5.0 +google-cloud-alloydb-connector[asyncpg]==1.12.1 sqlalchemy==2.0.40 -pytest==8.3.3 +pytest==9.0.3; python_version >= "3.10" ipykernel==6.29.5 -pytest-asyncio==0.24.0 +pytest-asyncio==1.3.0 nbconvert==7.16.6 \ No newline at end of file diff --git a/aml-ai/requirements-test.txt b/aml-ai/requirements-test.txt index 060ed652e0b..c9e154ba440 100644 --- a/aml-ai/requirements-test.txt +++ b/aml-ai/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 \ No newline at end of file +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/analytics/noxfile_config.py b/appengine/flexible/analytics/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/analytics/noxfile_config.py +++ b/appengine/flexible/analytics/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/analytics/requirements-test.txt b/appengine/flexible/analytics/requirements-test.txt index 0a501624ec5..a4cc4887361 100644 --- a/appengine/flexible/analytics/requirements-test.txt +++ b/appengine/flexible/analytics/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" responses==0.23.1 diff --git a/appengine/flexible/datastore/noxfile_config.py b/appengine/flexible/datastore/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/datastore/noxfile_config.py +++ b/appengine/flexible/datastore/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/datastore/requirements-test.txt b/appengine/flexible/datastore/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/datastore/requirements-test.txt +++ b/appengine/flexible/datastore/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/django_cloudsql/noxfile_config.py b/appengine/flexible/django_cloudsql/noxfile_config.py index 60e19bd8a96..4f10cf1a8f6 100644 --- a/appengine/flexible/django_cloudsql/noxfile_config.py +++ b/appengine/flexible/django_cloudsql/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/appengine/flexible/django_cloudsql/requirements-test.txt b/appengine/flexible/django_cloudsql/requirements-test.txt index 5e5d2c73a81..75ff3b9675d 100644 --- a/appengine/flexible/django_cloudsql/requirements-test.txt +++ b/appengine/flexible/django_cloudsql/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-django==4.9.0 diff --git a/appengine/flexible/hello_world/noxfile_config.py b/appengine/flexible/hello_world/noxfile_config.py index ae3ed14dc36..0973c8621c7 100644 --- a/appengine/flexible/hello_world/noxfile_config.py +++ b/appengine/flexible/hello_world/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/appengine/flexible/hello_world/requirements-test.txt b/appengine/flexible/hello_world/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/hello_world/requirements-test.txt +++ b/appengine/flexible/hello_world/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/hello_world_django/noxfile_config.py b/appengine/flexible/hello_world_django/noxfile_config.py index 692b834f789..949abebe3ea 100644 --- a/appengine/flexible/hello_world_django/noxfile_config.py +++ b/appengine/flexible/hello_world_django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/hello_world_django/requirements-test.txt b/appengine/flexible/hello_world_django/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/hello_world_django/requirements-test.txt +++ b/appengine/flexible/hello_world_django/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/metadata/noxfile_config.py b/appengine/flexible/metadata/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/metadata/noxfile_config.py +++ b/appengine/flexible/metadata/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/metadata/requirements-test.txt b/appengine/flexible/metadata/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/metadata/requirements-test.txt +++ b/appengine/flexible/metadata/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/multiple_services/gateway-service/noxfile_config.py b/appengine/flexible/multiple_services/gateway-service/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/multiple_services/gateway-service/noxfile_config.py +++ b/appengine/flexible/multiple_services/gateway-service/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/multiple_services/gateway-service/requirements-test.txt b/appengine/flexible/multiple_services/gateway-service/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/multiple_services/gateway-service/requirements-test.txt +++ b/appengine/flexible/multiple_services/gateway-service/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/multiple_services/static-service/noxfile_config.py b/appengine/flexible/multiple_services/static-service/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/multiple_services/static-service/noxfile_config.py +++ b/appengine/flexible/multiple_services/static-service/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/multiple_services/static-service/requirements-test.txt b/appengine/flexible/multiple_services/static-service/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/multiple_services/static-service/requirements-test.txt +++ b/appengine/flexible/multiple_services/static-service/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/numpy/noxfile_config.py b/appengine/flexible/numpy/noxfile_config.py index 5f744eddc83..949abebe3ea 100644 --- a/appengine/flexible/numpy/noxfile_config.py +++ b/appengine/flexible/numpy/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/numpy/requirements-test.txt b/appengine/flexible/numpy/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/numpy/requirements-test.txt +++ b/appengine/flexible/numpy/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/pubsub/noxfile_config.py b/appengine/flexible/pubsub/noxfile_config.py index 501440bf378..eb510f7a4b8 100644 --- a/appengine/flexible/pubsub/noxfile_config.py +++ b/appengine/flexible/pubsub/noxfile_config.py @@ -23,7 +23,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # Skipping for Python 3.9 due to pyarrow compilation failure. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/pubsub/requirements-test.txt b/appengine/flexible/pubsub/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/pubsub/requirements-test.txt +++ b/appengine/flexible/pubsub/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/scipy/noxfile_config.py b/appengine/flexible/scipy/noxfile_config.py index fa718fc163c..6abbd44a54a 100644 --- a/appengine/flexible/scipy/noxfile_config.py +++ b/appengine/flexible/scipy/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.11", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/scipy/requirements-test.txt b/appengine/flexible/scipy/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/scipy/requirements-test.txt +++ b/appengine/flexible/scipy/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/static_files/noxfile_config.py b/appengine/flexible/static_files/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/static_files/noxfile_config.py +++ b/appengine/flexible/static_files/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/static_files/requirements-test.txt b/appengine/flexible/static_files/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/static_files/requirements-test.txt +++ b/appengine/flexible/static_files/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/storage/noxfile_config.py b/appengine/flexible/storage/noxfile_config.py index 972f04d9a4d..addd1f2d00e 100644 --- a/appengine/flexible/storage/noxfile_config.py +++ b/appengine/flexible/storage/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/appengine/flexible/storage/requirements-test.txt b/appengine/flexible/storage/requirements-test.txt index f27726d7455..3b2c5a8f638 100644 --- a/appengine/flexible/storage/requirements-test.txt +++ b/appengine/flexible/storage/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-cloud-storage==2.9.0 diff --git a/appengine/flexible/tasks/Dockerfile b/appengine/flexible/tasks/Dockerfile index 5aaeb51144d..10d577925a9 100644 --- a/appengine/flexible/tasks/Dockerfile +++ b/appengine/flexible/tasks/Dockerfile @@ -14,7 +14,7 @@ # Use the official Python image. # https://hub.docker.com/_/python -FROM python:3.11 +FROM python:3.14 # Copy local code to the container image. ENV APP_HOME /app diff --git a/appengine/flexible/tasks/noxfile_config.py b/appengine/flexible/tasks/noxfile_config.py index 196376e7023..93284075acd 100644 --- a/appengine/flexible/tasks/noxfile_config.py +++ b/appengine/flexible/tasks/noxfile_config.py @@ -22,7 +22,8 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/tasks/requirements-test.txt b/appengine/flexible/tasks/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/appengine/flexible/tasks/requirements-test.txt +++ b/appengine/flexible/tasks/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/flexible/twilio/noxfile_config.py b/appengine/flexible/twilio/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/twilio/noxfile_config.py +++ b/appengine/flexible/twilio/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/twilio/requirements-test.txt b/appengine/flexible/twilio/requirements-test.txt index 0a501624ec5..a4cc4887361 100644 --- a/appengine/flexible/twilio/requirements-test.txt +++ b/appengine/flexible/twilio/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" responses==0.23.1 diff --git a/appengine/flexible/websockets/noxfile_config.py b/appengine/flexible/websockets/noxfile_config.py index 196376e7023..949abebe3ea 100644 --- a/appengine/flexible/websockets/noxfile_config.py +++ b/appengine/flexible/websockets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/websockets/requirements-test.txt b/appengine/flexible/websockets/requirements-test.txt index 92b9194cf63..884df6e946a 100644 --- a/appengine/flexible/websockets/requirements-test.txt +++ b/appengine/flexible/websockets/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" retrying==1.3.4 websocket-client==1.7.0 diff --git a/appengine/standard/analytics/requirements-test.txt b/appengine/standard/analytics/requirements-test.txt index 30b5b4c9f19..1f1919df7e1 100644 --- a/appengine/standard/analytics/requirements-test.txt +++ b/appengine/standard/analytics/requirements-test.txt @@ -1,4 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" responses==0.17.0; python_version < '3.7' responses==0.23.1; python_version > '3.6' diff --git a/appengine/standard/blobstore/blobreader/requirements-test.txt b/appengine/standard/blobstore/blobreader/requirements-test.txt index c607ba3b2ab..201a14af7e3 100644 --- a/appengine/standard/blobstore/blobreader/requirements-test.txt +++ b/appengine/standard/blobstore/blobreader/requirements-test.txt @@ -1,3 +1,2 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" WebTest==2.0.35; python_version < '3.0' diff --git a/appengine/standard/blobstore/gcs/requirements-test.txt b/appengine/standard/blobstore/gcs/requirements-test.txt index c607ba3b2ab..201a14af7e3 100644 --- a/appengine/standard/blobstore/gcs/requirements-test.txt +++ b/appengine/standard/blobstore/gcs/requirements-test.txt @@ -1,3 +1,2 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" WebTest==2.0.35; python_version < '3.0' diff --git a/appengine/standard/endpoints-frameworks-v2/echo/requirements-test.txt b/appengine/standard/endpoints-frameworks-v2/echo/requirements-test.txt index b45b8adfc17..c6c555e9b7d 100644 --- a/appengine/standard/endpoints-frameworks-v2/echo/requirements-test.txt +++ b/appengine/standard/endpoints-frameworks-v2/echo/requirements-test.txt @@ -1,5 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' -pytest==8.3.2; python_version >= '3.0' +pytest==9.0.3; python_version >= "3.10" mock==3.0.5; python_version < '3.0' mock==5.1.0; python_version >= '3.0' diff --git a/appengine/standard/endpoints-frameworks-v2/iata/requirements-test.txt b/appengine/standard/endpoints-frameworks-v2/iata/requirements-test.txt index 7439fc43d48..c9e154ba440 100644 --- a/appengine/standard/endpoints-frameworks-v2/iata/requirements-test.txt +++ b/appengine/standard/endpoints-frameworks-v2/iata/requirements-test.txt @@ -1,2 +1 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard/endpoints-frameworks-v2/quickstart/requirements-test.txt b/appengine/standard/endpoints-frameworks-v2/quickstart/requirements-test.txt index b45b8adfc17..c6c555e9b7d 100644 --- a/appengine/standard/endpoints-frameworks-v2/quickstart/requirements-test.txt +++ b/appengine/standard/endpoints-frameworks-v2/quickstart/requirements-test.txt @@ -1,5 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' -pytest==8.3.2; python_version >= '3.0' +pytest==9.0.3; python_version >= "3.10" mock==3.0.5; python_version < '3.0' mock==5.1.0; python_version >= '3.0' diff --git a/appengine/standard/firebase/firenotes/backend/requirements-test.txt b/appengine/standard/firebase/firenotes/backend/requirements-test.txt index b45b8adfc17..c6c555e9b7d 100644 --- a/appengine/standard/firebase/firenotes/backend/requirements-test.txt +++ b/appengine/standard/firebase/firenotes/backend/requirements-test.txt @@ -1,5 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' -pytest==8.3.2; python_version >= '3.0' +pytest==9.0.3; python_version >= "3.10" mock==3.0.5; python_version < '3.0' mock==5.1.0; python_version >= '3.0' diff --git a/appengine/standard/flask/hello_world/requirements-test.txt b/appengine/standard/flask/hello_world/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/flask/hello_world/requirements-test.txt +++ b/appengine/standard/flask/hello_world/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/iap/requirements-test.txt b/appengine/standard/iap/requirements-test.txt index 2bdf05ee6cd..645c7b65f82 100644 --- a/appengine/standard/iap/requirements-test.txt +++ b/appengine/standard/iap/requirements-test.txt @@ -1,5 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' -pytest==8.3.2; python_version >= '3.0' +pytest==9.0.3; python_version >= "3.10" WebTest==2.0.35; python_version < '3.0' six==1.16.0 diff --git a/appengine/standard/images/api/requirements-test.txt b/appengine/standard/images/api/requirements-test.txt index e32096ac3f2..e44de1e709c 100644 --- a/appengine/standard/images/api/requirements-test.txt +++ b/appengine/standard/images/api/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.3.5 +pytest==9.0.3; python_version >= "3.10" six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/memcache/guestbook/requirements-test.txt b/appengine/standard/memcache/guestbook/requirements-test.txt index fc0672f932b..e44de1e709c 100644 --- a/appengine/standard/memcache/guestbook/requirements-test.txt +++ b/appengine/standard/memcache/guestbook/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.3.4 +pytest==9.0.3; python_version >= "3.10" six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/memcache/snippets/requirements-test.txt b/appengine/standard/memcache/snippets/requirements-test.txt index fc0672f932b..e44de1e709c 100644 --- a/appengine/standard/memcache/snippets/requirements-test.txt +++ b/appengine/standard/memcache/snippets/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.3.4 +pytest==9.0.3; python_version >= "3.10" six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/migration/incoming/requirements-test.txt b/appengine/standard/migration/incoming/requirements-test.txt index 9dddb06acfc..81aa28131ef 100644 --- a/appengine/standard/migration/incoming/requirements-test.txt +++ b/appengine/standard/migration/incoming/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.3.5 +pytest==9.0.3; python_version >= "3.10" WebTest==3.0.4 diff --git a/appengine/standard/migration/memorystore/requirements-test.txt b/appengine/standard/migration/memorystore/requirements-test.txt index 97587b45b12..8f9dd472203 100644 --- a/appengine/standard/migration/memorystore/requirements-test.txt +++ b/appengine/standard/migration/memorystore/requirements-test.txt @@ -1,6 +1,4 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' -pytest==8.3.2; python_version >= '3.0' +pytest==9.0.3; python_version >= "3.10" mock==5.0.2; python_version > '3.0' mock==3.0.5; python_version < '3.0' six==1.16.0 diff --git a/appengine/standard/migration/ndb/overview/requirements-test.txt b/appengine/standard/migration/ndb/overview/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/migration/ndb/overview/requirements-test.txt +++ b/appengine/standard/migration/ndb/overview/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/migration/ndb/redis_cache/requirements-test.txt b/appengine/standard/migration/ndb/redis_cache/requirements-test.txt index 729e42b9a2e..325a4c49696 100644 --- a/appengine/standard/migration/ndb/redis_cache/requirements-test.txt +++ b/appengine/standard/migration/ndb/redis_cache/requirements-test.txt @@ -1,7 +1,5 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" # 2025-01-14 Adds support for Python3. -pytest==8.3.2; python_version >= '3.0' WebTest==3.0.1; python_version >= '3.0' six==1.16.0 \ No newline at end of file diff --git a/appengine/standard/migration/storage/requirements-test.txt b/appengine/standard/migration/storage/requirements-test.txt index 7439fc43d48..c9e154ba440 100644 --- a/appengine/standard/migration/storage/requirements-test.txt +++ b/appengine/standard/migration/storage/requirements-test.txt @@ -1,2 +1 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard/migration/taskqueue/pull-counter/requirements-test.txt b/appengine/standard/migration/taskqueue/pull-counter/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/migration/taskqueue/pull-counter/requirements-test.txt +++ b/appengine/standard/migration/taskqueue/pull-counter/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/migration/urlfetch/async/requirements-test.txt b/appengine/standard/migration/urlfetch/async/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/migration/urlfetch/async/requirements-test.txt +++ b/appengine/standard/migration/urlfetch/async/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/migration/urlfetch/requests/requirements-test.txt b/appengine/standard/migration/urlfetch/requests/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/migration/urlfetch/requests/requirements-test.txt +++ b/appengine/standard/migration/urlfetch/requests/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/ndb/overview/requirements-test.txt b/appengine/standard/ndb/overview/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/ndb/overview/requirements-test.txt +++ b/appengine/standard/ndb/overview/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/ndb/transactions/requirements-test.txt b/appengine/standard/ndb/transactions/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/ndb/transactions/requirements-test.txt +++ b/appengine/standard/ndb/transactions/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/noxfile_config.py b/appengine/standard/noxfile_config.py index f39811085fa..c58186d0158 100644 --- a/appengine/standard/noxfile_config.py +++ b/appengine/standard/noxfile_config.py @@ -24,7 +24,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["3.6", "3.7", "3.8", "3.10", "3.11", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard/taskqueue/counter/requirements-test.txt b/appengine/standard/taskqueue/counter/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/taskqueue/counter/requirements-test.txt +++ b/appengine/standard/taskqueue/counter/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/taskqueue/pull-counter/requirements-test.txt b/appengine/standard/taskqueue/pull-counter/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/taskqueue/pull-counter/requirements-test.txt +++ b/appengine/standard/taskqueue/pull-counter/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/urlfetch/async/requirements-test.txt b/appengine/standard/urlfetch/async/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/urlfetch/async/requirements-test.txt +++ b/appengine/standard/urlfetch/async/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/urlfetch/requests/requirements-test.txt b/appengine/standard/urlfetch/requests/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/urlfetch/requests/requirements-test.txt +++ b/appengine/standard/urlfetch/requests/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/urlfetch/snippets/requirements-test.txt b/appengine/standard/urlfetch/snippets/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/urlfetch/snippets/requirements-test.txt +++ b/appengine/standard/urlfetch/snippets/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard/users/requirements-test.txt b/appengine/standard/users/requirements-test.txt index 454c88a573a..e7fb62924c9 100644 --- a/appengine/standard/users/requirements-test.txt +++ b/appengine/standard/users/requirements-test.txt @@ -1,6 +1,3 @@ -# pin pytest to 4.6.11 for Python2. -pytest==4.6.11; python_version < '3.0' +pytest==9.0.3; python_version >= "3.10" -# pytest==8.3.4 and six==1.17.0 for Python3. -pytest==8.3.4; python_version >= '3.0' six==1.17.0 \ No newline at end of file diff --git a/appengine/standard_python3/bigquery/noxfile_config.py b/appengine/standard_python3/bigquery/noxfile_config.py index 3428b4ef27a..5dbb51286c6 100644 --- a/appengine/standard_python3/bigquery/noxfile_config.py +++ b/appengine/standard_python3/bigquery/noxfile_config.py @@ -23,7 +23,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # There's no google-cloud-bigquery package for Python 3.9. - "ignored_versions": ["2.7", "3.6", "3.9", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bigquery/requirements-test.txt b/appengine/standard_python3/bigquery/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/bigquery/requirements-test.txt +++ b/appengine/standard_python3/bigquery/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/building-an-app/building-an-app-1/requirements-test.txt b/appengine/standard_python3/building-an-app/building-an-app-1/requirements-test.txt index c987bcfee7e..c9e154ba440 100644 --- a/appengine/standard_python3/building-an-app/building-an-app-1/requirements-test.txt +++ b/appengine/standard_python3/building-an-app/building-an-app-1/requirements-test.txt @@ -1,2 +1 @@ -pytest==7.0.1; python_version == '3.9' -pytest==9.0.2; python_version >= '3.10' +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/building-an-app/building-an-app-2/requirements-test.txt b/appengine/standard_python3/building-an-app/building-an-app-2/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/building-an-app/building-an-app-2/requirements-test.txt +++ b/appengine/standard_python3/building-an-app/building-an-app-2/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/building-an-app/building-an-app-3/requirements-test.txt b/appengine/standard_python3/building-an-app/building-an-app-3/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/building-an-app/building-an-app-3/requirements-test.txt +++ b/appengine/standard_python3/building-an-app/building-an-app-3/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/building-an-app/building-an-app-4/requirements-test.txt b/appengine/standard_python3/building-an-app/building-an-app-4/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/building-an-app/building-an-app-4/requirements-test.txt +++ b/appengine/standard_python3/building-an-app/building-an-app-4/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/bundled-services/blobstore/django/noxfile_config.py b/appengine/standard_python3/bundled-services/blobstore/django/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/blobstore/django/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/blobstore/django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/blobstore/django/requirements-test.txt b/appengine/standard_python3/bundled-services/blobstore/django/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/blobstore/django/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/blobstore/django/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/blobstore/django/requirements.txt b/appengine/standard_python3/bundled-services/blobstore/django/requirements.txt index c616634cafe..0dca8b45f05 100644 --- a/appengine/standard_python3/bundled-services/blobstore/django/requirements.txt +++ b/appengine/standard_python3/bundled-services/blobstore/django/requirements.txt @@ -1,4 +1,4 @@ -Django==5.1.9; python_version >= "3.10" +Django==5.1.15; python_version >= "3.10" Django==4.2.16; python_version < "3.10" django-environ==0.10.0 google-cloud-logging==3.5.0 diff --git a/appengine/standard_python3/bundled-services/blobstore/flask/noxfile_config.py b/appengine/standard_python3/bundled-services/blobstore/flask/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/blobstore/flask/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/blobstore/flask/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/blobstore/flask/requirements-test.txt b/appengine/standard_python3/bundled-services/blobstore/flask/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/blobstore/flask/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/blobstore/flask/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/blobstore/wsgi/noxfile_config.py b/appengine/standard_python3/bundled-services/blobstore/wsgi/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/blobstore/wsgi/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/blobstore/wsgi/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/blobstore/wsgi/requirements-test.txt b/appengine/standard_python3/bundled-services/blobstore/wsgi/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/blobstore/wsgi/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/blobstore/wsgi/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/deferred/django/noxfile_config.py b/appengine/standard_python3/bundled-services/deferred/django/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/deferred/django/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/deferred/django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/deferred/django/requirements-test.txt b/appengine/standard_python3/bundled-services/deferred/django/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/deferred/django/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/deferred/django/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/deferred/flask/noxfile_config.py b/appengine/standard_python3/bundled-services/deferred/flask/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/deferred/flask/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/deferred/flask/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/deferred/flask/requirements-test.txt b/appengine/standard_python3/bundled-services/deferred/flask/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/deferred/flask/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/deferred/flask/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/deferred/wsgi/noxfile_config.py b/appengine/standard_python3/bundled-services/deferred/wsgi/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/deferred/wsgi/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/deferred/wsgi/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/deferred/wsgi/requirements-test.txt b/appengine/standard_python3/bundled-services/deferred/wsgi/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/deferred/wsgi/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/deferred/wsgi/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/mail/django/noxfile_config.py b/appengine/standard_python3/bundled-services/mail/django/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/mail/django/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/mail/django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/mail/django/requirements-test.txt b/appengine/standard_python3/bundled-services/mail/django/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/mail/django/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/mail/django/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/mail/django/requirements.txt b/appengine/standard_python3/bundled-services/mail/django/requirements.txt index bdd07a4620e..d5731eb8861 100644 --- a/appengine/standard_python3/bundled-services/mail/django/requirements.txt +++ b/appengine/standard_python3/bundled-services/mail/django/requirements.txt @@ -1,4 +1,4 @@ -Django==5.1.13; python_version >= "3.10" +Django==5.1.15; python_version >= "3.10" Django==4.2.16; python_version >= "3.8" and python_version < "3.10" Django==3.2.25; python_version < "3.8" django-environ==0.10.0 diff --git a/appengine/standard_python3/bundled-services/mail/flask/noxfile_config.py b/appengine/standard_python3/bundled-services/mail/flask/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/mail/flask/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/mail/flask/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/mail/flask/requirements-test.txt b/appengine/standard_python3/bundled-services/mail/flask/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/mail/flask/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/mail/flask/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/bundled-services/mail/wsgi/noxfile_config.py b/appengine/standard_python3/bundled-services/mail/wsgi/noxfile_config.py index 1bde00988d8..99047da44a9 100644 --- a/appengine/standard_python3/bundled-services/mail/wsgi/noxfile_config.py +++ b/appengine/standard_python3/bundled-services/mail/wsgi/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/standard_python3/bundled-services/mail/wsgi/requirements-test.txt b/appengine/standard_python3/bundled-services/mail/wsgi/requirements-test.txt index b83aedab5dd..b8e94617358 100644 --- a/appengine/standard_python3/bundled-services/mail/wsgi/requirements-test.txt +++ b/appengine/standard_python3/bundled-services/mail/wsgi/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" requests==2.28.2 \ No newline at end of file diff --git a/appengine/standard_python3/cloudsql/requirements-test.txt b/appengine/standard_python3/cloudsql/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/cloudsql/requirements-test.txt +++ b/appengine/standard_python3/cloudsql/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/custom-server/requirements-test.txt b/appengine/standard_python3/custom-server/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/custom-server/requirements-test.txt +++ b/appengine/standard_python3/custom-server/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/django/noxfile_config.py b/appengine/standard_python3/django/noxfile_config.py index b05bde23ec6..2e8aab8cdeb 100644 --- a/appengine/standard_python3/django/noxfile_config.py +++ b/appengine/standard_python3/django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/appengine/standard_python3/django/requirements-test.txt b/appengine/standard_python3/django/requirements-test.txt index 99bb7d24ca4..5279f42cfd4 100644 --- a/appengine/standard_python3/django/requirements-test.txt +++ b/appengine/standard_python3/django/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" pytest-django==4.5.0 diff --git a/appengine/standard_python3/hello_world/requirements-test.txt b/appengine/standard_python3/hello_world/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/hello_world/requirements-test.txt +++ b/appengine/standard_python3/hello_world/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/migration/urlfetch/requirements-test.txt b/appengine/standard_python3/migration/urlfetch/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/migration/urlfetch/requirements-test.txt +++ b/appengine/standard_python3/migration/urlfetch/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/pubsub/requirements-test.txt b/appengine/standard_python3/pubsub/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/pubsub/requirements-test.txt +++ b/appengine/standard_python3/pubsub/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/redis/requirements-test.txt b/appengine/standard_python3/redis/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/redis/requirements-test.txt +++ b/appengine/standard_python3/redis/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/spanner/requirements-test.txt b/appengine/standard_python3/spanner/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/spanner/requirements-test.txt +++ b/appengine/standard_python3/spanner/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/appengine/standard_python3/warmup/requirements-test.txt b/appengine/standard_python3/warmup/requirements-test.txt index c2845bffbe8..c9e154ba440 100644 --- a/appengine/standard_python3/warmup/requirements-test.txt +++ b/appengine/standard_python3/warmup/requirements-test.txt @@ -1 +1 @@ -pytest==7.0.1 +pytest==9.0.3; python_version >= "3.10" diff --git a/asset/snippets/noxfile_config.py b/asset/snippets/noxfile_config.py index 9a1680c88df..4eae59976e2 100644 --- a/asset/snippets/noxfile_config.py +++ b/asset/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/asset/snippets/requirements-test.txt b/asset/snippets/requirements-test.txt index d57b0bfd0ab..b85518d5117 100644 --- a/asset/snippets/requirements-test.txt +++ b/asset/snippets/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1 flaky==3.8.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/auth/api-client/requirements-test.txt b/auth/api-client/requirements-test.txt index 6ff70adf77d..975d5ee58c2 100644 --- a/auth/api-client/requirements-test.txt +++ b/auth/api-client/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" backoff==2.2.1 diff --git a/auth/cloud-client-temp/noxfile_config.py b/auth/cloud-client-temp/noxfile_config.py index e892b338fce..658f73ff360 100644 --- a/auth/cloud-client-temp/noxfile_config.py +++ b/auth/cloud-client-temp/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/auth/cloud-client-temp/requirements.txt b/auth/cloud-client-temp/requirements.txt index 8dafe853ea0..c0bda55ed4a 100644 --- a/auth/cloud-client-temp/requirements.txt +++ b/auth/cloud-client-temp/requirements.txt @@ -1,8 +1,7 @@ google-cloud-compute==1.42.0 google-cloud-storage==3.8.0 google-auth==2.47.0 -pytest===8.4.2; python_version == '3.9' -pytest==9.0.2; python_version > '3.9' +pytest==9.0.3; python_version >= "3.10" boto3>=1.26.0 requests==2.32.5 python-dotenv==1.2.1 diff --git a/auth/cloud-client/requirements-test.txt b/auth/cloud-client/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/auth/cloud-client/requirements-test.txt +++ b/auth/cloud-client/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/auth/custom-credentials/aws/Dockerfile b/auth/custom-credentials/aws/Dockerfile index d90d88aa0a8..0cd34429f50 100644 --- a/auth/custom-credentials/aws/Dockerfile +++ b/auth/custom-credentials/aws/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.13-slim +FROM python:3.14-slim RUN useradd -m appuser diff --git a/auth/custom-credentials/aws/noxfile_config.py b/auth/custom-credentials/aws/noxfile_config.py index 0ed973689f7..526763fbcc9 100644 --- a/auth/custom-credentials/aws/noxfile_config.py +++ b/auth/custom-credentials/aws/noxfile_config.py @@ -13,5 +13,6 @@ # limitations under the License. TEST_CONFIG_OVERRIDE = { - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], } diff --git a/auth/custom-credentials/aws/requirements-test.txt b/auth/custom-credentials/aws/requirements-test.txt index 43b24059d3e..8e23e776847 100644 --- a/auth/custom-credentials/aws/requirements-test.txt +++ b/auth/custom-credentials/aws/requirements-test.txt @@ -1,2 +1,2 @@ -r requirements.txt -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/auth/custom-credentials/okta/noxfile_config.py b/auth/custom-credentials/okta/noxfile_config.py index 0ed973689f7..379d24818b5 100644 --- a/auth/custom-credentials/okta/noxfile_config.py +++ b/auth/custom-credentials/okta/noxfile_config.py @@ -13,5 +13,5 @@ # limitations under the License. TEST_CONFIG_OVERRIDE = { - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], } diff --git a/auth/custom-credentials/okta/requirements-test.txt b/auth/custom-credentials/okta/requirements-test.txt index f47609d2651..8e23e776847 100644 --- a/auth/custom-credentials/okta/requirements-test.txt +++ b/auth/custom-credentials/okta/requirements-test.txt @@ -1,2 +1,2 @@ -r requirements.txt -pytest==7.1.2 +pytest==9.0.3; python_version >= "3.10" diff --git a/auth/custom-credentials/okta/requirements.txt b/auth/custom-credentials/okta/requirements.txt index d9669ebee9f..893676b178f 100644 --- a/auth/custom-credentials/okta/requirements.txt +++ b/auth/custom-credentials/okta/requirements.txt @@ -1,4 +1,4 @@ requests==2.32.3 google-cloud-storage==2.19.0 google-auth==2.43.0 -python-dotenv==1.1.1 +python-dotenv==1.2.2 diff --git a/auth/downscoping/requirements-test.txt b/auth/downscoping/requirements-test.txt index 5d399275c93..a967ba62fb1 100644 --- a/auth/downscoping/requirements-test.txt +++ b/auth/downscoping/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-cloud-storage==2.9.0; python_version < '3.7' google-cloud-storage==2.9.0; python_version > '3.6' diff --git a/auth/end-user/web/requirements-test.txt b/auth/end-user/web/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/auth/end-user/web/requirements-test.txt +++ b/auth/end-user/web/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/auth/service-to-service/noxfile_config.py b/auth/service-to-service/noxfile_config.py index bf45881273d..f6a3cf7417f 100644 --- a/auth/service-to-service/noxfile_config.py +++ b/auth/service-to-service/noxfile_config.py @@ -23,7 +23,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # We only run the cloud run tests in py38 session. - "ignored_versions": ["2.7", "3.6", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/auth/service-to-service/requirements-test.txt b/auth/service-to-service/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/auth/service-to-service/requirements-test.txt +++ b/auth/service-to-service/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/automl/snippets/noxfile_config.py b/automl/snippets/noxfile_config.py index ef111e5e309..b4a45d95757 100644 --- a/automl/snippets/noxfile_config.py +++ b/automl/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them # "enforce_type_hints": False, diff --git a/automl/snippets/requirements-test.txt b/automl/snippets/requirements-test.txt index f3230681cda..79932f83530 100644 --- a/automl/snippets/requirements-test.txt +++ b/automl/snippets/requirements-test.txt @@ -1,2 +1,2 @@ backoff==2.2.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/batch/requirements-test.txt b/batch/requirements-test.txt index 08d1b1b9c1f..4daf4a01072 100644 --- a/batch/requirements-test.txt +++ b/batch/requirements-test.txt @@ -1,4 +1,4 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-cloud-compute==1.11.0 google-cloud-resource-manager==1.10.1 google-cloud-storage==2.9.0 diff --git a/bigquery-connection/snippets/noxfile_config.py b/bigquery-connection/snippets/noxfile_config.py index 28c09af52f7..6cd93d1263d 100644 --- a/bigquery-connection/snippets/noxfile_config.py +++ b/bigquery-connection/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery-connection/snippets/requirements-test.txt b/bigquery-connection/snippets/requirements-test.txt index 5b0f38d50e2..334e1bfdbb8 100644 --- a/bigquery-connection/snippets/requirements-test.txt +++ b/bigquery-connection/snippets/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-cloud-testutils==1.5.0 \ No newline at end of file diff --git a/bigquery-datatransfer/snippets/noxfile_config.py b/bigquery-datatransfer/snippets/noxfile_config.py index 161ffcc14f3..5c1c0aa7b2f 100644 --- a/bigquery-datatransfer/snippets/noxfile_config.py +++ b/bigquery-datatransfer/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/bigquery-datatransfer/snippets/requirements-test.txt b/bigquery-datatransfer/snippets/requirements-test.txt index ae8913096ea..3c6ff1b456d 100644 --- a/bigquery-datatransfer/snippets/requirements-test.txt +++ b/bigquery-datatransfer/snippets/requirements-test.txt @@ -1,4 +1,4 @@ google-cloud-bigquery==3.27.0 google-cloud-pubsub==2.28.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" mock==5.1.0 diff --git a/bigquery-migration/snippets/noxfile_config.py b/bigquery-migration/snippets/noxfile_config.py index 68825a3b2dc..5ed96a67651 100644 --- a/bigquery-migration/snippets/noxfile_config.py +++ b/bigquery-migration/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery-migration/snippets/requirements-test.txt b/bigquery-migration/snippets/requirements-test.txt index d54b3ea50e2..6b60bac71d7 100644 --- a/bigquery-migration/snippets/requirements-test.txt +++ b/bigquery-migration/snippets/requirements-test.txt @@ -1,4 +1,4 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-cloud-testutils==1.5.0 google-api-core==2.17.1 google-cloud-storage==2.9.0 \ No newline at end of file diff --git a/bigquery-reservation/snippets/noxfile_config.py b/bigquery-reservation/snippets/noxfile_config.py index e1c631ca86f..4fb2be93998 100644 --- a/bigquery-reservation/snippets/noxfile_config.py +++ b/bigquery-reservation/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.6"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery-reservation/snippets/requirements-test.txt b/bigquery-reservation/snippets/requirements-test.txt index 840c3fcffe5..3e1319f761b 100644 --- a/bigquery-reservation/snippets/requirements-test.txt +++ b/bigquery-reservation/snippets/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-cloud-testutils==1.5.0 diff --git a/bigquery/bigframes/noxfile_config.py b/bigquery/bigframes/noxfile_config.py index f19dde20378..322efba33e8 100644 --- a/bigquery/bigframes/noxfile_config.py +++ b/bigquery/bigframes/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.6", "3.8", "3.9", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery/bigframes/requirements-test.txt b/bigquery/bigframes/requirements-test.txt index f1684cd8061..8b8e28c484c 100644 --- a/bigquery/bigframes/requirements-test.txt +++ b/bigquery/bigframes/requirements-test.txt @@ -1,2 +1,2 @@ flaky==3.8.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/bqml/noxfile_config.py b/bigquery/bqml/noxfile_config.py index 4e2c703470f..a4cb0cac197 100644 --- a/bigquery/bqml/noxfile_config.py +++ b/bigquery/bqml/noxfile_config.py @@ -23,7 +23,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # Skipping for Python 3.9 due to pyarrow compilation failure. - "ignored_versions": ["2.7", "3.6", "3.9", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/bigquery/bqml/requirements-test.txt b/bigquery/bqml/requirements-test.txt index f1684cd8061..8b8e28c484c 100644 --- a/bigquery/bqml/requirements-test.txt +++ b/bigquery/bqml/requirements-test.txt @@ -1,2 +1,2 @@ flaky==3.8.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/cloud-client/requirements-test.txt b/bigquery/cloud-client/requirements-test.txt index 7d32dfc20c7..1fb857b4d88 100644 --- a/bigquery/cloud-client/requirements-test.txt +++ b/bigquery/cloud-client/requirements-test.txt @@ -1,3 +1,3 @@ # samples/snippets should be runnable with no "extras" google-cloud-testutils==1.5.0 -pytest==8.3.4 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/continuous-queries/requirements-test.txt b/bigquery/continuous-queries/requirements-test.txt index ecdd071f48d..a4f09c46e50 100644 --- a/bigquery/continuous-queries/requirements-test.txt +++ b/bigquery/continuous-queries/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.3.5 +pytest==9.0.3; python_version >= "3.10" google-auth==2.38.0 requests==2.32.4 diff --git a/bigquery/pandas-gbq-migration/noxfile_config.py b/bigquery/pandas-gbq-migration/noxfile_config.py index 4e2c703470f..a4cb0cac197 100644 --- a/bigquery/pandas-gbq-migration/noxfile_config.py +++ b/bigquery/pandas-gbq-migration/noxfile_config.py @@ -23,7 +23,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # Skipping for Python 3.9 due to pyarrow compilation failure. - "ignored_versions": ["2.7", "3.6", "3.9", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/bigquery/pandas-gbq-migration/requirements-test.txt b/bigquery/pandas-gbq-migration/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/bigquery/pandas-gbq-migration/requirements-test.txt +++ b/bigquery/pandas-gbq-migration/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/python-db-dtypes-pandas/snippets/requirements-test.txt b/bigquery/python-db-dtypes-pandas/snippets/requirements-test.txt index 9471b3d92fb..c9e154ba440 100644 --- a/bigquery/python-db-dtypes-pandas/snippets/requirements-test.txt +++ b/bigquery/python-db-dtypes-pandas/snippets/requirements-test.txt @@ -1 +1 @@ -pytest==8.4.2 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/remote-function/document/noxfile_config.py b/bigquery/remote-function/document/noxfile_config.py index 129472ab778..05254a9bf8a 100644 --- a/bigquery/remote-function/document/noxfile_config.py +++ b/bigquery/remote-function/document/noxfile_config.py @@ -17,7 +17,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery/remote-function/document/requirements-test.txt b/bigquery/remote-function/document/requirements-test.txt index 254febb7aba..ac936365b2e 100644 --- a/bigquery/remote-function/document/requirements-test.txt +++ b/bigquery/remote-function/document/requirements-test.txt @@ -1,4 +1,4 @@ Flask==2.2.2 functions-framework==3.9.2 google-cloud-documentai==3.0.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/remote-function/translate/noxfile_config.py b/bigquery/remote-function/translate/noxfile_config.py index 881bc58580f..45b90dd8081 100644 --- a/bigquery/remote-function/translate/noxfile_config.py +++ b/bigquery/remote-function/translate/noxfile_config.py @@ -17,7 +17,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery/remote-function/translate/requirements-test.txt b/bigquery/remote-function/translate/requirements-test.txt index 2048a36731f..adb53acce34 100644 --- a/bigquery/remote-function/translate/requirements-test.txt +++ b/bigquery/remote-function/translate/requirements-test.txt @@ -1,4 +1,4 @@ Flask==2.2.2 functions-framework==3.9.2 google-cloud-translate==3.18.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery/remote-function/vision/noxfile_config.py b/bigquery/remote-function/vision/noxfile_config.py index 881bc58580f..45b90dd8081 100644 --- a/bigquery/remote-function/vision/noxfile_config.py +++ b/bigquery/remote-function/vision/noxfile_config.py @@ -17,7 +17,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery/remote-function/vision/requirements-test.txt b/bigquery/remote-function/vision/requirements-test.txt index 62634fcffc0..20f0bc405f4 100644 --- a/bigquery/remote-function/vision/requirements-test.txt +++ b/bigquery/remote-function/vision/requirements-test.txt @@ -1,4 +1,4 @@ Flask==2.2.2 functions-framework==3.9.2 google-cloud-vision==3.8.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery_storage/pyarrow/noxfile_config.py b/bigquery_storage/pyarrow/noxfile_config.py index 29edb31ffe8..fea7f946dff 100644 --- a/bigquery_storage/pyarrow/noxfile_config.py +++ b/bigquery_storage/pyarrow/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery_storage/pyarrow/requirements-test.txt b/bigquery_storage/pyarrow/requirements-test.txt index 7561ed55ce2..c9e154ba440 100644 --- a/bigquery_storage/pyarrow/requirements-test.txt +++ b/bigquery_storage/pyarrow/requirements-test.txt @@ -1,3 +1 @@ -pytest===7.4.3; python_version == '3.7' -pytest===8.3.5; python_version == '3.8' -pytest==8.4.1; python_version >= '3.9' +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery_storage/quickstart/noxfile_config.py b/bigquery_storage/quickstart/noxfile_config.py index f1fa9e5618b..0973c8621c7 100644 --- a/bigquery_storage/quickstart/noxfile_config.py +++ b/bigquery_storage/quickstart/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery_storage/quickstart/requirements-test.txt b/bigquery_storage/quickstart/requirements-test.txt index 7561ed55ce2..c9e154ba440 100644 --- a/bigquery_storage/quickstart/requirements-test.txt +++ b/bigquery_storage/quickstart/requirements-test.txt @@ -1,3 +1 @@ -pytest===7.4.3; python_version == '3.7' -pytest===8.3.5; python_version == '3.8' -pytest==8.4.1; python_version >= '3.9' +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery_storage/snippets/noxfile_config.py b/bigquery_storage/snippets/noxfile_config.py index f1fa9e5618b..0973c8621c7 100644 --- a/bigquery_storage/snippets/noxfile_config.py +++ b/bigquery_storage/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery_storage/snippets/requirements-test.txt b/bigquery_storage/snippets/requirements-test.txt index 230ca56dc3a..06cc720170b 100644 --- a/bigquery_storage/snippets/requirements-test.txt +++ b/bigquery_storage/snippets/requirements-test.txt @@ -1,4 +1,2 @@ google-cloud-testutils==1.6.4 -pytest===7.4.3; python_version == '3.7' -pytest===8.3.5; python_version == '3.8' -pytest==8.4.1; python_version >= '3.9' +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery_storage/snippets/requirements.txt b/bigquery_storage/snippets/requirements.txt index 8a456493526..821c0abb139 100644 --- a/bigquery_storage/snippets/requirements.txt +++ b/bigquery_storage/snippets/requirements.txt @@ -1,6 +1,4 @@ google-cloud-bigquery-storage==2.32.0 google-cloud-bigquery===3.30.0; python_version <= '3.8' google-cloud-bigquery==3.35.1; python_version >= '3.9' -pytest===7.4.3; python_version == '3.7' -pytest===8.3.5; python_version == '3.8' -pytest==8.4.1; python_version >= '3.9' +pytest==9.0.3; python_version >= "3.10" diff --git a/bigquery_storage/to_dataframe/noxfile_config.py b/bigquery_storage/to_dataframe/noxfile_config.py index f1fa9e5618b..0973c8621c7 100644 --- a/bigquery_storage/to_dataframe/noxfile_config.py +++ b/bigquery_storage/to_dataframe/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/bigquery_storage/to_dataframe/requirements-test.txt b/bigquery_storage/to_dataframe/requirements-test.txt index 7561ed55ce2..c9e154ba440 100644 --- a/bigquery_storage/to_dataframe/requirements-test.txt +++ b/bigquery_storage/to_dataframe/requirements-test.txt @@ -1,3 +1 @@ -pytest===7.4.3; python_version == '3.7' -pytest===8.3.5; python_version == '3.8' -pytest==8.4.1; python_version >= '3.9' +pytest==9.0.3; python_version >= "3.10" diff --git a/billing/requirements-test.txt b/billing/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/billing/requirements-test.txt +++ b/billing/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/blog/introduction_to_data_models_in_cloud_datastore/noxfile_config.py b/blog/introduction_to_data_models_in_cloud_datastore/noxfile_config.py index 9a1680c88df..4eae59976e2 100644 --- a/blog/introduction_to_data_models_in_cloud_datastore/noxfile_config.py +++ b/blog/introduction_to_data_models_in_cloud_datastore/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/blog/introduction_to_data_models_in_cloud_datastore/requirements-test.txt b/blog/introduction_to_data_models_in_cloud_datastore/requirements-test.txt index 185d62c4204..23df1e03c7e 100644 --- a/blog/introduction_to_data_models_in_cloud_datastore/requirements-test.txt +++ b/blog/introduction_to_data_models_in_cloud_datastore/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" flaky==3.8.1 diff --git a/cloud-sql/mysql/sqlalchemy/Dockerfile b/cloud-sql/mysql/sqlalchemy/Dockerfile index 72a0ef555e1..d0ad90b7fbb 100644 --- a/cloud-sql/mysql/sqlalchemy/Dockerfile +++ b/cloud-sql/mysql/sqlalchemy/Dockerfile @@ -14,7 +14,7 @@ # Use the official Python image. # https://hub.docker.com/_/python -FROM python:3.13 +FROM python:3.14 RUN apt-get update diff --git a/cloud-sql/postgres/sqlalchemy/Dockerfile b/cloud-sql/postgres/sqlalchemy/Dockerfile index 72a0ef555e1..d0ad90b7fbb 100644 --- a/cloud-sql/postgres/sqlalchemy/Dockerfile +++ b/cloud-sql/postgres/sqlalchemy/Dockerfile @@ -14,7 +14,7 @@ # Use the official Python image. # https://hub.docker.com/_/python -FROM python:3.13 +FROM python:3.14 RUN apt-get update diff --git a/cloud-sql/sql-server/sqlalchemy/Dockerfile b/cloud-sql/sql-server/sqlalchemy/Dockerfile index 75f4e22a969..1464006d45b 100644 --- a/cloud-sql/sql-server/sqlalchemy/Dockerfile +++ b/cloud-sql/sql-server/sqlalchemy/Dockerfile @@ -14,7 +14,7 @@ # Use the official Python image. # https://hub.docker.com/_/python -FROM python:3.13 +FROM python:3.14 RUN apt-get update diff --git a/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/Dockerfile b/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/Dockerfile index e78e11b3462..a18789f2f09 100644 --- a/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/Dockerfile +++ b/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM python:3.11 +FROM python:3.14 # Allow statements and log messages to immediately appear in the Cloud Run logs ENV PYTHONUNBUFFERED True diff --git a/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/noxfile_config.py b/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/noxfile_config.py index 5751b6d12eb..9577c4f3b42 100644 --- a/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/noxfile_config.py +++ b/composer/blog/gcp-tech-blog/unit-test-dags-cloud-build/noxfile_config.py @@ -32,6 +32,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # Skipping for Python 3.9 due to numpy compilation failure. + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) "ignored_versions": ["2.7", "3.9", "3.10", "3.11"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them diff --git a/compute/client_library/requirements.txt b/compute/client_library/requirements.txt index f9faea10a9d..656732bef9a 100644 --- a/compute/client_library/requirements.txt +++ b/compute/client_library/requirements.txt @@ -1,5 +1,4 @@ isort==6.0.0; python_version > "3.9" isort==5.13.2; python_version <= "3.8" -black==24.8.0; python_version < "3.9" -black==24.10.0; python_version >= "3.9" -google-cloud-compute==1.19.1 \ No newline at end of file +black==26.3.1 +google-cloud-compute==1.19.1 diff --git a/dataflow/conftest.py b/dataflow/conftest.py index a1f81eac6f6..2bb6c6b3ecf 100644 --- a/dataflow/conftest.py +++ b/dataflow/conftest.py @@ -85,7 +85,7 @@ def bucket_name(test_name: str, location: str, unique_id: str) -> Iterator[str]: # Try to remove all files before deleting the bucket. # Deleting a bucket with too many files results in an error. try: - run_cmd("gsutil", "-m", "rm", "-rf", f"gs://{bucket_name}/*") + run_cmd("gcloud", "storage", "rm", "--recursive", "--continue-on-error", f"gs://{bucket_name}/*") except RuntimeError: # If no files were found and it fails, ignore the error. pass diff --git a/dataflow/custom-containers/miniconda/Dockerfile b/dataflow/custom-containers/miniconda/Dockerfile index bcc1eadc7f5..31e8c3b03f8 100644 --- a/dataflow/custom-containers/miniconda/Dockerfile +++ b/dataflow/custom-containers/miniconda/Dockerfile @@ -18,7 +18,7 @@ FROM continuumio/miniconda3:22.11.1-alpine AS builder # Create a virtual environment and make it standalone with conda-pack. # https://conda.github.io/conda-pack -RUN conda create -y -n env python=3.9 \ +RUN conda create -y -n env python=3.14 \ && conda install -y conda-pack \ && conda-pack -n env -o /tmp/env.tar \ && mkdir /opt/python \ @@ -31,7 +31,7 @@ FROM ubuntu:latest WORKDIR /pipeline # Set the entrypoint to Apache Beam SDK worker launcher. -COPY --from=apache/beam_python3.9_sdk:2.55.1 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam ENTRYPOINT [ "/opt/apache/beam/boot" ] # Copy the python installation from the builder stage. diff --git a/dataflow/custom-containers/miniconda/noxfile_config.py b/dataflow/custom-containers/miniconda/noxfile_config.py index fb2bcbdea22..60b814e62b1 100644 --- a/dataflow/custom-containers/miniconda/noxfile_config.py +++ b/dataflow/custom-containers/miniconda/noxfile_config.py @@ -22,10 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ We're opting out of all Python versions except 3.9. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.10", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/dataflow/custom-containers/minimal/Dockerfile b/dataflow/custom-containers/minimal/Dockerfile index 2176aa76a81..cb113d33854 100644 --- a/dataflow/custom-containers/minimal/Dockerfile +++ b/dataflow/custom-containers/minimal/Dockerfile @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM python:3.9-slim +FROM python:3.14-slim WORKDIR /pipeline # Set the entrypoint to Apache Beam SDK worker launcher. -COPY --from=apache/beam_python3.9_sdk:2.55.1 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam ENTRYPOINT [ "/opt/apache/beam/boot" ] # Install the requirements. diff --git a/dataflow/custom-containers/minimal/noxfile_config.py b/dataflow/custom-containers/minimal/noxfile_config.py index fb2bcbdea22..60b814e62b1 100644 --- a/dataflow/custom-containers/minimal/noxfile_config.py +++ b/dataflow/custom-containers/minimal/noxfile_config.py @@ -22,10 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ We're opting out of all Python versions except 3.9. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.10", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/dataflow/custom-containers/ubuntu/Dockerfile b/dataflow/custom-containers/ubuntu/Dockerfile index c35d23d9957..67e5d80e998 100644 --- a/dataflow/custom-containers/ubuntu/Dockerfile +++ b/dataflow/custom-containers/ubuntu/Dockerfile @@ -17,7 +17,7 @@ FROM ubuntu:focal WORKDIR /pipeline # Set the entrypoint to Apache Beam SDK worker launcher. -COPY --from=apache/beam_python3.8_sdk:2.40.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam ENTRYPOINT [ "/opt/apache/beam/boot" ] # Install Python with pip, dev tools, distutils, and a C++ compiler. diff --git a/dataflow/custom-containers/ubuntu/noxfile_config.py b/dataflow/custom-containers/ubuntu/noxfile_config.py index fb2bcbdea22..60b814e62b1 100644 --- a/dataflow/custom-containers/ubuntu/noxfile_config.py +++ b/dataflow/custom-containers/ubuntu/noxfile_config.py @@ -22,10 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ We're opting out of all Python versions except 3.9. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.10", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/dataflow/encryption-keys/README.md b/dataflow/encryption-keys/README.md index 0545d63d321..036540108d8 100644 --- a/dataflow/encryption-keys/README.md +++ b/dataflow/encryption-keys/README.md @@ -25,7 +25,7 @@ Additionally, for this sample you need the following: ```sh export BUCKET=your-gcs-bucket - gsutil mb gs://$BUCKET + gcloud storage buckets create gs://$BUCKET ``` 1. [Create a symmetric key ring](https://cloud.google.com/kms/docs/creating-keys). @@ -174,10 +174,10 @@ To avoid incurring charges to your GCP account for the resources used: ```sh # Remove only the files created by this sample. -gsutil -m rm -rf "gs://$BUCKET/samples/dataflow/kms" +gcloud storage rm --recursive --continue-on-error "gs://$BUCKET/samples/dataflow/kms" # [optional] Remove the Cloud Storage bucket. -gsutil rb gs://$BUCKET +gcloud storage buckets delete gs://$BUCKET # Remove the BigQuery table. bq rm -f -t $PROJECT:$DATASET.$TABLE diff --git a/dataflow/flex-templates/getting_started/README.md b/dataflow/flex-templates/getting_started/README.md index d7ee5d38bd3..383fdca052e 100644 --- a/dataflow/flex-templates/getting_started/README.md +++ b/dataflow/flex-templates/getting_started/README.md @@ -9,7 +9,7 @@ Make sure you have followed the ```sh export BUCKET="your--bucket" -gsutil mb gs://$BUCKET +gcloud storage buckets create gs://$BUCKET ``` ## create an Artifact Registry repository @@ -51,4 +51,3 @@ gcloud dataflow flex-template run "flex-`date +%Y%m%d-%H%M%S`" \ For more information about building and running flex templates, see 📝 [Use Flex Templates](https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates). - diff --git a/dataflow/flex-templates/pipeline_with_dependencies/Dockerfile b/dataflow/flex-templates/pipeline_with_dependencies/Dockerfile index e85016b1411..0939e9e0728 100644 --- a/dataflow/flex-templates/pipeline_with_dependencies/Dockerfile +++ b/dataflow/flex-templates/pipeline_with_dependencies/Dockerfile @@ -24,14 +24,14 @@ # This Dockerfile illustrates how to use a custom base image when building # a custom contaier images for Dataflow. A 'slim' base image is smaller in size, # but does not include some preinstalled libraries, like google-cloud-debugger. -# To use a standard image, use apache/beam_python3.11_sdk:2.54.0 instead. +# To use a standard image, use apache/beam_python3.14_sdk:2.73.0 instead. # Use consistent versions of Python interpreter in the project. -FROM python:3.11-slim +FROM python:3.14-slim # Copy SDK entrypoint binary from Apache Beam image, which makes it possible to # use the image as SDK container image. If you explicitly depend on # apache-beam in setup.py, use the same version of Beam in both files. -COPY --from=apache/beam_python3.11_sdk:2.54.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam # Copy Flex Template launcher binary from the launcher image, which makes it # possible to use the image as a Flex Template base image. diff --git a/dataflow/flex-templates/pipeline_with_dependencies/README.md b/dataflow/flex-templates/pipeline_with_dependencies/README.md index 99385639297..79bbabf9761 100644 --- a/dataflow/flex-templates/pipeline_with_dependencies/README.md +++ b/dataflow/flex-templates/pipeline_with_dependencies/README.md @@ -73,7 +73,7 @@ rules. It is optional. export PROJECT="project-id" export BUCKET="your-bucket" export REGION="us-central1" -gsutil mb -p $PROJECT gs://$BUCKET +gcloud storage buckets create gs://$BUCKET --project=$PROJECT ``` ## Create an Artifact Registry repository @@ -165,7 +165,7 @@ gcloud dataflow flex-template run "flex-`date +%Y%m%d-%H%M%S`" \ After the pipeline finishes, use the following command to inspect the output: ```bash -gsutil cat gs://$BUCKET/output* +gcloud storage cat gs://$BUCKET/output* ``` ## Optional: Update the dependencies in the requirements file and rebuild the Docker images diff --git a/dataflow/flex-templates/pipeline_with_dependencies/noxfile_config.py b/dataflow/flex-templates/pipeline_with_dependencies/noxfile_config.py index 8df70c1108b..c3badedaaba 100644 --- a/dataflow/flex-templates/pipeline_with_dependencies/noxfile_config.py +++ b/dataflow/flex-templates/pipeline_with_dependencies/noxfile_config.py @@ -16,8 +16,8 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ We're opting out of all Python versions except 3.11. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], } diff --git a/dataflow/flex-templates/pipeline_with_dependencies/requirements.txt b/dataflow/flex-templates/pipeline_with_dependencies/requirements.txt index bef166bb943..cc9fda76736 100644 --- a/dataflow/flex-templates/pipeline_with_dependencies/requirements.txt +++ b/dataflow/flex-templates/pipeline_with_dependencies/requirements.txt @@ -305,7 +305,7 @@ typing-extensions==4.10.0 # via apache-beam tzlocal==5.2 # via js2py -urllib3==2.6.0 +urllib3==2.6.3 # via requests wrapt==1.16.0 # via deprecated diff --git a/dataflow/flex-templates/streaming_beam/README.md b/dataflow/flex-templates/streaming_beam/README.md index 66d891ce526..2a21e44220b 100644 --- a/dataflow/flex-templates/streaming_beam/README.md +++ b/dataflow/flex-templates/streaming_beam/README.md @@ -25,7 +25,7 @@ Additionally, for this sample you need the following: ```sh export BUCKET="your-gcs-bucket" - gsutil mb gs://$BUCKET + gcloud storage buckets create gs://$BUCKET ``` 1. Create a @@ -231,7 +231,7 @@ The following sections describe how to delete or turn off these resources. 1. Delete the template spec file from Cloud Storage. ```sh - gsutil rm $TEMPLATE_PATH + gcloud storage rm $TEMPLATE_PATH ``` 1. Delete the Flex Template container image from Container Registry. @@ -277,7 +277,7 @@ The following sections describe how to delete or turn off these resources. > These objects cannot be recovered. > > ```sh - > gsutil rm -r gs://$BUCKET + > gcloud storage rm --recursive gs://$BUCKET > ``` ## Limitations diff --git a/dataflow/gemma-flex-template/Dockerfile b/dataflow/gemma-flex-template/Dockerfile index 284474e9759..fb2c52d27d6 100644 --- a/dataflow/gemma-flex-template/Dockerfile +++ b/dataflow/gemma-flex-template/Dockerfile @@ -30,11 +30,11 @@ RUN pip install --no-cache-dir --upgrade pip \ # Copy SDK entrypoint binary from Apache Beam image, which makes it possible to # use the image as SDK container image. # The Beam version should match the version specified in requirements.txt -COPY --from=apache/beam_python3.10_sdk:2.62.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam # Copy Flex Template launcher binary from the launcher image, which makes it # possible to use the image as a Flex Template base image. -COPY --from=gcr.io/dataflow-templates-base/python310-template-launcher-base:latest /opt/google/dataflow/python_template_launcher /opt/google/dataflow/python_template_launcher +COPY --from=gcr.io/dataflow-templates-base/python314-template-launcher-base:latest /opt/google/dataflow/python_template_launcher /opt/google/dataflow/python_template_launcher # Copy the model directory downloaded from Kaggle and the pipeline code. COPY pytorch_model pytorch_model diff --git a/dataflow/gemma-flex-template/README.md b/dataflow/gemma-flex-template/README.md index 8ade42a8c46..0e082cc2bb7 100644 --- a/dataflow/gemma-flex-template/README.md +++ b/dataflow/gemma-flex-template/README.md @@ -43,7 +43,7 @@ Click [here to create a GCS bucket](https://console.cloud.google.com/storage/cre ```sh export GCS_BUCKET="your--bucket" -gsutil mb gs://$GCS_BUCKET +gcloud storage buckets create gs://$GCS_BUCKET ``` Make sure your GCS bucket name does __not__ include the `gs://` prefix diff --git a/dataflow/gemma-flex-template/e2e_test.py b/dataflow/gemma-flex-template/e2e_test.py index f95f78ec089..be281a9c984 100644 --- a/dataflow/gemma-flex-template/e2e_test.py +++ b/dataflow/gemma-flex-template/e2e_test.py @@ -92,7 +92,7 @@ def responses_subscription( @pytest.fixture(scope="session") def flex_template_image(utils: Utils) -> str: - conftest.run_cmd("gsutil", "cp", "-r", GEMMA_GCS, ".") + conftest.run_cmd("gcloud", "storage", "cp", "--recursive", GEMMA_GCS, ".") yield from utils.cloud_build_submit(NAME) diff --git a/dataflow/gemma-flex-template/noxfile_config.py b/dataflow/gemma-flex-template/noxfile_config.py index 7e6ba7ba31b..35321dbbdea 100644 --- a/dataflow/gemma-flex-template/noxfile_config.py +++ b/dataflow/gemma-flex-template/noxfile_config.py @@ -16,10 +16,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # Opting out of all Python versions except 3.10. # The Python version used is defined by the Dockerfile and the job # submission enviornment must match. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], "envs": { "PYTHONPATH": ".." }, diff --git a/dataflow/gemma/Dockerfile b/dataflow/gemma/Dockerfile index d66c298e6eb..b3472a56955 100644 --- a/dataflow/gemma/Dockerfile +++ b/dataflow/gemma/Dockerfile @@ -29,7 +29,7 @@ RUN pip install --upgrade --no-cache-dir pip \ && pip install --no-cache-dir -r requirements.txt # Copy files from official SDK image, including script/dependencies. -COPY --from=apache/beam_python3.11_sdk:2.54.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam # Copy the model directory downloaded from Kaggle and the pipeline code. COPY gemma_2b gemma_2B diff --git a/dataflow/gemma/e2e_test.py b/dataflow/gemma/e2e_test.py index e2510716f4b..6f65fb15959 100644 --- a/dataflow/gemma/e2e_test.py +++ b/dataflow/gemma/e2e_test.py @@ -60,7 +60,7 @@ def test_name() -> str: @pytest.fixture(scope="session") def container_image(utils: Utils) -> str: # Copy Gemma onto the local environment - conftest.run_cmd("gsutil", "cp", "-r", GEMMA_GCS, ".") + conftest.run_cmd("gcloud", "storage", "cp", "--recursive", GEMMA_GCS, ".") yield from utils.cloud_build_submit(NAME) diff --git a/dataflow/gemma/noxfile_config.py b/dataflow/gemma/noxfile_config.py index 7b3b1b9ebf6..35321dbbdea 100644 --- a/dataflow/gemma/noxfile_config.py +++ b/dataflow/gemma/noxfile_config.py @@ -16,10 +16,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # Opting out of all Python versions except 3.11. # The Python version used is defined by the Dockerfile and the job # submission enviornment must match. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], "envs": { "PYTHONPATH": ".." }, diff --git a/dataflow/gpu-examples/pytorch-minimal/Dockerfile b/dataflow/gpu-examples/pytorch-minimal/Dockerfile index f86d8bb388f..df3903a36ed 100644 --- a/dataflow/gpu-examples/pytorch-minimal/Dockerfile +++ b/dataflow/gpu-examples/pytorch-minimal/Dockerfile @@ -27,5 +27,5 @@ RUN pip install --no-cache-dir --upgrade pip \ && pip check # Set the entrypoint to Apache Beam SDK worker launcher. -COPY --from=apache/beam_python3.10_sdk:2.62.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam ENTRYPOINT [ "/opt/apache/beam/boot" ] diff --git a/dataflow/gpu-examples/pytorch-minimal/noxfile_config.py b/dataflow/gpu-examples/pytorch-minimal/noxfile_config.py index 99b1fb47b8e..ac06c5f8740 100644 --- a/dataflow/gpu-examples/pytorch-minimal/noxfile_config.py +++ b/dataflow/gpu-examples/pytorch-minimal/noxfile_config.py @@ -22,10 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ We're opting out of all Python versions except 3.10. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/dataflow/gpu-examples/tensorflow-landsat-prime/Dockerfile b/dataflow/gpu-examples/tensorflow-landsat-prime/Dockerfile index a506a8727a7..9b2fba3c978 100644 --- a/dataflow/gpu-examples/tensorflow-landsat-prime/Dockerfile +++ b/dataflow/gpu-examples/tensorflow-landsat-prime/Dockerfile @@ -25,9 +25,9 @@ COPY *.py ./ RUN apt-get update \ # Install Python and other system dependencies. && apt-get install -y --no-install-recommends \ - curl g++ python3.10-dev python3.10-venv python3-distutils \ + curl g++ python3.14-dev python3.14-venv python3-distutils \ && rm -rf /var/lib/apt/lists/* \ - && update-alternatives --install /usr/bin/python python /usr/bin/python3.10 10 \ + && update-alternatives --install /usr/bin/python python /usr/bin/python3.14 10 \ && curl https://bootstrap.pypa.io/get-pip.py | python \ # Install the pipeline requirements. && pip install --no-cache-dir -r requirements.txt \ @@ -35,5 +35,5 @@ RUN apt-get update \ # Set the entrypoint to Apache Beam SDK worker launcher. # Check this matches the apache-beam version in the requirements.txt -COPY --from=apache/beam_python3.10_sdk:2.62.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam ENTRYPOINT [ "/opt/apache/beam/boot" ] diff --git a/dataflow/gpu-examples/tensorflow-landsat-prime/noxfile_config.py b/dataflow/gpu-examples/tensorflow-landsat-prime/noxfile_config.py index 376ea30e3b6..ca12a452f5b 100644 --- a/dataflow/gpu-examples/tensorflow-landsat-prime/noxfile_config.py +++ b/dataflow/gpu-examples/tensorflow-landsat-prime/noxfile_config.py @@ -22,10 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ Test only on Python 3.10. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/dataflow/gpu-examples/tensorflow-landsat/Dockerfile b/dataflow/gpu-examples/tensorflow-landsat/Dockerfile index 39a836fdb0b..f547b13de44 100644 --- a/dataflow/gpu-examples/tensorflow-landsat/Dockerfile +++ b/dataflow/gpu-examples/tensorflow-landsat/Dockerfile @@ -25,9 +25,9 @@ COPY *.py ./ RUN apt-get update \ # Install Python and other system dependencies. && apt-get install -y --no-install-recommends \ - curl g++ python3.10-dev python3.10-venv python3-distutils \ + curl g++ python3.14-dev python3.14-venv python3-distutils \ && rm -rf /var/lib/apt/lists/* \ - && update-alternatives --install /usr/bin/python python /usr/bin/python3.10 10 \ + && update-alternatives --install /usr/bin/python python /usr/bin/python3.14 10 \ && curl https://bootstrap.pypa.io/get-pip.py | python \ # Install the pipeline requirements. && pip install --no-cache-dir -r requirements.txt \ @@ -35,5 +35,5 @@ RUN apt-get update \ # Set the entrypoint to Apache Beam SDK worker launcher. # Check this matches the apache-beam version in the requirements.txt -COPY --from=apache/beam_python3.10_sdk:2.62.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam ENTRYPOINT [ "/opt/apache/beam/boot" ] diff --git a/dataflow/gpu-examples/tensorflow-landsat/noxfile_config.py b/dataflow/gpu-examples/tensorflow-landsat/noxfile_config.py index baf97789883..33c259f5bef 100644 --- a/dataflow/gpu-examples/tensorflow-landsat/noxfile_config.py +++ b/dataflow/gpu-examples/tensorflow-landsat/noxfile_config.py @@ -22,10 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ Test only on Python 3.10. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/dataflow/gpu-examples/tensorflow-minimal/Dockerfile b/dataflow/gpu-examples/tensorflow-minimal/Dockerfile index e5f79f6e4ad..16c74bc0d75 100644 --- a/dataflow/gpu-examples/tensorflow-minimal/Dockerfile +++ b/dataflow/gpu-examples/tensorflow-minimal/Dockerfile @@ -25,9 +25,9 @@ COPY *.py ./ RUN apt-get update \ # Install Python and other system dependencies. && apt-get install -y --no-install-recommends \ - curl g++ python3.10-dev python3.10-venv python3-distutils \ + curl g++ python3.14-dev python3.14-venv python3-distutils \ && rm -rf /var/lib/apt/lists/* \ - && update-alternatives --install /usr/bin/python python /usr/bin/python3.10 10 \ + && update-alternatives --install /usr/bin/python python /usr/bin/python3.14 10 \ && curl https://bootstrap.pypa.io/get-pip.py | python \ # Install the pipeline requirements. && pip install --no-cache-dir -r requirements.txt \ @@ -35,5 +35,5 @@ RUN apt-get update \ # Set the entrypoint to Apache Beam SDK worker launcher. # Check this matches the apache-beam version in the requirements.txt -COPY --from=apache/beam_python3.10_sdk:2.62.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam ENTRYPOINT [ "/opt/apache/beam/boot" ] diff --git a/dataflow/gpu-examples/tensorflow-minimal/noxfile_config.py b/dataflow/gpu-examples/tensorflow-minimal/noxfile_config.py index baf97789883..33c259f5bef 100644 --- a/dataflow/gpu-examples/tensorflow-minimal/noxfile_config.py +++ b/dataflow/gpu-examples/tensorflow-minimal/noxfile_config.py @@ -22,10 +22,10 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - # > ℹ️ Test only on Python 3.10. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.11", "3.12", "3.13"], + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) + "ignored_versions": ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/dataflow/run-inference/requirements-test.txt b/dataflow/run-inference/requirements-test.txt index c9095c832fd..1802752120d 100644 --- a/dataflow/run-inference/requirements-test.txt +++ b/dataflow/run-inference/requirements-test.txt @@ -1,4 +1,4 @@ google-cloud-aiplatform==1.57.0 google-cloud-dataflow-client==0.8.14 google-cloud-storage==2.10.0 -pytest==8.2.0 +pytest==9.0.3 diff --git a/dataflow/run-inference/requirements.txt b/dataflow/run-inference/requirements.txt index 585334e1a9b..d0376ac202e 100644 --- a/dataflow/run-inference/requirements.txt +++ b/dataflow/run-inference/requirements.txt @@ -1,3 +1,3 @@ apache-beam[gcp]==2.49.0 torch==2.2.2 -transformers==4.38.0 +transformers==5.0.0rc3 diff --git a/dataflow/run-inference/tests/e2e_test.py b/dataflow/run-inference/tests/e2e_test.py index 0428af3dd28..70be7d6878d 100644 --- a/dataflow/run-inference/tests/e2e_test.py +++ b/dataflow/run-inference/tests/e2e_test.py @@ -95,7 +95,7 @@ def dataflow_job( ) -> Iterator[str]: # Upload the state dict to Cloud Storage. state_dict_gcs = f"gs://{bucket_name}/temp/state_dict.pt" - conftest.run_cmd("gsutil", "cp", "-n", state_dict_path, state_dict_gcs) + conftest.run_cmd("gcloud", "storage", "cp", "--no-clobber", state_dict_path, state_dict_gcs) # Launch the streaming Dataflow pipeline. conftest.run_cmd( diff --git a/dataflow/run_template/README.md b/dataflow/run_template/README.md index c73fb76c504..dda9f4570aa 100644 --- a/dataflow/run_template/README.md +++ b/dataflow/run_template/README.md @@ -29,7 +29,7 @@ Additionally, for this sample you need the following: ```sh export BUCKET=your-gcs-bucket - gsutil mb gs://$BUCKET + gcloud storage buckets create gs://$BUCKET ``` 1. Clone the `python-docs-samples` repository. diff --git a/dataflow/snippets/Dockerfile b/dataflow/snippets/Dockerfile index bb230e64e4d..4234ca52651 100644 --- a/dataflow/snippets/Dockerfile +++ b/dataflow/snippets/Dockerfile @@ -18,7 +18,7 @@ # on the host machine. This Dockerfile is derived from the # dataflow/custom-containers/ubuntu sample. -FROM python:3.12-slim +FROM python:3.14-slim # Install JRE COPY --from=openjdk:8-jre-slim /usr/local/openjdk-8 /usr/local/openjdk-8 @@ -28,7 +28,7 @@ RUN update-alternatives --install /usr/bin/java java /usr/local/openjdk-8/bin/ja WORKDIR /pipeline # Copy files from official SDK image. -COPY --from=apache/beam_python3.11_sdk:2.63.0 /opt/apache/beam /opt/apache/beam +COPY --from=apache/beam_python3.14_sdk:2.73.0 /opt/apache/beam /opt/apache/beam # Set the entrypoint to Apache Beam SDK launcher. ENTRYPOINT [ "/opt/apache/beam/boot" ] @@ -37,7 +37,7 @@ RUN apt-get update RUN apt-get install -y --no-install-recommends docker.io # Install dependencies. -RUN pip3 install --no-cache-dir apache-beam[gcp]==2.63.0 +RUN pip3 install --no-cache-dir apache-beam[gcp]==2.73.0 RUN pip install --no-cache-dir kafka-python==2.0.6 # Verify that the image does not have conflicting dependencies. diff --git a/dataflow/snippets/noxfile_config.py b/dataflow/snippets/noxfile_config.py index 900f58e0ddf..7760eb40877 100644 --- a/dataflow/snippets/noxfile_config.py +++ b/dataflow/snippets/noxfile_config.py @@ -22,6 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. + # Note: Docker-based sample, testing only against version specified in Dockerfile (3.14) "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them diff --git a/dataproc/snippets/README.md b/dataproc/snippets/README.md index 98622be7dc1..442b8fa55bb 100644 --- a/dataproc/snippets/README.md +++ b/dataproc/snippets/README.md @@ -64,7 +64,7 @@ To run list_clusters.py: To run submit_job_to_cluster.py, first create a GCS bucket (used by Cloud Dataproc to stage files) from the Cloud Console or with gsutil: - gsutil mb gs:// + gcloud storage buckets create gs:// Next, set the following environment variables: diff --git a/dataproc/snippets/python-api-walkthrough.md b/dataproc/snippets/python-api-walkthrough.md index c5eb884a8f0..2ca94cca3ca 100644 --- a/dataproc/snippets/python-api-walkthrough.md +++ b/dataproc/snippets/python-api-walkthrough.md @@ -65,7 +65,7 @@ an explanation of how the code works. * To create a new bucket, run the following command. Your bucket name must be unique. - gsutil mb -p {{project-id}} gs://your-bucket-name + gcloud storage buckets create --project={{project-id}} gs://your-bucket-name 2. Set environment variables. @@ -145,12 +145,12 @@ Cluster cluster-name successfully deleted. If you created a Cloud Storage bucket to use for this walkthrough, you can run the following command to delete the bucket (the bucket must be empty). - gsutil rb gs://$BUCKET + gcloud storage buckets delete gs://$BUCKET * You can run the following command to **delete the bucket and all objects within it. Note: the deleted objects cannot be recovered.** - gsutil rm -r gs://$BUCKET + gcloud storage rm --recursive gs://$BUCKET * **For more information.** See the [Dataproc documentation](https://cloud.google.com/dataproc/docs/) diff --git a/discoveryengine/answer_query_sample.py b/discoveryengine/answer_query_sample.py index fcb47bff6b8..92d51c43a71 100644 --- a/discoveryengine/answer_query_sample.py +++ b/discoveryengine/answer_query_sample.py @@ -69,7 +69,8 @@ def answer_query_sample( ignore_non_answer_seeking_query=False, # Optional: Ignore non-answer seeking query ignore_low_relevant_content=False, # Optional: Return fallback answer when content is not relevant model_spec=discoveryengine.AnswerQueryRequest.AnswerGenerationSpec.ModelSpec( - model_version="gemini-2.5-flash/answer_gen/v1", # Optional: Model to use for answer generation + # Use the 2026 stable production model for answer generation + model_version="gemini-2.5-flash/answer_gen/stable", ), prompt_spec=discoveryengine.AnswerQueryRequest.AnswerGenerationSpec.PromptSpec( preamble="Give a detailed answer.", # Optional: Natural language instructions for customizing the answer. diff --git a/endpoints/bookstore-grpc-transcoding/requirements-test.txt b/endpoints/bookstore-grpc-transcoding/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/endpoints/bookstore-grpc-transcoding/requirements-test.txt +++ b/endpoints/bookstore-grpc-transcoding/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/endpoints/bookstore-grpc/requirements-test.txt b/endpoints/bookstore-grpc/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/endpoints/bookstore-grpc/requirements-test.txt +++ b/endpoints/bookstore-grpc/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/endpoints/getting-started-grpc/requirements-test.txt b/endpoints/getting-started-grpc/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/endpoints/getting-started-grpc/requirements-test.txt +++ b/endpoints/getting-started-grpc/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/endpoints/getting-started/clients/service_to_service_non_default/requirements-test.txt b/endpoints/getting-started/clients/service_to_service_non_default/requirements-test.txt index 15d066af319..216d5b8a24a 100644 --- a/endpoints/getting-started/clients/service_to_service_non_default/requirements-test.txt +++ b/endpoints/getting-started/clients/service_to_service_non_default/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +endpoints/getting-started/clients/service_to_service_non_default/requirements-test.txt diff --git a/enterpriseknowledgegraph/entity_reconciliation/requirements-test.txt b/enterpriseknowledgegraph/entity_reconciliation/requirements-test.txt index 55d9a1d34d9..2313637c624 100644 --- a/enterpriseknowledgegraph/entity_reconciliation/requirements-test.txt +++ b/enterpriseknowledgegraph/entity_reconciliation/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-api-core google-cloud-enterpriseknowledgegraph diff --git a/enterpriseknowledgegraph/search/requirements-test.txt b/enterpriseknowledgegraph/search/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/enterpriseknowledgegraph/search/requirements-test.txt +++ b/enterpriseknowledgegraph/search/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/error_reporting/fluent_on_compute/requirements-test.txt b/error_reporting/fluent_on_compute/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/error_reporting/fluent_on_compute/requirements-test.txt +++ b/error_reporting/fluent_on_compute/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/error_reporting/snippets/requirements-test.txt b/error_reporting/snippets/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/error_reporting/snippets/requirements-test.txt +++ b/error_reporting/snippets/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/eventarc/audit-storage/Dockerfile b/eventarc/audit-storage/Dockerfile index d5b1fad1c17..e65ba1afa4d 100644 --- a/eventarc/audit-storage/Dockerfile +++ b/eventarc/audit-storage/Dockerfile @@ -16,7 +16,7 @@ # Use the official Python image. # https://hub.docker.com/_/python -FROM python:3.11-slim +FROM python:3.14-slim # Allow statements and log messages to immediately appear in the Cloud Run logs ENV PYTHONUNBUFFERED True diff --git a/eventarc/audit-storage/requirements-test.txt b/eventarc/audit-storage/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/eventarc/audit-storage/requirements-test.txt +++ b/eventarc/audit-storage/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/eventarc/audit_iam/requirements-test.txt b/eventarc/audit_iam/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/eventarc/audit_iam/requirements-test.txt +++ b/eventarc/audit_iam/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/eventarc/generic/Dockerfile b/eventarc/generic/Dockerfile index a7a158bcb39..e4f1889dc5b 100644 --- a/eventarc/generic/Dockerfile +++ b/eventarc/generic/Dockerfile @@ -14,7 +14,7 @@ # Use the official Python image. # https://hub.docker.com/_/python -FROM python:3.11-slim +FROM python:3.14-slim # Allow statements and log messages to immediately appear in the Cloud Run logs ENV PYTHONUNBUFFERED True diff --git a/eventarc/generic/requirements-test.txt b/eventarc/generic/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/eventarc/generic/requirements-test.txt +++ b/eventarc/generic/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/eventarc/pubsub/Dockerfile b/eventarc/pubsub/Dockerfile index a7a158bcb39..e4f1889dc5b 100644 --- a/eventarc/pubsub/Dockerfile +++ b/eventarc/pubsub/Dockerfile @@ -14,7 +14,7 @@ # Use the official Python image. # https://hub.docker.com/_/python -FROM python:3.11-slim +FROM python:3.14-slim # Allow statements and log messages to immediately appear in the Cloud Run logs ENV PYTHONUNBUFFERED True diff --git a/eventarc/pubsub/requirements-test.txt b/eventarc/pubsub/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/eventarc/pubsub/requirements-test.txt +++ b/eventarc/pubsub/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/eventarc/storage_handler/requirements-test.txt b/eventarc/storage_handler/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/eventarc/storage_handler/requirements-test.txt +++ b/eventarc/storage_handler/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/functions/imagemagick/requirements-dev.txt b/functions/imagemagick/requirements-dev.txt index 158a3587da8..3bbf38755d9 100644 --- a/functions/imagemagick/requirements-dev.txt +++ b/functions/imagemagick/requirements-dev.txt @@ -1,4 +1,4 @@ uuid==1.30 -pytest==8.2.0; python_version > "3.0" +pytest==9.0.3; python_version > "3.0" # pin pytest to 4.6.11 or lower for Python2. -pytest==4.6.11; python_version < "3.0" +pytest==9.0.3; python_version < "3.0" diff --git a/functions/ocr/app/main.py b/functions/ocr/app/main.py index 186c9abfaaa..53bf3467d1d 100644 --- a/functions/ocr/app/main.py +++ b/functions/ocr/app/main.py @@ -69,7 +69,7 @@ def detect_text(bucket: str, filename: str) -> None: filename: name of the file to be read. Returns: - None; the output is written to stdout and Stackdriver Logging. + None; the output is written to stdout and Cloud Logging. """ print("Looking for text in image {}".format(filename)) @@ -123,7 +123,7 @@ def process_image(file_info: dict, context: dict) -> None: context: a dictionary containing metadata about the event. Returns: - None; the output is written to stdout and Stackdriver Logging. + None; the output is written to stdout and Cloud Logging. """ bucket = validate_message(file_info, "bucket") name = validate_message(file_info, "name") @@ -148,7 +148,7 @@ def translate_text(event: dict, context: dict) -> None: context: a dictionary containing metadata about the event. Returns: - None; the output is written to stdout and Stackdriver Logging. + None; the output is written to stdout and Cloud Logging. """ if event.get("data"): message_data = base64.b64decode(event["data"]).decode("utf-8") @@ -189,7 +189,7 @@ def save_result(event: dict, context: dict) -> None: context: a dictionary containing metadata about the event. Returns: - None; the output is written to stdout and Stackdriver Logging. + None; the output is written to stdout and Cloud Logging. """ if event.get("data"): message_data = base64.b64decode(event["data"]).decode("utf-8") diff --git a/functions/tips-retry/main.py b/functions/tips-retry/main.py index 847ae6394dc..dfe11942af2 100644 --- a/functions/tips-retry/main.py +++ b/functions/tips-retry/main.py @@ -27,7 +27,7 @@ def retry_or_not(data, context): data (dict): The event payload. context (google.cloud.functions.Context): The event metadata. Returns: - None; output is written to Stackdriver Logging + None; output is written to Cloud Logging """ # Retry based on a user-defined parameter diff --git a/functions/v2/tips-avoid-infinite-retries/main.py b/functions/v2/tips-avoid-infinite-retries/main.py index e3b735f2f74..9e751d5d0b5 100644 --- a/functions/v2/tips-avoid-infinite-retries/main.py +++ b/functions/v2/tips-avoid-infinite-retries/main.py @@ -29,7 +29,7 @@ def avoid_infinite_retries(cloud_event): Args: cloud_event: The cloud event associated with the current trigger Returns: - None; output is written to Stackdriver Logging + None; output is written to Cloud Logging """ timestamp = cloud_event["time"] diff --git a/functions/v2/tips-retry/main.py b/functions/v2/tips-retry/main.py index 7ff58a954ff..91ce20b8468 100644 --- a/functions/v2/tips-retry/main.py +++ b/functions/v2/tips-retry/main.py @@ -31,7 +31,7 @@ def retry_or_not(cloud_event): Args: cloud_event: The cloud event with a Pub/Sub data payload Returns: - None; output is written to Stackdriver Logging + None; output is written to Cloud Logging """ # The Pub/Sub event payload is passed as the CloudEvent's data payload. diff --git a/gemma2/noxfile_config.py b/gemma2/noxfile_config.py index 494cf15318d..fd69813938c 100644 --- a/gemma2/noxfile_config.py +++ b/gemma2/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/gemma2/requirements-test.txt b/gemma2/requirements-test.txt index 40543aababf..c9e154ba440 100644 --- a/gemma2/requirements-test.txt +++ b/gemma2/requirements-test.txt @@ -1 +1 @@ -pytest==8.3.3 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/batch_prediction/noxfile_config.py b/genai/batch_prediction/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/batch_prediction/noxfile_config.py +++ b/genai/batch_prediction/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/batch_prediction/requirements-test.txt b/genai/batch_prediction/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/batch_prediction/requirements-test.txt +++ b/genai/batch_prediction/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/bounding_box/noxfile_config.py b/genai/bounding_box/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/bounding_box/noxfile_config.py +++ b/genai/bounding_box/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/bounding_box/requirements-test.txt b/genai/bounding_box/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/bounding_box/requirements-test.txt +++ b/genai/bounding_box/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/bounding_box/test_bounding_box_examples.py b/genai/bounding_box/test_bounding_box_examples.py index bb6eca92008..39b0056e7a3 100644 --- a/genai/bounding_box/test_bounding_box_examples.py +++ b/genai/bounding_box/test_bounding_box_examples.py @@ -20,7 +20,7 @@ import boundingbox_with_txt_img -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/code_execution/noxfile_config.py b/genai/code_execution/noxfile_config.py index 29d9e7911eb..650b3c47840 100644 --- a/genai/code_execution/noxfile_config.py +++ b/genai/code_execution/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.13", "3.14"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/code_execution/requirements-test.txt b/genai/code_execution/requirements-test.txt index 8d10ef87035..7289efe2596 100644 --- a/genai/code_execution/requirements-test.txt +++ b/genai/code_execution/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.29.0 -pytest==9.0.2 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==1.3.0 diff --git a/genai/code_execution/test_codeexecution.py b/genai/code_execution/test_codeexecution.py index e3a8bfb7944..ea978643c7c 100644 --- a/genai/code_execution/test_codeexecution.py +++ b/genai/code_execution/test_codeexecution.py @@ -17,7 +17,7 @@ import codeexecution_barplot_with_txt_img import codeexecution_cropimage_with_txt_img -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/content_cache/noxfile_config.py b/genai/content_cache/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/content_cache/noxfile_config.py +++ b/genai/content_cache/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/content_cache/requirements-test.txt b/genai/content_cache/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/content_cache/requirements-test.txt +++ b/genai/content_cache/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/content_cache/test_content_cache_examples.py b/genai/content_cache/test_content_cache_examples.py index d7d9e5abda4..d17c43b1bea 100644 --- a/genai/content_cache/test_content_cache_examples.py +++ b/genai/content_cache/test_content_cache_examples.py @@ -21,7 +21,7 @@ import contentcache_use_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/controlled_generation/noxfile_config.py b/genai/controlled_generation/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/controlled_generation/noxfile_config.py +++ b/genai/controlled_generation/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/controlled_generation/requirements-test.txt b/genai/controlled_generation/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/genai/controlled_generation/requirements-test.txt +++ b/genai/controlled_generation/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/genai/controlled_generation/test_controlled_generation_examples.py b/genai/controlled_generation/test_controlled_generation_examples.py index ab27d8e7a46..2bd518be054 100644 --- a/genai/controlled_generation/test_controlled_generation_examples.py +++ b/genai/controlled_generation/test_controlled_generation_examples.py @@ -25,7 +25,7 @@ import ctrlgen_with_nullable_schema import ctrlgen_with_resp_schema -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/count_tokens/noxfile_config.py b/genai/count_tokens/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/count_tokens/noxfile_config.py +++ b/genai/count_tokens/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/count_tokens/requirements-test.txt b/genai/count_tokens/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/genai/count_tokens/requirements-test.txt +++ b/genai/count_tokens/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/genai/count_tokens/test_count_tokens_examples.py b/genai/count_tokens/test_count_tokens_examples.py index e83f20cd14c..94f5b06c036 100644 --- a/genai/count_tokens/test_count_tokens_examples.py +++ b/genai/count_tokens/test_count_tokens_examples.py @@ -25,7 +25,7 @@ import counttoken_with_txt import counttoken_with_txt_vid -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/embeddings/noxfile_config.py b/genai/embeddings/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/embeddings/noxfile_config.py +++ b/genai/embeddings/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/embeddings/requirements-test.txt b/genai/embeddings/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/embeddings/requirements-test.txt +++ b/genai/embeddings/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/embeddings/test_embeddings_examples.py b/genai/embeddings/test_embeddings_examples.py index 5908ccddc6a..5b8d94f07c3 100644 --- a/genai/embeddings/test_embeddings_examples.py +++ b/genai/embeddings/test_embeddings_examples.py @@ -20,7 +20,7 @@ import embeddings_docretrieval_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/express_mode/noxfile_config.py b/genai/express_mode/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/express_mode/noxfile_config.py +++ b/genai/express_mode/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/express_mode/requirements-test.txt b/genai/express_mode/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/express_mode/requirements-test.txt +++ b/genai/express_mode/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/image_generation/imggen_mmflash_edit_img_with_txt_img.py b/genai/image_generation/imggen_mmflash_edit_img_with_txt_img.py index e2d9888a027..405702d4eff 100644 --- a/genai/image_generation/imggen_mmflash_edit_img_with_txt_img.py +++ b/genai/image_generation/imggen_mmflash_edit_img_with_txt_img.py @@ -26,7 +26,7 @@ def generate_content() -> str: image = Image.open("test_resources/example-image-eiffel-tower.png") response = client.models.generate_content( - model="gemini-3-pro-image-preview", + model="gemini-3.1-flash-image", contents=[image, "Edit this image to make it look like a cartoon."], config=GenerateContentConfig(response_modalities=[Modality.TEXT, Modality.IMAGE]), ) diff --git a/genai/image_generation/imggen_mmflash_img_with_vid.py b/genai/image_generation/imggen_mmflash_img_with_vid.py new file mode 100644 index 00000000000..98a0c51f996 --- /dev/null +++ b/genai/image_generation/imggen_mmflash_img_with_vid.py @@ -0,0 +1,51 @@ +# Copyright 2026 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 +# +# https://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. + + +def generate_content() -> str: + # [START googlegenaisdk_imggen_mmflash_img_with_vid] + from google import genai + from google.genai.types import GenerateContentConfig, Modality, Part + from PIL import Image + from io import BytesIO + + client = genai.Client() + + # A video on 'The ABCs of agent building' + video = "https://www.youtube.com/watch?v=rjoMZyxncUI" + + response = client.models.generate_content( + model="gemini-3.1-flash-image", + contents=[ + Part.from_uri( + file_uri=video, + mime_type="video/mp4" + ), + "Generate an infographic of the topics covered in this video." + ], + config=GenerateContentConfig(response_modalities=[Modality.TEXT, Modality.IMAGE]), + ) + for part in response.candidates[0].content.parts: + if part.text: + print(part.text) + elif part.inline_data: + image = Image.open(BytesIO((part.inline_data.data))) + image.save("output_folder/video-image.png") + + # [END googlegenaisdk_imggen_mmflash_img_with_vid] + return "output_folder/video-image.png" + + +if __name__ == "__main__": + generate_content() diff --git a/genai/image_generation/imggen_mmflash_locale_aware_with_txt.py b/genai/image_generation/imggen_mmflash_locale_aware_with_txt.py index 305be883d22..2e80866a525 100644 --- a/genai/image_generation/imggen_mmflash_locale_aware_with_txt.py +++ b/genai/image_generation/imggen_mmflash_locale_aware_with_txt.py @@ -23,7 +23,7 @@ def generate_content() -> str: client = genai.Client() response = client.models.generate_content( - model="gemini-2.5-flash-image", + model="gemini-3.1-flash-image", contents=("Generate a photo of a breakfast meal."), config=GenerateContentConfig(response_modalities=[Modality.TEXT, Modality.IMAGE]), ) diff --git a/genai/image_generation/imggen_mmflash_multiple_imgs_with_txt.py b/genai/image_generation/imggen_mmflash_multiple_imgs_with_txt.py index 2b831ca97d9..884dba9d45f 100644 --- a/genai/image_generation/imggen_mmflash_multiple_imgs_with_txt.py +++ b/genai/image_generation/imggen_mmflash_multiple_imgs_with_txt.py @@ -23,7 +23,7 @@ def generate_content() -> str: client = genai.Client() response = client.models.generate_content( - model="gemini-2.5-flash-image", + model="gemini-3.1-flash-image", contents=("Generate 3 images a cat sitting on a chair."), config=GenerateContentConfig(response_modalities=[Modality.TEXT, Modality.IMAGE]), ) diff --git a/genai/image_generation/imggen_mmflash_txt_and_img_with_txt.py b/genai/image_generation/imggen_mmflash_txt_and_img_with_txt.py index 7a9d11103a7..ff2b9fda9f9 100644 --- a/genai/image_generation/imggen_mmflash_txt_and_img_with_txt.py +++ b/genai/image_generation/imggen_mmflash_txt_and_img_with_txt.py @@ -23,7 +23,7 @@ def generate_content() -> int: client = genai.Client() response = client.models.generate_content( - model="gemini-3-pro-image-preview", + model="gemini-3.1-flash-image", contents=( "Generate an illustrated recipe for a paella." "Create images to go alongside the text as you generate the recipe" diff --git a/genai/image_generation/imggen_mmflash_with_txt.py b/genai/image_generation/imggen_mmflash_with_txt.py index cd6c458a757..fd83f89eeda 100644 --- a/genai/image_generation/imggen_mmflash_with_txt.py +++ b/genai/image_generation/imggen_mmflash_with_txt.py @@ -25,7 +25,7 @@ def generate_content() -> str: client = genai.Client() response = client.models.generate_content( - model="gemini-3-pro-image-preview", + model="gemini-3.1-flash-image", contents=("Generate an image of the Eiffel tower with fireworks in the background."), config=GenerateContentConfig( response_modalities=[Modality.TEXT, Modality.IMAGE], diff --git a/genai/image_generation/noxfile_config.py b/genai/image_generation/noxfile_config.py index d63baa25bfa..0973c8621c7 100644 --- a/genai/image_generation/noxfile_config.py +++ b/genai/image_generation/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/image_generation/requirements-test.txt b/genai/image_generation/requirements-test.txt index 4ccc4347cbe..14a8493498b 100644 --- a/genai/image_generation/requirements-test.txt +++ b/genai/image_generation/requirements-test.txt @@ -1,3 +1,3 @@ google-api-core==2.24.0 google-cloud-storage==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/image_generation/test_image_generation.py b/genai/image_generation/test_image_generation.py index f30b295f85e..f5cf14bb62c 100644 --- a/genai/image_generation/test_image_generation.py +++ b/genai/image_generation/test_image_generation.py @@ -41,7 +41,7 @@ import imggen_virtual_try_on_with_txt_img import imggen_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/image_generation/test_image_generation_mmflash.py b/genai/image_generation/test_image_generation_mmflash.py index 3ae60ec66ba..1b6b46bae70 100644 --- a/genai/image_generation/test_image_generation_mmflash.py +++ b/genai/image_generation/test_image_generation_mmflash.py @@ -19,13 +19,14 @@ import os import imggen_mmflash_edit_img_with_txt_img +import imggen_mmflash_img_with_vid import imggen_mmflash_locale_aware_with_txt import imggen_mmflash_multiple_imgs_with_txt import imggen_mmflash_txt_and_img_with_txt import imggen_mmflash_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" @@ -49,3 +50,6 @@ def test_imggen_mmflash_locale_aware_with_txt() -> None: def test_imggen_mmflash_multiple_imgs_with_txt() -> None: assert imggen_mmflash_multiple_imgs_with_txt.generate_content() + +def test_imggen_mmflash_img_with_vid() -> None: + assert imggen_mmflash_img_with_vid.generate_content() diff --git a/genai/live/noxfile_config.py b/genai/live/noxfile_config.py index d63baa25bfa..0973c8621c7 100644 --- a/genai/live/noxfile_config.py +++ b/genai/live/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/live/requirements-test.txt b/genai/live/requirements-test.txt index 7d5998c481d..654ef724fd6 100644 --- a/genai/live/requirements-test.txt +++ b/genai/live/requirements-test.txt @@ -1,5 +1,5 @@ backoff==2.2.1 google-api-core==2.25.1 -pytest==8.4.1 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==1.1.0 pytest-mock==3.14.0 \ No newline at end of file diff --git a/genai/live/test_live_examples.py b/genai/live/test_live_examples.py index ffb0f10c689..2d59ee87d10 100644 --- a/genai/live/test_live_examples.py +++ b/genai/live/test_live_examples.py @@ -42,7 +42,7 @@ import live_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/model_optimizer/noxfile_config.py b/genai/model_optimizer/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/model_optimizer/noxfile_config.py +++ b/genai/model_optimizer/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/model_optimizer/requirements-test.txt b/genai/model_optimizer/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/genai/model_optimizer/requirements-test.txt +++ b/genai/model_optimizer/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/genai/model_optimizer/test_modeloptimizer_examples.py b/genai/model_optimizer/test_modeloptimizer_examples.py index c26668b3ad3..71eb67f7575 100644 --- a/genai/model_optimizer/test_modeloptimizer_examples.py +++ b/genai/model_optimizer/test_modeloptimizer_examples.py @@ -15,7 +15,7 @@ import modeloptimizer_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/provisioned_throughput/noxfile_config.py b/genai/provisioned_throughput/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/provisioned_throughput/noxfile_config.py +++ b/genai/provisioned_throughput/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/provisioned_throughput/requirements-test.txt b/genai/provisioned_throughput/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/provisioned_throughput/requirements-test.txt +++ b/genai/provisioned_throughput/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/provisioned_throughput/test_provisioned_throughput_examples.py b/genai/provisioned_throughput/test_provisioned_throughput_examples.py index 693d4fe32da..8bcda182b73 100644 --- a/genai/provisioned_throughput/test_provisioned_throughput_examples.py +++ b/genai/provisioned_throughput/test_provisioned_throughput_examples.py @@ -20,7 +20,7 @@ import provisionedthroughput_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/safety/noxfile_config.py b/genai/safety/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/safety/noxfile_config.py +++ b/genai/safety/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/safety/requirements-test.txt b/genai/safety/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/safety/requirements-test.txt +++ b/genai/safety/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/safety/test_safety_examples.py b/genai/safety/test_safety_examples.py index 593e43fb617..1da4d861cf5 100644 --- a/genai/safety/test_safety_examples.py +++ b/genai/safety/test_safety_examples.py @@ -21,7 +21,7 @@ import safety_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/template_folder/noxfile_config.py b/genai/template_folder/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/template_folder/noxfile_config.py +++ b/genai/template_folder/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/template_folder/requirements-test.txt b/genai/template_folder/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/genai/template_folder/requirements-test.txt +++ b/genai/template_folder/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/genai/template_folder/test_templatefolder_examples.py b/genai/template_folder/test_templatefolder_examples.py index ecae1dce1d2..acc25e25530 100644 --- a/genai/template_folder/test_templatefolder_examples.py +++ b/genai/template_folder/test_templatefolder_examples.py @@ -15,7 +15,7 @@ import templatefolder_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/text_generation/noxfile_config.py b/genai/text_generation/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/text_generation/noxfile_config.py +++ b/genai/text_generation/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/text_generation/requirements-test.txt b/genai/text_generation/requirements-test.txt index e43b7792721..22a9617b8e8 100644 --- a/genai/text_generation/requirements-test.txt +++ b/genai/text_generation/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/text_generation/test_text_generation_examples.py b/genai/text_generation/test_text_generation_examples.py index 3477caef9df..d859b4ff73b 100644 --- a/genai/text_generation/test_text_generation_examples.py +++ b/genai/text_generation/test_text_generation_examples.py @@ -39,7 +39,7 @@ import textgen_with_youtube_video import thinking_textgen_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/thinking/noxfile_config.py b/genai/thinking/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/thinking/noxfile_config.py +++ b/genai/thinking/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/thinking/requirements-test.txt b/genai/thinking/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/genai/thinking/requirements-test.txt +++ b/genai/thinking/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/genai/thinking/test_thinking_examples.py b/genai/thinking/test_thinking_examples.py index 71fc75f1f9a..047141ace4e 100644 --- a/genai/thinking/test_thinking_examples.py +++ b/genai/thinking/test_thinking_examples.py @@ -17,7 +17,7 @@ import thinking_includethoughts_with_txt import thinking_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/tools/noxfile_config.py b/genai/tools/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/tools/noxfile_config.py +++ b/genai/tools/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/tools/requirements-test.txt b/genai/tools/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/genai/tools/requirements-test.txt +++ b/genai/tools/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/genai/tools/test_tools_examples.py b/genai/tools/test_tools_examples.py index 60ed069e1a4..95611393b00 100644 --- a/genai/tools/test_tools_examples.py +++ b/genai/tools/test_tools_examples.py @@ -31,7 +31,7 @@ import tools_urlcontext_with_txt import tools_vais_with_txt -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/genai/tuning/noxfile_config.py b/genai/tuning/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/tuning/noxfile_config.py +++ b/genai/tuning/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/tuning/requirements-test.txt b/genai/tuning/requirements-test.txt index 4ccc4347cbe..14a8493498b 100644 --- a/genai/tuning/requirements-test.txt +++ b/genai/tuning/requirements-test.txt @@ -1,3 +1,3 @@ google-api-core==2.24.0 google-cloud-storage==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/video_generation/noxfile_config.py b/genai/video_generation/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/genai/video_generation/noxfile_config.py +++ b/genai/video_generation/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/genai/video_generation/requirements-test.txt b/genai/video_generation/requirements-test.txt index 4ccc4347cbe..14a8493498b 100644 --- a/genai/video_generation/requirements-test.txt +++ b/genai/video_generation/requirements-test.txt @@ -1,3 +1,3 @@ google-api-core==2.24.0 google-cloud-storage==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/genai/video_generation/test_video_generation_examples.py b/genai/video_generation/test_video_generation_examples.py index 639793ff9e8..079bdf7e97c 100644 --- a/genai/video_generation/test_video_generation_examples.py +++ b/genai/video_generation/test_video_generation_examples.py @@ -41,7 +41,7 @@ import videogen_with_vid_edit_remove -os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "True" +os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" # The project name is included in the CICD pipeline # os.environ['GOOGLE_CLOUD_PROJECT'] = "add-your-project-name" diff --git a/generative_ai/README.md b/generative_ai/README.md index 9cd7509813b..caf5c1ea389 100644 --- a/generative_ai/README.md +++ b/generative_ai/README.md @@ -1,15 +1,14 @@ -# Generative AI Samples on Google Cloud +# Generative AI on Google Cloud: Python Samples -Welcome to the Python samples folder for Generative AI on Vertex AI! In this folder, you can find the Python samples -used in [Google Cloud Generative AI documentation](https://cloud.google.com/ai/generative-ai?hl=en). +This directory contains the official Python code samples featured in the [Google Cloud Generative AI documentation](https://cloud.google.com/ai/generative-ai?hl=en). These scripts demonstrate how to integrate and build with Vertex AI. -If you are looking for colab notebook, then this [link](https://github.com/GoogleCloudPlatform/generative-ai/tree/main). +Looking for interactive, step-by-step tutorials? Check out our extensive collection of [Colab notebooks](https://github.com/GoogleCloudPlatform/generative-ai/tree/main). ## Getting Started -To try and run these Code samples, we have following recommend using Google Cloud IDE or Google Colab. +> **Note:** An active Google Cloud Project is required. -Note: A Google Cloud Project is a pre-requisite. +We recommend running these code samples using Google Cloud Shell Editor or Google Colab to minimize environment setup. ### Feature folders @@ -21,47 +20,26 @@ Browse the folders below to find the Generative AI capabilities you're intereste Google Cloud Product - Short Description (With the help of Gemini 1.5) - - - - Context Caching - - https://cloud.google.com/vertex-ai/generative-ai/docs/context-cache/context-cache-overview - - Code samples demonstrating how to use context caching with Vertex AI's generative models. This allows for more consistent and relevant responses across multiple interactions by storing previous conversation history. - - - - Controlled Generation - - https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/control-generated-output - - Examples of how to control the output of generative models, such as specifying length, format, or sentiment. - - - - Count Token - - https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/list-token - - Code demonstrating how to count tokens in text, which is crucial for managing costs and understanding model limitations. + Short Description (With the help of Gemini 3.1) + Embeddings https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings - Code showing how to generate and use embeddings from text or images. Embeddings can be used for tasks like semantic search, clustering, and classification. + Learn how to use Vertex AI's text and multimodal embedding models. These samples show you how to convert your unstructured data into numerical vectors to power semantic search, clustering, and RAG applications. + + Extensions https://cloud.google.com/vertex-ai/generative-ai/docs/extensions/overview - Demonstrations of how to use extensions with generative models, enabling them to access and process real-time information, use tools, and interact with external systems. + These samples show how to connect Gemini to external APIs and databases so your models can retrieve live data and execute real-world actions. **Note** that as Google Cloud transitions to the Gemini Enterprise Agent Platform, standalone Vertex AI Extensions are evolving into *Tools* managed within the centralized Agent Registry. While these examples teach the core mechanics of model-to-API communication, future production applications should adopt the new Agent Platform architecture.. @@ -69,23 +47,16 @@ Browse the folders below to find the Generative AI capabilities you're intereste https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling - Examples of how to use function calling to enable generative models to execute specific actions or retrieve information from external APIs. - - - - Grounding - - https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/overview - - Code illustrating how to ground generative models with specific knowledge bases or data sources to improve the accuracy and relevance of their responses. + Function calling gives Gemini the ability to interact with your codebase. The model predicts which of your local functions needs to be run and returns the formatted arguments, leaving the actual execution up to your application. + Image Generation https://cloud.google.com/vertex-ai/generative-ai/docs/image/overview - Samples showcasing how to generate images from text prompts using models like Imagen. + Learn how to integrate the Imagen model into your applications. These examples cover text-to-image generation, editing, and using advanced parameters to get the exact visual output you need. @@ -93,7 +64,7 @@ Browse the folders below to find the Generative AI capabilities you're intereste https://cloud.google.com/vertex-ai/generative-ai/docs/model-garden/explore-models - Resources related to exploring and utilizing pre-trained models available in Vertex AI's Model Garden. + These examples show you how to provision endpoints and serve predictions from first-party, third-party, and open-source foundation models available in the Vertex AI Model Garden. @@ -101,7 +72,7 @@ Browse the folders below to find the Generative AI capabilities you're intereste https://cloud.google.com/vertex-ai/generative-ai/docs/models/tune-models - Code and guides for fine-tuning pre-trained generative models on specific datasets or for specific tasks. + Tailor Gemini and other foundation models to your specific domain. These examples cover how to format your datasets, kick off tuning jobs on Vertex AI, and deploy your custom-tuned models or adapters to production endpoints. @@ -109,7 +80,7 @@ Browse the folders below to find the Generative AI capabilities you're intereste https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/rag-api - Information and resources about Retrieval Augmented Generation (RAG), which combines information retrieval with generative models. + These examples cover the end-to-end RAG architecture: ingesting data, generating embeddings, querying a vector database, and passing the retrieved context to Gemini to generate informed, accurate answers. @@ -117,23 +88,7 @@ Browse the folders below to find the Generative AI capabilities you're intereste https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/reasoning-engine - Details about the Reasoning Engine, which enables more complex reasoning and logical deduction in generative models. - - - - Safety - - https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/configure-safety-attributes - - Examples of how to configure safety attributes and filters to mitigate risks and ensure responsible use of generative models. - - - - System Instructions - - https://cloud.google.com/vertex-ai/generative-ai/docs/learn/prompts/system-instructions?hl=en - - Code demonstrating how to provide system instructions to guide the behavior and responses of generative models. + These examples cover how to use Vertex AI Reasoning Engine to build custom agents. @@ -141,23 +96,7 @@ Browse the folders below to find the Generative AI capabilities you're intereste https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/send-chat-prompts-gemini - Samples of how to generate text using Gemini models, including chat-based interactions and creative writing. - - - - Understand Audio - - https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/audio-understanding - - Examples of how to use generative models for audio understanding tasks, such as transcription and audio classification. - - - - Understand Video - - https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/video-understanding - - Samples showcasing how to use generative models for video understanding tasks, such as video summarization and content analysis. + These samples demonstrate how to use Vertex AI's Gemini models to generate, summarize, and extract information from text. diff --git a/generative_ai/chat_completions/noxfile_config.py b/generative_ai/chat_completions/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/chat_completions/noxfile_config.py +++ b/generative_ai/chat_completions/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/chat_completions/requirements-test.txt b/generative_ai/chat_completions/requirements-test.txt index 3b9949d8513..3a0f817634b 100644 --- a/generative_ai/chat_completions/requirements-test.txt +++ b/generative_ai/chat_completions/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/embeddings/noxfile_config.py b/generative_ai/embeddings/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/embeddings/noxfile_config.py +++ b/generative_ai/embeddings/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/embeddings/requirements-test.txt b/generative_ai/embeddings/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/embeddings/requirements-test.txt +++ b/generative_ai/embeddings/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/evaluation/noxfile_config.py b/generative_ai/evaluation/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/evaluation/noxfile_config.py +++ b/generative_ai/evaluation/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/evaluation/requirements-test.txt b/generative_ai/evaluation/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/evaluation/requirements-test.txt +++ b/generative_ai/evaluation/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/extensions/noxfile_config.py b/generative_ai/extensions/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/extensions/noxfile_config.py +++ b/generative_ai/extensions/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/extensions/requirements-test.txt b/generative_ai/extensions/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/extensions/requirements-test.txt +++ b/generative_ai/extensions/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/function_calling/noxfile_config.py b/generative_ai/function_calling/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/function_calling/noxfile_config.py +++ b/generative_ai/function_calling/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/function_calling/requirements-test.txt b/generative_ai/function_calling/requirements-test.txt index 3b9949d8513..3a0f817634b 100644 --- a/generative_ai/function_calling/requirements-test.txt +++ b/generative_ai/function_calling/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.24.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/image_generation/noxfile_config.py b/generative_ai/image_generation/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/image_generation/noxfile_config.py +++ b/generative_ai/image_generation/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/image_generation/requirements-test.txt b/generative_ai/image_generation/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/image_generation/requirements-test.txt +++ b/generative_ai/image_generation/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/labels/noxfile_config.py b/generative_ai/labels/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/labels/noxfile_config.py +++ b/generative_ai/labels/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/labels/requirements-test.txt b/generative_ai/labels/requirements-test.txt index 2247ce2d832..cefab43dffa 100644 --- a/generative_ai/labels/requirements-test.txt +++ b/generative_ai/labels/requirements-test.txt @@ -1,2 +1,2 @@ google-api-core==2.23.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/generative_ai/model_garden/noxfile_config.py b/generative_ai/model_garden/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/model_garden/noxfile_config.py +++ b/generative_ai/model_garden/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/model_garden/requirements-test.txt b/generative_ai/model_garden/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/model_garden/requirements-test.txt +++ b/generative_ai/model_garden/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/model_tuning/noxfile_config.py b/generative_ai/model_tuning/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/model_tuning/noxfile_config.py +++ b/generative_ai/model_tuning/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/model_tuning/requirements-test.txt b/generative_ai/model_tuning/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/model_tuning/requirements-test.txt +++ b/generative_ai/model_tuning/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/prompts/noxfile_config.py b/generative_ai/prompts/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/prompts/noxfile_config.py +++ b/generative_ai/prompts/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/prompts/requirements-test.txt b/generative_ai/prompts/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/prompts/requirements-test.txt +++ b/generative_ai/prompts/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/provisioned_throughput/noxfile_config.py b/generative_ai/provisioned_throughput/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/provisioned_throughput/noxfile_config.py +++ b/generative_ai/provisioned_throughput/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/provisioned_throughput/requirements-test.txt b/generative_ai/provisioned_throughput/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/provisioned_throughput/requirements-test.txt +++ b/generative_ai/provisioned_throughput/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/rag/noxfile_config.py b/generative_ai/rag/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/rag/noxfile_config.py +++ b/generative_ai/rag/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/rag/requirements-test.txt b/generative_ai/rag/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/rag/requirements-test.txt +++ b/generative_ai/rag/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/generative_ai/reasoning_engine/noxfile_config.py b/generative_ai/reasoning_engine/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/generative_ai/reasoning_engine/noxfile_config.py +++ b/generative_ai/reasoning_engine/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/generative_ai/reasoning_engine/requirements-test.txt b/generative_ai/reasoning_engine/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/generative_ai/reasoning_engine/requirements-test.txt +++ b/generative_ai/reasoning_engine/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/healthcare/api-client/v1/consent/noxfile_config.py b/healthcare/api-client/v1/consent/noxfile_config.py index ecc5247cce9..52036a424ef 100644 --- a/healthcare/api-client/v1/consent/noxfile_config.py +++ b/healthcare/api-client/v1/consent/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/healthcare/api-client/v1/consent/requirements-test.txt b/healthcare/api-client/v1/consent/requirements-test.txt index 0d7187a429e..659ed4bc2c9 100644 --- a/healthcare/api-client/v1/consent/requirements-test.txt +++ b/healthcare/api-client/v1/consent/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" backoff==2.2.1; python_version < "3.7" backoff==2.2.1; python_version >= "3.7" diff --git a/healthcare/api-client/v1/datasets/noxfile_config.py b/healthcare/api-client/v1/datasets/noxfile_config.py index b4d9f9b057c..6cea5520fa8 100644 --- a/healthcare/api-client/v1/datasets/noxfile_config.py +++ b/healthcare/api-client/v1/datasets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/healthcare/api-client/v1/datasets/requirements-test.txt b/healthcare/api-client/v1/datasets/requirements-test.txt index 8b9eaff06c4..cb48e4d986e 100644 --- a/healthcare/api-client/v1/datasets/requirements-test.txt +++ b/healthcare/api-client/v1/datasets/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" retrying==1.3.4 diff --git a/healthcare/api-client/v1/dicom/noxfile_config.py b/healthcare/api-client/v1/dicom/noxfile_config.py index b4d9f9b057c..6cea5520fa8 100644 --- a/healthcare/api-client/v1/dicom/noxfile_config.py +++ b/healthcare/api-client/v1/dicom/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/healthcare/api-client/v1/dicom/requirements-test.txt b/healthcare/api-client/v1/dicom/requirements-test.txt index 0d7187a429e..659ed4bc2c9 100644 --- a/healthcare/api-client/v1/dicom/requirements-test.txt +++ b/healthcare/api-client/v1/dicom/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" backoff==2.2.1; python_version < "3.7" backoff==2.2.1; python_version >= "3.7" diff --git a/healthcare/api-client/v1/fhir/noxfile_config.py b/healthcare/api-client/v1/fhir/noxfile_config.py index 1a9099a80eb..c2250035bd5 100644 --- a/healthcare/api-client/v1/fhir/noxfile_config.py +++ b/healthcare/api-client/v1/fhir/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/healthcare/api-client/v1/fhir/requirements-test.txt b/healthcare/api-client/v1/fhir/requirements-test.txt index 0d7187a429e..659ed4bc2c9 100644 --- a/healthcare/api-client/v1/fhir/requirements-test.txt +++ b/healthcare/api-client/v1/fhir/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" backoff==2.2.1; python_version < "3.7" backoff==2.2.1; python_version >= "3.7" diff --git a/healthcare/api-client/v1/hl7v2/noxfile_config.py b/healthcare/api-client/v1/hl7v2/noxfile_config.py index b4d9f9b057c..6cea5520fa8 100644 --- a/healthcare/api-client/v1/hl7v2/noxfile_config.py +++ b/healthcare/api-client/v1/hl7v2/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/healthcare/api-client/v1/hl7v2/requirements-test.txt b/healthcare/api-client/v1/hl7v2/requirements-test.txt index 0d7187a429e..659ed4bc2c9 100644 --- a/healthcare/api-client/v1/hl7v2/requirements-test.txt +++ b/healthcare/api-client/v1/hl7v2/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" backoff==2.2.1; python_version < "3.7" backoff==2.2.1; python_version >= "3.7" diff --git a/healthcare/api-client/v1beta1/fhir/requirements-test.txt b/healthcare/api-client/v1beta1/fhir/requirements-test.txt index 8ce117fb56e..36921e74453 100644 --- a/healthcare/api-client/v1beta1/fhir/requirements-test.txt +++ b/healthcare/api-client/v1beta1/fhir/requirements-test.txt @@ -1,3 +1,3 @@ backoff==2.2.1; python_version < "3.7" backoff==2.2.1; python_version >= "3.7" -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/iam/api-client/noxfile_config.py b/iam/api-client/noxfile_config.py index 30f1c3971e6..f879875f76a 100644 --- a/iam/api-client/noxfile_config.py +++ b/iam/api-client/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Declare optional test sessions you want to opt-in. Currently we # have the following optional test sessions: # 'cloud_run' # Test session for Cloud Run application. diff --git a/iam/api-client/requirements-test.txt b/iam/api-client/requirements-test.txt index 8b9eaff06c4..cb48e4d986e 100644 --- a/iam/api-client/requirements-test.txt +++ b/iam/api-client/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" retrying==1.3.4 diff --git a/iam/cloud-client/snippets/noxfile_config.py b/iam/cloud-client/snippets/noxfile_config.py index 029a70011cc..658f73ff360 100644 --- a/iam/cloud-client/snippets/noxfile_config.py +++ b/iam/cloud-client/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/iam/cloud-client/snippets/requirements-test.txt b/iam/cloud-client/snippets/requirements-test.txt index 6ff70adf77d..975d5ee58c2 100644 --- a/iam/cloud-client/snippets/requirements-test.txt +++ b/iam/cloud-client/snippets/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" backoff==2.2.1 diff --git a/iap/app_engine_app/requirements-test.txt b/iap/app_engine_app/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/iap/app_engine_app/requirements-test.txt +++ b/iap/app_engine_app/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/iap/requirements-test.txt b/iap/requirements-test.txt index 185d62c4204..23df1e03c7e 100644 --- a/iap/requirements-test.txt +++ b/iap/requirements-test.txt @@ -1,2 +1,2 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" flaky==3.8.1 diff --git a/iap/requirements.txt b/iap/requirements.txt index c0d103f39e4..452dc0220c4 100644 --- a/iap/requirements.txt +++ b/iap/requirements.txt @@ -1,4 +1,4 @@ -cryptography==45.0.1 +cryptography==46.0.7 Flask==3.1.3 google-auth==2.38.0 gunicorn==23.0.0 diff --git a/jobs/v3/api_client/noxfile_config.py b/jobs/v3/api_client/noxfile_config.py index b4d9f9b057c..6cea5520fa8 100644 --- a/jobs/v3/api_client/noxfile_config.py +++ b/jobs/v3/api_client/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/jobs/v3/api_client/requirements-test.txt b/jobs/v3/api_client/requirements-test.txt index 2a635ea7b6a..322ae75b68c 100644 --- a/jobs/v3/api_client/requirements-test.txt +++ b/jobs/v3/api_client/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1; python_version < "3.7" backoff==2.2.1; python_version >= "3.7" -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" flaky==3.8.1 diff --git a/kms/attestations/noxfile_config.py b/kms/attestations/noxfile_config.py index a68d8a75ecd..932bef266b6 100644 --- a/kms/attestations/noxfile_config.py +++ b/kms/attestations/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/kms/attestations/requirements-test.txt b/kms/attestations/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/kms/attestations/requirements-test.txt +++ b/kms/attestations/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/kms/attestations/requirements.txt b/kms/attestations/requirements.txt index 21fdd0e1147..12decf81590 100644 --- a/kms/attestations/requirements.txt +++ b/kms/attestations/requirements.txt @@ -1,4 +1,4 @@ cryptography==45.0.1 -pem==21.2.0; python_version < '3.8' +pem==23.1.0; python_version < '3.8' pem==23.1.0; python_version > '3.7' requests==2.31.0 diff --git a/kms/snippets/noxfile_config.py b/kms/snippets/noxfile_config.py index 457e86f5413..0973c8621c7 100644 --- a/kms/snippets/noxfile_config.py +++ b/kms/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/kms/snippets/requirements-test.txt b/kms/snippets/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/kms/snippets/requirements-test.txt +++ b/kms/snippets/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/kubernetes_engine/api-client/requirements-test.txt b/kubernetes_engine/api-client/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/kubernetes_engine/api-client/requirements-test.txt +++ b/kubernetes_engine/api-client/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/kubernetes_engine/django_tutorial/requirements-test.txt b/kubernetes_engine/django_tutorial/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/kubernetes_engine/django_tutorial/requirements-test.txt +++ b/kubernetes_engine/django_tutorial/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/language/snippets/api/requirements-test.txt b/language/snippets/api/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/language/snippets/api/requirements-test.txt +++ b/language/snippets/api/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/language/snippets/classify_text/noxfile_config.py b/language/snippets/classify_text/noxfile_config.py index 25d1d4e081c..50cd5669209 100644 --- a/language/snippets/classify_text/noxfile_config.py +++ b/language/snippets/classify_text/noxfile_config.py @@ -25,7 +25,7 @@ # > ℹ️ Test only on Python 3.10. # > The Python version used is defined by the Dockerfile, so it's redundant # > to run multiple tests since they would all be running the same Dockerfile. - "ignored_versions": ["2.7", "3.6", "3.7", "3.9", "3.11", "3.12", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them # "enforce_type_hints": True, diff --git a/language/snippets/classify_text/requirements-test.txt b/language/snippets/classify_text/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/language/snippets/classify_text/requirements-test.txt +++ b/language/snippets/classify_text/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/language/snippets/cloud-client/v1/requirements-test.txt b/language/snippets/cloud-client/v1/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/language/snippets/cloud-client/v1/requirements-test.txt +++ b/language/snippets/cloud-client/v1/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/language/snippets/sentiment/requirements-test.txt b/language/snippets/sentiment/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/language/snippets/sentiment/requirements-test.txt +++ b/language/snippets/sentiment/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/language/v1/requirements-test.txt b/language/v1/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/language/v1/requirements-test.txt +++ b/language/v1/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/language/v2/noxfile_config.py b/language/v2/noxfile_config.py index 38a32880121..b7d8115d773 100644 --- a/language/v2/noxfile_config.py +++ b/language/v2/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/language/v2/requirements-test.txt b/language/v2/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/language/v2/requirements-test.txt +++ b/language/v2/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/logging/import-logs/noxfile_config.py b/logging/import-logs/noxfile_config.py index e0098f56b2f..8ed5845a7a3 100644 --- a/logging/import-logs/noxfile_config.py +++ b/logging/import-logs/noxfile_config.py @@ -17,5 +17,5 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.6", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], } diff --git a/logging/import-logs/requirements-test.txt b/logging/import-logs/requirements-test.txt index 47c9e1b113d..c00563c2dde 100644 --- a/logging/import-logs/requirements-test.txt +++ b/logging/import-logs/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" google-cloud-logging~=3.11.4 google-cloud-storage~=2.10.0 diff --git a/logging/samples/snippets/requirements-test.txt b/logging/samples/snippets/requirements-test.txt index 37eb1f9aa7a..79932f83530 100644 --- a/logging/samples/snippets/requirements-test.txt +++ b/logging/samples/snippets/requirements-test.txt @@ -1,3 +1,2 @@ backoff==2.2.1 -pytest===7.4.4; python_version == '3.7' -pytest==8.2.2; python_version >= '3.8' +pytest==9.0.3; python_version >= "3.10" diff --git a/managedkafka/snippets/connect/clusters/requirements.txt b/managedkafka/snippets/connect/clusters/requirements.txt index 5f372e81c41..2903dc4f44d 100644 --- a/managedkafka/snippets/connect/clusters/requirements.txt +++ b/managedkafka/snippets/connect/clusters/requirements.txt @@ -1,5 +1,5 @@ protobuf==5.29.4 -pytest==8.2.2 +pytest==9.0.3; python_version >= "3.10" google-api-core==2.23.0 google-auth==2.38.0 google-cloud-managedkafka==0.1.12 diff --git a/managedkafka/snippets/requirements.txt b/managedkafka/snippets/requirements.txt index 5f372e81c41..2903dc4f44d 100644 --- a/managedkafka/snippets/requirements.txt +++ b/managedkafka/snippets/requirements.txt @@ -1,5 +1,5 @@ protobuf==5.29.4 -pytest==8.2.2 +pytest==9.0.3; python_version >= "3.10" google-api-core==2.23.0 google-auth==2.38.0 google-cloud-managedkafka==0.1.12 diff --git a/media-translation/snippets/noxfile_config.py b/media-translation/snippets/noxfile_config.py index a68d8a75ecd..932bef266b6 100644 --- a/media-translation/snippets/noxfile_config.py +++ b/media-translation/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/media-translation/snippets/requirements-test.txt b/media-translation/snippets/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/media-translation/snippets/requirements-test.txt +++ b/media-translation/snippets/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/media_cdn/requirements-test.txt b/media_cdn/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/media_cdn/requirements-test.txt +++ b/media_cdn/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/memorystore/memcache/noxfile_config.py b/memorystore/memcache/noxfile_config.py index e70e0f7ff70..0d9b541774e 100644 --- a/memorystore/memcache/noxfile_config.py +++ b/memorystore/memcache/noxfile_config.py @@ -23,7 +23,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # We only run the cloud run tests in py38 session. - "ignored_versions": ["2.7", "3.6", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/memorystore/redis/cloud_run_deployment/Dockerfile b/memorystore/redis/cloud_run_deployment/Dockerfile index 94548382d70..81e9d8f6404 100644 --- a/memorystore/redis/cloud_run_deployment/Dockerfile +++ b/memorystore/redis/cloud_run_deployment/Dockerfile @@ -14,7 +14,7 @@ # Use the official lightweight Python image. # https://hub.docker.com/_/python -FROM python:3.11-slim +FROM python:3.14-slim # Copy local code to the container image. ENV APP_HOME /app diff --git a/memorystore/redis/noxfile_config.py b/memorystore/redis/noxfile_config.py index bf45881273d..f6a3cf7417f 100644 --- a/memorystore/redis/noxfile_config.py +++ b/memorystore/redis/noxfile_config.py @@ -23,7 +23,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. # We only run the cloud run tests in py38 session. - "ignored_versions": ["2.7", "3.6", "3.7"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/memorystore/redis/requirements-test.txt b/memorystore/redis/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/memorystore/redis/requirements-test.txt +++ b/memorystore/redis/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/model_armor/snippets/noxfile_config.py b/model_armor/snippets/noxfile_config.py index 29c18b2ba9c..293769315f2 100644 --- a/model_armor/snippets/noxfile_config.py +++ b/model_armor/snippets/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/model_armor/snippets/requirements-test.txt b/model_armor/snippets/requirements-test.txt index 1c987370aa9..c9e154ba440 100644 --- a/model_armor/snippets/requirements-test.txt +++ b/model_armor/snippets/requirements-test.txt @@ -1 +1 @@ -pytest==8.3.4 \ No newline at end of file +pytest==9.0.3; python_version >= "3.10" diff --git a/model_garden/anthropic/noxfile_config.py b/model_garden/anthropic/noxfile_config.py index 2a0f115c38f..0973c8621c7 100644 --- a/model_garden/anthropic/noxfile_config.py +++ b/model_garden/anthropic/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.12"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/model_garden/anthropic/requirements-test.txt b/model_garden/anthropic/requirements-test.txt index 73541a927f4..de695820000 100644 --- a/model_garden/anthropic/requirements-test.txt +++ b/model_garden/anthropic/requirements-test.txt @@ -1,4 +1,4 @@ google-api-core==2.24.0 google-cloud-bigquery==3.29.0 google-cloud-storage==2.19.0 -pytest==8.2.0 \ No newline at end of file +pytest==9.0.3; python_version >= "3.10" diff --git a/model_garden/gemma/noxfile_config.py b/model_garden/gemma/noxfile_config.py index 962ba40a926..0973c8621c7 100644 --- a/model_garden/gemma/noxfile_config.py +++ b/model_garden/gemma/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.11", "3.13"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": True, diff --git a/model_garden/gemma/requirements-test.txt b/model_garden/gemma/requirements-test.txt index 92281986e50..baa23bf9c3e 100644 --- a/model_garden/gemma/requirements-test.txt +++ b/model_garden/gemma/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 google-api-core==2.19.0 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" pytest-asyncio==0.23.6 diff --git a/monitoring/api/v3/api-client/README.rst b/monitoring/api/v3/api-client/README.rst index b905644a9e8..0b83c81e51f 100644 --- a/monitoring/api/v3/api-client/README.rst +++ b/monitoring/api/v3/api-client/README.rst @@ -1,18 +1,18 @@ .. This file is automatically generated. Do not edit this file directly. -Stackdriver Monitoring Python Samples +Cloud Monitoring Python Samples =============================================================================== .. image:: https://gstatic.com/cloudssh/images/open-btn.png :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/api-client/README.rst -This directory contains samples for Stackdriver Monitoring. `Stackdriver Monitoring `_ collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Stackdriver ingests that data and generates insights via dashboards, charts, and alerts. +This directory contains samples for Cloud Monitoring. `Cloud Monitoring `_ collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Cloud Monitoring ingests that data and generates insights via dashboards, charts, and alerts. -.. _Stackdriver Monitoring: https://cloud.google.com/monitoring/docs +.. _Cloud Monitoring: https://cloud.google.com/monitoring/docs Setup ------------------------------------------------------------------------------- @@ -78,7 +78,7 @@ To run this sample: usage: list_resources.py [-h] --project_id PROJECT_ID - Sample command-line program for retrieving Stackdriver Monitoring API V3 + Sample command-line program for retrieving Cloud Monitoring API V3 data. See README.md for instructions on setting up your development environment. @@ -111,7 +111,7 @@ To run this sample: usage: custom_metric.py [-h] --project_id PROJECT_ID - Sample command-line program for writing and reading Stackdriver Monitoring + Sample command-line program for writing and reading Cloud Monitoring API V3 custom metrics. Simple command-line program to demonstrate connecting to the Google diff --git a/monitoring/api/v3/api-client/README.rst.in b/monitoring/api/v3/api-client/README.rst.in index e71bd6de87c..529a45128cb 100644 --- a/monitoring/api/v3/api-client/README.rst.in +++ b/monitoring/api/v3/api-client/README.rst.in @@ -1,15 +1,15 @@ # This file is used to generate README.rst product: - name: Stackdriver Monitoring - short_name: Stackdriver Monitoring + name: Cloud Monitoring + short_name: Cloud Monitoring url: https://cloud.google.com/monitoring/docs description: > - `Stackdriver Monitoring `_ collects metrics, events, and metadata from + `Cloud Monitoring `_ collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many - others. Stackdriver ingests that data and generates insights via + others. Cloud Monitoring ingests that data and generates insights via dashboards, charts, and alerts. setup: diff --git a/monitoring/api/v3/api-client/list_resources.py b/monitoring/api/v3/api-client/list_resources.py index e77e610314f..2a4aac9f904 100644 --- a/monitoring/api/v3/api-client/list_resources.py +++ b/monitoring/api/v3/api-client/list_resources.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Sample command-line program for retrieving Stackdriver Monitoring API V3 +"""Sample command-line program for retrieving Cloud Monitoring API V3 data. See README.md for instructions on setting up your development environment. diff --git a/monitoring/api/v3/api-client/requirements-test.txt b/monitoring/api/v3/api-client/requirements-test.txt index 2a635ea7b6a..322ae75b68c 100644 --- a/monitoring/api/v3/api-client/requirements-test.txt +++ b/monitoring/api/v3/api-client/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1; python_version < "3.7" backoff==2.2.1; python_version >= "3.7" -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" flaky==3.8.1 diff --git a/monitoring/opencensus/requirements-test.txt b/monitoring/opencensus/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/monitoring/opencensus/requirements-test.txt +++ b/monitoring/opencensus/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/monitoring/prometheus/requirements-test.txt b/monitoring/prometheus/requirements-test.txt index 15d066af319..c9e154ba440 100644 --- a/monitoring/prometheus/requirements-test.txt +++ b/monitoring/prometheus/requirements-test.txt @@ -1 +1 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/monitoring/snippets/v3/alerts-client/README.rst b/monitoring/snippets/v3/alerts-client/README.rst index bb59aad5fee..4f941d6fc14 100644 --- a/monitoring/snippets/v3/alerts-client/README.rst +++ b/monitoring/snippets/v3/alerts-client/README.rst @@ -1,18 +1,18 @@ .. This file is automatically generated. Do not edit this file directly. -Google Stackdriver Alerting API Python Samples +Google Cloud Monitoring Alerting API Python Samples =============================================================================== .. image:: https://gstatic.com/cloudssh/images/open-btn.png :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/alerts-client/README.rst -This directory contains samples for Google Stackdriver Alerting API. Stackdriver Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Stackdriver's Alerting API allows you to create, delete, and make back up copies of your alert policies. +This directory contains samples for Google Cloud Monitoring Alerting API. Cloud Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Cloud Monitoring's Alerting API allows you to create, delete, and make back up copies of your alert policies. -.. _Google Stackdriver Alerting API: https://cloud.google.com/monitoring/alerts/ +.. _Google Cloud Monitoring Alerting API: https://cloud.google.com/monitoring/alerts/ To run the sample, you need to enable the API at: https://console.cloud.google.com/apis/library/monitoring.googleapis.com diff --git a/monitoring/snippets/v3/alerts-client/README.rst.in b/monitoring/snippets/v3/alerts-client/README.rst.in index 00b280124ea..c3bd356a750 100644 --- a/monitoring/snippets/v3/alerts-client/README.rst.in +++ b/monitoring/snippets/v3/alerts-client/README.rst.in @@ -1,15 +1,15 @@ # This file is used to generate README.rst product: - name: Google Stackdriver Alerting API - short_name: Stackdriver Alerting API + name: Google Cloud Monitoring Alerting API + short_name: Cloud Monitoring Alerting API url: https://cloud.google.com/monitoring/alerts/ description: > - Stackdriver Monitoring collects metrics, events, and metadata from Google + Cloud Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch - and many others. Stackdriver's Alerting API allows you to create, + and many others. Cloud Monitoring's Alerting API allows you to create, delete, and make back up copies of your alert policies. required_api_url: https://console.cloud.google.com/apis/library/monitoring.googleapis.com diff --git a/monitoring/snippets/v3/alerts-client/noxfile_config.py b/monitoring/snippets/v3/alerts-client/noxfile_config.py index 083b166d18c..f5de96c352a 100644 --- a/monitoring/snippets/v3/alerts-client/noxfile_config.py +++ b/monitoring/snippets/v3/alerts-client/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Declare optional test sessions you want to opt-in. Currently we # have the following optional test sessions: # 'cloud_run' # Test session for Cloud Run application. diff --git a/monitoring/snippets/v3/alerts-client/requirements-test.txt b/monitoring/snippets/v3/alerts-client/requirements-test.txt index e312099c33c..568cffaec48 100644 --- a/monitoring/snippets/v3/alerts-client/requirements-test.txt +++ b/monitoring/snippets/v3/alerts-client/requirements-test.txt @@ -1,3 +1,3 @@ -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" retrying==1.3.4 flaky==3.8.1 diff --git a/monitoring/snippets/v3/cloud-client/README.rst b/monitoring/snippets/v3/cloud-client/README.rst index 280f9c4e0a7..64e62d36ad9 100644 --- a/monitoring/snippets/v3/cloud-client/README.rst +++ b/monitoring/snippets/v3/cloud-client/README.rst @@ -1,20 +1,20 @@ .. This file is automatically generated. Do not edit this file directly. -Google Stackdriver Monitoring API Python Samples +Google Cloud Monitoring API Python Samples =============================================================================== .. image:: https://gstatic.com/cloudssh/images/open-btn.png :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/cloud-client/README.rst -This directory contains samples for Google Stackdriver Monitoring API. Stackdriver Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch - and many others. Stackdriver ingests that data and generates insights +This directory contains samples for Google Cloud Monitoring API. Cloud Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch + and many others. Cloud Monitoring ingests that data and generates insights via dashboards, charts, and alerts. -.. _Google Stackdriver Monitoring API: https://cloud.google.com/monitoring/docs/ +.. _Google Cloud Monitoring API: https://cloud.google.com/monitoring/docs/ To run the sample, you need to enable the API at: https://console.cloud.google.com/apis/library/monitoring.googleapis.com diff --git a/monitoring/snippets/v3/cloud-client/README.rst.in b/monitoring/snippets/v3/cloud-client/README.rst.in index 0ab6b2258b7..8ac06335517 100644 --- a/monitoring/snippets/v3/cloud-client/README.rst.in +++ b/monitoring/snippets/v3/cloud-client/README.rst.in @@ -1,15 +1,15 @@ # This file is used to generate README.rst product: - name: Google Stackdriver Monitoring API - short_name: Stackdriver Monitoring API + name: Google Cloud Monitoring API + short_name: Cloud Monitoring API url: https://cloud.google.com/monitoring/docs/ description: > - Stackdriver Monitoring collects metrics, events, and metadata from Google + Cloud Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch - and many others. Stackdriver ingests that data and generates insights + and many others. Cloud Monitoring ingests that data and generates insights via dashboards, charts, and alerts. required_api_url: https://console.cloud.google.com/apis/library/monitoring.googleapis.com diff --git a/monitoring/snippets/v3/cloud-client/noxfile_config.py b/monitoring/snippets/v3/cloud-client/noxfile_config.py index 083b166d18c..f5de96c352a 100644 --- a/monitoring/snippets/v3/cloud-client/noxfile_config.py +++ b/monitoring/snippets/v3/cloud-client/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Declare optional test sessions you want to opt-in. Currently we # have the following optional test sessions: # 'cloud_run' # Test session for Cloud Run application. diff --git a/monitoring/snippets/v3/cloud-client/requirements-test.txt b/monitoring/snippets/v3/cloud-client/requirements-test.txt index f3230681cda..79932f83530 100644 --- a/monitoring/snippets/v3/cloud-client/requirements-test.txt +++ b/monitoring/snippets/v3/cloud-client/requirements-test.txt @@ -1,2 +1,2 @@ backoff==2.2.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/monitoring/snippets/v3/uptime-check-client/README.rst b/monitoring/snippets/v3/uptime-check-client/README.rst index 30046bdef9d..b565f9e4884 100644 --- a/monitoring/snippets/v3/uptime-check-client/README.rst +++ b/monitoring/snippets/v3/uptime-check-client/README.rst @@ -1,18 +1,18 @@ .. This file is automatically generated. Do not edit this file directly. -Google Stackdriver Uptime Checks API Python Samples +Google Cloud Monitoring Uptime Checks API Python Samples =============================================================================== .. image:: https://gstatic.com/cloudssh/images/open-btn.png :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/uptime-check-client/README.rst -This directory contains samples for Google Stackdriver Uptime Checks API. Stackdriver Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Stackdriver's Uptime Checks API allows you to create, delete, and list your project's Uptime Checks. +This directory contains samples for Google Cloud Monitoring Uptime Checks API. Cloud Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Cloud Monitoring's Uptime Checks API allows you to create, delete, and list your project's Uptime Checks. -.. _Google Stackdriver Uptime Checks API: https://cloud.google.com/monitoring/uptime-checks/management +.. _Google Cloud Monitoring Uptime Checks API: https://cloud.google.com/monitoring/uptime-checks/management Setup ------------------------------------------------------------------------------- diff --git a/monitoring/snippets/v3/uptime-check-client/README.rst.in b/monitoring/snippets/v3/uptime-check-client/README.rst.in index 1174962e48d..84998ed3529 100644 --- a/monitoring/snippets/v3/uptime-check-client/README.rst.in +++ b/monitoring/snippets/v3/uptime-check-client/README.rst.in @@ -1,15 +1,15 @@ # This file is used to generate README.rst product: - name: Google Stackdriver Uptime Checks API - short_name: Stackdriver Uptime Checks API + name: Google Cloud Monitoring Uptime Checks API + short_name: Cloud Uptime Checks API url: https://cloud.google.com/monitoring/uptime-checks/management description: > - Stackdriver Monitoring collects metrics, events, and metadata from Google + Cloud Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch - and many others. Stackdriver's Uptime Checks API allows you to create, + and many others. Cloud Monitoring's Uptime Checks API allows you to create, delete, and list your project's Uptime Checks. setup: diff --git a/monitoring/snippets/v3/uptime-check-client/noxfile_config.py b/monitoring/snippets/v3/uptime-check-client/noxfile_config.py index 083b166d18c..f5de96c352a 100644 --- a/monitoring/snippets/v3/uptime-check-client/noxfile_config.py +++ b/monitoring/snippets/v3/uptime-check-client/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.9", "3.10", "3.11"], + "ignored_versions": ["3.8", "3.9", "3.11", "3.12", "3.13"], # Declare optional test sessions you want to opt-in. Currently we # have the following optional test sessions: # 'cloud_run' # Test session for Cloud Run application. diff --git a/monitoring/snippets/v3/uptime-check-client/requirements-test.txt b/monitoring/snippets/v3/uptime-check-client/requirements-test.txt index f3230681cda..79932f83530 100644 --- a/monitoring/snippets/v3/uptime-check-client/requirements-test.txt +++ b/monitoring/snippets/v3/uptime-check-client/requirements-test.txt @@ -1,2 +1,2 @@ backoff==2.2.1 -pytest==8.2.0 +pytest==9.0.3; python_version >= "3.10" diff --git a/parametermanager/snippets-adk/README.md b/parametermanager/snippets-adk/README.md new file mode 100644 index 00000000000..a2ab8a841eb --- /dev/null +++ b/parametermanager/snippets-adk/README.md @@ -0,0 +1,99 @@ +# ADK Parameter Manager Samples + +This directory contains samples demonstrating how to use the Agent Development Kit (ADK) with Google Cloud Parameter Manager. + +## Folders +* `agent_global`: Sample for accessing parameters from a global Parameter Manager instance. +* `agent_regional`: Sample for accessing parameters from a regional Parameter Manager endpoint. + +## Prerequisites + +1. **Create and activate a virtual environment**: + ```bash + python3 -m venv .venv + source .venv/bin/activate + ``` + +2. **Set up Application Default Credentials**: + ```bash + gcloud auth application-default login + ``` + +3. **Install dependencies**: + You need to install dependencies for the specific sample or test you want to run. + + For global agent samples and tests: + ```bash + pip install -r agent_global/requirements.txt + ``` + + For regional agent samples and tests: + ```bash + pip install -r agent_regional/requirements.txt + ``` + +4. **Set up environment variables**: + * `GOOGLE_CLOUD_PROJECT`: Your Google Cloud Project ID. (Required for both samples and tests). + + The following environment variables are **only required when running the samples manually**. The tests will generate and use their own temporary parameters automatically. + + * `ADK_TEST_PARAMETER_ID`: The ID of the parameter to access. + * `ADK_TEST_PARAMETER_VERSION` (Optional): The version of the parameter (defaults to `latest`). + * `GOOGLE_CLOUD_PROJECT_LOCATION` (Required for regional samples): The region where the parameter is located (e.g., `us-central1`). + +## Running the Samples + +The samples are designed to be run from this directory (`snippets-adk`) using the `adk run` command. + +### Global Parameter Manager Agent + +1. **Create a `.env` file** alongside `agent.py` in the `agent_global` directory: + ```env + GOOGLE_GENAI_USE_VERTEXAI=1 + GOOGLE_CLOUD_PROJECT=your-project-id + GOOGLE_CLOUD_LOCATION=us-central1 + ``` + *Note: Replace `your-project-id` with your GCP project ID.* + +2. **Run the agent**: + ```bash + export GOOGLE_CLOUD_PROJECT="your-project-id" + export ADK_TEST_PARAMETER_ID="your-parameter-id" + adk run agent_global + ``` + +### Regional Parameter Manager Agent + +1. **Create a `.env` file** alongside `agent.py` in the `agent_regional` directory: + ```env + GOOGLE_GENAI_USE_VERTEXAI=1 + GOOGLE_CLOUD_PROJECT=your-project-id + GOOGLE_CLOUD_LOCATION=us-central1 + ``` + *Note: Replace `your-project-id` with your GCP project ID.* + +2. **Run the agent**: + ```bash + export GOOGLE_CLOUD_PROJECT="your-project-id" + export GOOGLE_CLOUD_PROJECT_LOCATION="us-central1" + export ADK_TEST_PARAMETER_ID="your-parameter-id" + adk run agent_regional + ``` + +## Running the Tests + +The tests are located within the specific agent folders and run the samples using `adk run`. + +To run tests for the global agent: +```bash +pip install -r agent_global/requirements.txt +pip install -r agent_global/requirements-test.txt +pytest agent_global/snippets_adk_test.py +``` + +To run tests for the regional agent: +```bash +pip install -r agent_regional/requirements.txt +pip install -r agent_regional/requirements-test.txt +pytest agent_regional/snippets_adk_test.py +``` diff --git a/parametermanager/snippets-adk/agent_global/agent.py b/parametermanager/snippets-adk/agent_global/agent.py new file mode 100644 index 00000000000..3ec915375ae --- /dev/null +++ b/parametermanager/snippets-adk/agent_global/agent.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# Copyright 2026 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. +""" +ADK agent for accessing parameters from global Parameter Manager. +""" + +import os + +from google.adk import Agent +from google.adk.integrations.parameter_manager.parameter_client import ParameterManagerClient + +# Fetch parameter from global Parameter Manager +project_id = os.environ.get("GOOGLE_CLOUD_PROJECT") +parameter_id = os.environ.get("ADK_TEST_PARAMETER_ID") +parameter_version = os.environ.get("ADK_TEST_PARAMETER_VERSION", "latest") + +if not project_id or not parameter_id: + raise ValueError("GOOGLE_CLOUD_PROJECT and ADK_TEST_PARAMETER_ID environment variables must be set.") + +resource_name = f"projects/{project_id}/locations/global/parameters/{parameter_id}/versions/{parameter_version}" + +print("Fetching parameter from global Parameter Manager...") +# Initialize Parameter Manager Client +client = ParameterManagerClient() + +# Fetch parameter +try: + parameter_payload = client.get_parameter(resource_name) + print("Successfully fetched parameter.") +except Exception as e: + print(f"Error fetching parameter: {e}") + raise e + +# Initialize Agent +root_agent = Agent( + model='gemini-2.5-flash', + name='root_agent', + description='A helpful assistant for user questions.', + instruction='Answer user questions to the best of your knowledge', +) + +print("Agent initialized successfully.") diff --git a/parametermanager/snippets-adk/agent_global/noxfile_config.py b/parametermanager/snippets-adk/agent_global/noxfile_config.py new file mode 100644 index 00000000000..2a42a33e5e8 --- /dev/null +++ b/parametermanager/snippets-adk/agent_global/noxfile_config.py @@ -0,0 +1,27 @@ +# Copyright 2026 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": True, + # An envvar key for determining the project id to use. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # A dictionary you want to inject into your test. + "envs": {}, +} diff --git a/parametermanager/snippets-adk/agent_global/requirements-test.txt b/parametermanager/snippets-adk/agent_global/requirements-test.txt new file mode 100644 index 00000000000..b3b2b3ca4cc --- /dev/null +++ b/parametermanager/snippets-adk/agent_global/requirements-test.txt @@ -0,0 +1 @@ +pytest==9.0.3 diff --git a/parametermanager/snippets-adk/agent_global/requirements.txt b/parametermanager/snippets-adk/agent_global/requirements.txt new file mode 100644 index 00000000000..a7a4fdd4908 --- /dev/null +++ b/parametermanager/snippets-adk/agent_global/requirements.txt @@ -0,0 +1 @@ +google-adk[extensions]>=1.30 diff --git a/parametermanager/snippets-adk/agent_global/snippets_adk_test.py b/parametermanager/snippets-adk/agent_global/snippets_adk_test.py new file mode 100644 index 00000000000..57746824045 --- /dev/null +++ b/parametermanager/snippets-adk/agent_global/snippets_adk_test.py @@ -0,0 +1,112 @@ +# Copyright 2026 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 os +import subprocess +import time +from typing import Iterator +import uuid + +from google.api_core import exceptions +from google.cloud import parametermanager_v1 +import pytest + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PARENT_DIR = os.path.dirname(CURRENT_DIR) + + +@pytest.fixture() +def client() -> parametermanager_v1.ParameterManagerClient: + return parametermanager_v1.ParameterManagerClient() + + +@pytest.fixture() +def project_id() -> str: + return os.environ["GOOGLE_CLOUD_PROJECT"] + + +@pytest.fixture() +def parameter_id( + client: parametermanager_v1.ParameterManagerClient, project_id: str +) -> Iterator[str]: + parameter_id = f"python-adk-test-{uuid.uuid4()}" + yield parameter_id + + # Teardown: delete the version then the parameter + version_path = client.parameter_version_path(project_id, "global", parameter_id, "1") + parameter_path = client.parameter_path(project_id, "global", parameter_id) + + print("Deleting parameter version 1...") + try: + time.sleep(1) + client.delete_parameter_version(request={"name": version_path}) + except exceptions.NotFound: + pass + + print(f"Deleting parameter {parameter_id}...") + try: + time.sleep(2) + client.delete_parameter(name=parameter_path) + except exceptions.NotFound: + pass + + +def test_agent_global( + client: parametermanager_v1.ParameterManagerClient, project_id: str, parameter_id: str +) -> None: + # Create the parameter + parent = client.common_location_path(project_id, "global") + print(f"Creating parameter {parameter_id}...") + client.create_parameter( + request={ + "parent": parent, + "parameter_id": parameter_id, + } + ) + + # Add a version + parameter_path = client.parameter_path(project_id, "global", parameter_id) + print(f"Adding version to {parameter_id}...") + client.create_parameter_version( + request={ + "parent": parameter_path, + "parameter_version_id": "1", + "parameter_version": { + "payload": {"data": b"test-payload"} + }, + } + ) + + # Set environment variables required by the agent + os.environ["ADK_TEST_PARAMETER_ID"] = parameter_id + os.environ["ADK_TEST_PARAMETER_VERSION"] = "1" + + print(f"Running adk run agent_global from {PARENT_DIR}...") + # Run the sample using adk run + result = subprocess.run( + ["adk", "run", "agent_global"], + input="exit\n", + capture_output=True, + text=True, + cwd=PARENT_DIR, + ) + + print("STDOUT:") + print(result.stdout) + print("STDERR:") + print(result.stderr) + + assert result.returncode == 0 + assert "Successfully fetched parameter" in result.stdout + assert "Agent initialized successfully" in result.stdout diff --git a/parametermanager/snippets-adk/agent_regional/agent.py b/parametermanager/snippets-adk/agent_regional/agent.py new file mode 100644 index 00000000000..0c633dc8131 --- /dev/null +++ b/parametermanager/snippets-adk/agent_regional/agent.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +# Copyright 2026 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. +""" +ADK agent for accessing parameters from regional Parameter Manager. +""" + +import os + +from google.adk import Agent +from google.adk.integrations.parameter_manager.parameter_client import ParameterManagerClient + +# Fetch parameter from regional Parameter Manager +project_id = os.environ.get("GOOGLE_CLOUD_PROJECT") +location = os.environ.get("GOOGLE_CLOUD_PROJECT_LOCATION") +parameter_id = os.environ.get("ADK_TEST_PARAMETER_ID") +parameter_version = os.environ.get("ADK_TEST_PARAMETER_VERSION", "latest") + +if not project_id or not location or not parameter_id: + raise ValueError("GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_PROJECT_LOCATION, and ADK_TEST_PARAMETER_ID environment variables must be set.") + +resource_name = f"projects/{project_id}/locations/{location}/parameters/{parameter_id}/versions/{parameter_version}" + +print(f"Fetching parameter from regional Parameter Manager ({location})...") +# Initialize Parameter Manager Client (Regional) +client = ParameterManagerClient(location=location) + +# Fetch parameter +try: + parameter_payload = client.get_parameter(resource_name) + print("Successfully fetched parameter.") +except Exception as e: + print(f"Error fetching parameter: {e}") + raise e + +# Initialize Agent +root_agent = Agent( + model='gemini-2.5-flash', + name='root_agent', + description='A helpful assistant for user questions.', + instruction='Answer user questions to the best of your knowledge', +) + +print("Agent initialized successfully.") diff --git a/parametermanager/snippets-adk/agent_regional/noxfile_config.py b/parametermanager/snippets-adk/agent_regional/noxfile_config.py new file mode 100644 index 00000000000..2a42a33e5e8 --- /dev/null +++ b/parametermanager/snippets-adk/agent_regional/noxfile_config.py @@ -0,0 +1,27 @@ +# Copyright 2026 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": True, + # An envvar key for determining the project id to use. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # A dictionary you want to inject into your test. + "envs": {}, +} diff --git a/parametermanager/snippets-adk/agent_regional/requirements-test.txt b/parametermanager/snippets-adk/agent_regional/requirements-test.txt new file mode 100644 index 00000000000..15d066af319 --- /dev/null +++ b/parametermanager/snippets-adk/agent_regional/requirements-test.txt @@ -0,0 +1 @@ +pytest==8.2.0 diff --git a/parametermanager/snippets-adk/agent_regional/requirements.txt b/parametermanager/snippets-adk/agent_regional/requirements.txt new file mode 100644 index 00000000000..a7a4fdd4908 --- /dev/null +++ b/parametermanager/snippets-adk/agent_regional/requirements.txt @@ -0,0 +1 @@ +google-adk[extensions]>=1.30 diff --git a/parametermanager/snippets-adk/agent_regional/snippets_adk_test.py b/parametermanager/snippets-adk/agent_regional/snippets_adk_test.py new file mode 100644 index 00000000000..f523a72b073 --- /dev/null +++ b/parametermanager/snippets-adk/agent_regional/snippets_adk_test.py @@ -0,0 +1,124 @@ +# Copyright 2026 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 os +import subprocess +import time +from typing import Iterator +import uuid + +from google.api_core import exceptions +from google.cloud import parametermanager_v1 +import pytest + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PARENT_DIR = os.path.dirname(CURRENT_DIR) + + +@pytest.fixture() +def location() -> str: + return "us-central1" + + +@pytest.fixture() +def client(location: str) -> parametermanager_v1.ParameterManagerClient: + api_endpoint = f"parametermanager.{location}.rep.googleapis.com" + return parametermanager_v1.ParameterManagerClient( + client_options={"api_endpoint": api_endpoint} + ) + + +@pytest.fixture() +def project_id() -> str: + return os.environ["GOOGLE_CLOUD_PROJECT"] + + +@pytest.fixture() +def parameter_id( + client: parametermanager_v1.ParameterManagerClient, project_id: str, location: str +) -> Iterator[str]: + parameter_id = f"python-adk-test-{uuid.uuid4()}" + yield parameter_id + + # Teardown: delete the version then the parameter + version_path = f"projects/{project_id}/locations/{location}/parameters/{parameter_id}/versions/1" + parameter_path = f"projects/{project_id}/locations/{location}/parameters/{parameter_id}" + + print("Deleting parameter version 1...") + try: + time.sleep(1) + client.delete_parameter_version(request={"name": version_path}) + except exceptions.NotFound: + pass + + print(f"Deleting parameter {parameter_id}...") + try: + time.sleep(2) + client.delete_parameter(name=parameter_path) + except exceptions.NotFound: + pass + + +def test_agent_regional( + client: parametermanager_v1.ParameterManagerClient, + project_id: str, + location: str, + parameter_id: str, +) -> None: + # Create the parameter + parent = f"projects/{project_id}/locations/{location}" + print(f"Creating regional parameter {parameter_id} in {location}...") + client.create_parameter( + request={ + "parent": parent, + "parameter_id": parameter_id, + } + ) + + # Add a version + parameter_path = f"projects/{project_id}/locations/{location}/parameters/{parameter_id}" + print(f"Adding version to {parameter_id}...") + client.create_parameter_version( + request={ + "parent": parameter_path, + "parameter_version_id": "1", + "parameter_version": { + "payload": {"data": b"test-payload"} + }, + } + ) + + # Set environment variables required by the agent + os.environ["ADK_TEST_PARAMETER_ID"] = parameter_id + os.environ["ADK_TEST_PARAMETER_VERSION"] = "1" + os.environ["GOOGLE_CLOUD_PROJECT_LOCATION"] = location + + print(f"Running adk run agent_regional from {PARENT_DIR}...") + # Run the sample using adk run + result = subprocess.run( + ["adk", "run", "agent_regional"], + input="exit\n", + capture_output=True, + text=True, + cwd=PARENT_DIR, + ) + + print("STDOUT:") + print(result.stdout) + print("STDERR:") + print(result.stderr) + + assert result.returncode == 0 + assert "Successfully fetched parameter" in result.stdout + assert "Agent initialized successfully" in result.stdout diff --git a/parametermanager/snippets/get_param_version.py b/parametermanager/snippets/get_param_version.py index dace37d53ac..aaf75a4936a 100644 --- a/parametermanager/snippets/get_param_version.py +++ b/parametermanager/snippets/get_param_version.py @@ -20,6 +20,12 @@ # [START parametermanager_get_param_version] + +# The GetParameterVersion operation retrieves parameter metadata and doesn't +# support high-volume access. To access parameter values at scale, +# see Access a parameter version (https://docs.cloud.google.com/secret-manager/parameter-manager/docs/render-parameter-version). + + def get_param_version( project_id: str, parameter_id: str, version_id: str ) -> parametermanager_v1.ParameterVersion: diff --git a/parametermanager/snippets/regional_samples/render_regional_param_version.py b/parametermanager/snippets/regional_samples/render_regional_param_version.py index 106a684bc79..5ff7e122df9 100644 --- a/parametermanager/snippets/regional_samples/render_regional_param_version.py +++ b/parametermanager/snippets/regional_samples/render_regional_param_version.py @@ -34,7 +34,8 @@ def render_regional_param_version( location_id (str): The ID of the region where the parameter is located. parameter_id (str): The ID of the parameter for which version details are to be rendered. - version_id (str): The ID of the version to be rendered. + version_id (str): The ID of the version or alias (e.g. "latest") to + be rendered. Returns: parametermanager_v1.RenderParameterVersionResponse: An object diff --git a/parametermanager/snippets/render_param_version.py b/parametermanager/snippets/render_param_version.py index 7a0cefe3298..1c9a8b64618 100644 --- a/parametermanager/snippets/render_param_version.py +++ b/parametermanager/snippets/render_param_version.py @@ -32,7 +32,7 @@ def render_param_version( project_id (str): The ID of the project where the parameter is located. parameter_id (str): The ID of the parameter for which version details are to be rendered. - version_id (str): The ID of the version to be rendered. + version_id (str): The ID of the version or alias (e.g. "latest") to be rendered. Returns: parametermanager_v1.RenderParameterVersionResponse: An object diff --git a/pubsub/streaming-analytics/PubSubToGCS_test.py b/pubsub/streaming-analytics/PubSubToGCS_test.py index 35fd9fa5a89..8ce4e0bff2d 100644 --- a/pubsub/streaming-analytics/PubSubToGCS_test.py +++ b/pubsub/streaming-analytics/PubSubToGCS_test.py @@ -61,7 +61,7 @@ def test_pubsub_to_gcs(): # Check for output files on GCS. gcs_client = GcsIO() - files = gcs_client.list_prefix(f"gs://{BUCKET}/pubsub/{UUID}") + files = dict(gcs_client.list_files(f"gs://{BUCKET}/pubsub/{UUID}")) assert len(files) > 0 # Clean up. diff --git a/pubsub/streaming-analytics/README.md b/pubsub/streaming-analytics/README.md index 11706cf600b..f22a6ae5a2b 100644 --- a/pubsub/streaming-analytics/README.md +++ b/pubsub/streaming-analytics/README.md @@ -26,7 +26,7 @@ Sample(s) showing how to use [Google Cloud Pub/Sub] with [Google Cloud Dataflow] gcloud init ``` -1. [Enable the APIs](https://console.cloud.google.com/flows/enableapi?apiid=dataflow,compute_component,logging,storage_component,storage_api,pubsub,cloudresourcemanager.googleapis.com,cloudscheduler.googleapis.com,appengine.googleapis.com): Dataflow, Compute Engine, Stackdriver Logging, Cloud Storage, Cloud Storage JSON, Pub/Sub, Cloud Scheduler, Cloud Resource Manager, and App Engine. +1. [Enable the APIs](https://console.cloud.google.com/flows/enableapi?apiid=dataflow,compute_component,logging,storage_component,storage_api,pubsub,cloudresourcemanager.googleapis.com,cloudscheduler.googleapis.com,appengine.googleapis.com): Dataflow, Compute Engine, Cloud Logging, Cloud Storage, Cloud Storage JSON, Pub/Sub, Cloud Scheduler, Cloud Resource Manager, and App Engine. 1. Create a service account JSON key via the [*Create service account key* page], diff --git a/pubsub/streaming-analytics/noxfile_config.py b/pubsub/streaming-analytics/noxfile_config.py index 783945807ee..17b48115e0c 100644 --- a/pubsub/streaming-analytics/noxfile_config.py +++ b/pubsub/streaming-analytics/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.6", "3.9", "3.10", "3.11", "3.12", "3.13"], + "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.14"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/pubsub/streaming-analytics/requirements.txt b/pubsub/streaming-analytics/requirements.txt index 7dac644ad0f..44955c079c5 100644 --- a/pubsub/streaming-analytics/requirements.txt +++ b/pubsub/streaming-analytics/requirements.txt @@ -1 +1 @@ -apache-beam[gcp,test]==2.42.0 +apache-beam[gcp,test]==2.72.0 diff --git a/run/django/e2e_test_cleanup.yaml b/run/django/e2e_test_cleanup.yaml index 0006140f871..f3af8441112 100644 --- a/run/django/e2e_test_cleanup.yaml +++ b/run/django/e2e_test_cleanup.yaml @@ -22,8 +22,8 @@ steps: ./retry.sh "gcloud secrets describe ${_SECRET_SETTINGS_NAME}" \ "gcloud secrets delete ${_SECRET_SETTINGS_NAME} --quiet --project $PROJECT_ID" - ./retry.sh "gsutil ls gs://${_STORAGE_BUCKET}" \ - "gsutil -m rm -r gs://${_STORAGE_BUCKET}" + ./retry.sh "gcloud storage ls gs://${_STORAGE_BUCKET}" \ + "gcloud storage rm --recursive gs://${_STORAGE_BUCKET}" ./retry.sh "gcloud artifacts docker images describe ${_IMAGE_NAME}" \ "gcloud artifacts docker images delete ${_IMAGE_NAME} --quiet" diff --git a/run/django/e2e_test_setup.yaml b/run/django/e2e_test_setup.yaml index dac968f03f6..b4b2a6a634e 100644 --- a/run/django/e2e_test_setup.yaml +++ b/run/django/e2e_test_setup.yaml @@ -42,10 +42,9 @@ steps: args: - "-c" - | - ./retry.sh "gsutil mb \ - -l ${_REGION} \ - -p ${PROJECT_ID} \ - gs://${_STORAGE_BUCKET}" + ./retry.sh "gcloud storage buckets create gs://${_STORAGE_BUCKET} \ + --location ${_REGION} \ + --project ${PROJECT_ID}" - id: "IAM and Secrets" name: "gcr.io/google.com/cloudsdktool/cloud-sdk" @@ -148,4 +147,3 @@ substitutions: _DB_PASS: password1234 _ADMIN_PASSWORD: superpass _ADMIN_EMAIL: example@noop.com - diff --git a/run/logging-manual/README.md b/run/logging-manual/README.md index 378cf44efbe..ed8945290dc 100644 --- a/run/logging-manual/README.md +++ b/run/logging-manual/README.md @@ -1,6 +1,6 @@ # Cloud Run Manual Logging Sample -This sample shows how to send structured logs to Stackdriver Logging. +This sample shows how to send structured logs to Cloud Logging. [![Run in Google Cloud][run_img]][run_link] diff --git a/run/logging-manual/e2e_test.py b/run/logging-manual/e2e_test.py index a2eed020216..80aef7455e2 100644 --- a/run/logging-manual/e2e_test.py +++ b/run/logging-manual/e2e_test.py @@ -169,8 +169,8 @@ def test_end_to_end(service_url_auth_token, deployed_service): assert response.status_code == 200 assert "Hello Logger!" in response.content.decode("UTF-8") - # Test that the logs are writing properly to stackdriver - time.sleep(10) # Slight delay writing to stackdriver + # Test that the logs are writing properly to Cloud Logging + time.sleep(10) # Slight delay writing to Cloud Logging client = LoggingServiceV2Client() resource_names = [f"projects/{PROJECT}"] # We add timestamp for making the query faster. @@ -184,7 +184,7 @@ def test_end_to_end(service_url_auth_token, deployed_service): "AND jsonPayload.component=arbitrary-property" ) - # Retry a maximum number of 10 times to find results in stackdriver + # Retry a maximum number of 10 times to find results in Cloud Logging found = False for x in range(10): iterator = client.list_log_entries( diff --git a/run/logging-manual/requirements-test.txt b/run/logging-manual/requirements-test.txt index 86ed56c0141..cae36808290 100644 --- a/run/logging-manual/requirements-test.txt +++ b/run/logging-manual/requirements-test.txt @@ -1,2 +1,2 @@ pytest==8.2.0 -google-cloud-logging==3.11.4 +google-cloud-logging==3.15.0 diff --git a/run/mcp-server/README.md b/run/mcp-server/README.md index 19fe6971155..53d01ff9d8b 100644 --- a/run/mcp-server/README.md +++ b/run/mcp-server/README.md @@ -182,3 +182,32 @@ You should see the following output: You have successfully deployed a remote MCP server to Cloud Run and tested it using the FastMCP client. + +## Observability with OpenTelemetry + +This sample includes integration with OpenTelemetry to send traces, logs, and metrics to Google +Cloud Observability (Cloud Trace, Cloud Logging, and Cloud Monitoring). + +[FastMCP is natively instrumented for +OpenTelemetry](https://gofastmcp.com/servers/telemetry#opentelemetry), so simply setting up the +SDK is enough to get telemetry data. Learn more about OpenTelemetry instrumentation +[here](https://docs.cloud.google.com/stackdriver/docs/instrumentation/overview). + + +### Setup Observability + +1. **Ensure APIs are enabled**: + Make sure you have enabled the Telemetry (OTLP) API, Cloud Logging API, and Cloud Monitoring API in your Google Cloud project. + + ```bash + gcloud services enable logging.googleapis.com monitoring.googleapis.com telemetry.googleapis.com + ``` + +1. **Run the server**: + The sample is pre-configured to use OpenTelemetry. + + * **Locally**: Run `uv run server.py`. You can test it with the client: `uv run test_server.py`. + * **Cloud Run**: Deploy using the instructions in the [Deploy](#deploy) section. The default `Dockerfile` is already set up to run the instrumented server. + +1. **View Traces**: + After interacting with the server to generate traces, you can view them in the Google Cloud Console. For detailed instructions, see the [Google Cloud Trace documentation on finding traces](https://docs.cloud.google.com/trace/docs/finding-traces). diff --git a/run/mcp-server/otel_setup.py b/run/mcp-server/otel_setup.py new file mode 100644 index 00000000000..4d06f043991 --- /dev/null +++ b/run/mcp-server/otel_setup.py @@ -0,0 +1,67 @@ +# Copyright 2026 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. + +# [START cloudrun_mcpserver_setup_otel] +import logging +import google.auth +import google.auth.transport.requests +import grpc +from google.auth.transport.grpc import AuthMetadataPlugin +from opentelemetry import trace +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + OTLPSpanExporter, +) +from opentelemetry.sdk.resources import SERVICE_NAME, Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor + +logger = logging.getLogger(__name__) + + +def setup_opentelemetry(service_name: str) -> None: + """Sets up OpenTelemetry to send traces to Google Cloud Observability.""" + credentials, project_id = google.auth.default() + if not project_id: + raise Exception("Could not determine Google Cloud project ID.") + + resource = Resource.create( + attributes={ + SERVICE_NAME: service_name, + "gcp.project_id": project_id, + } + ) + + # Set up OTLP auth + request = google.auth.transport.requests.Request() + auth_metadata_plugin = AuthMetadataPlugin(credentials=credentials, request=request) + channel_creds = grpc.composite_channel_credentials( + grpc.ssl_channel_credentials(), + grpc.metadata_call_credentials(auth_metadata_plugin), + ) + + # Set up OpenTelemetry Python SDK + tracer_provider = TracerProvider(resource=resource) + tracer_provider.add_span_processor( + BatchSpanProcessor( + OTLPSpanExporter( + credentials=channel_creds, + endpoint="https://telemetry.googleapis.com:443/v1/traces", + ) + ) + ) + trace.set_tracer_provider(tracer_provider) + logger.info("OpenTelemetry successfully initialized.") + + +# [END cloudrun_mcpserver_setup_otel] diff --git a/run/mcp-server/pyproject.toml b/run/mcp-server/pyproject.toml index 8f46df9ef2c..d104884f089 100644 --- a/run/mcp-server/pyproject.toml +++ b/run/mcp-server/pyproject.toml @@ -6,4 +6,10 @@ readme = "README.md" requires-python = ">=3.10" dependencies = [ "fastmcp==3.2.0", + "opentelemetry-api==1.40.0", + "opentelemetry-sdk==1.40.0", + "opentelemetry-exporter-otlp-proto-grpc==1.40.0", + "google-auth==2.49.1", + "grpcio==1.80.0", ] + diff --git a/run/mcp-server/server.py b/run/mcp-server/server.py index 7068b2731ba..37f9ad68fc5 100644 --- a/run/mcp-server/server.py +++ b/run/mcp-server/server.py @@ -12,6 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# [START cloudrun_mcpserver_otel] +from otel_setup import setup_opentelemetry +setup_opentelemetry("mcp-server") + # [START cloudrun_mcpserver] import asyncio import logging @@ -64,3 +68,4 @@ def subtract(a: int, b: int) -> int: ) # [END cloudrun_mcpserver] +# [END cloudrun_mcpserver_otel] diff --git a/run/mcp-server/test_server.py b/run/mcp-server/test_server.py index ec7cfe2ab38..e566ffe5eec 100644 --- a/run/mcp-server/test_server.py +++ b/run/mcp-server/test_server.py @@ -12,11 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +# [START cloudrun_mcpserver_test_otel] +from otel_setup import setup_opentelemetry +setup_opentelemetry("test-server") + # [START cloudrun_mcpserver_test] import asyncio from fastmcp import Client + async def test_server(): # Test the MCP server using streamable-http transport. # Use "/sse" endpoint if using sse transport. @@ -28,12 +33,14 @@ async def test_server(): # Call add tool print(">>> 🪛 Calling add tool for 1 + 2") result = await client.call_tool("add", {"a": 1, "b": 2}) - print(f"<<< ✅ Result: {result[0].text}") + print(f"<<< ✅ Result: {result.content[0].text}") # Call subtract tool print(">>> 🪛 Calling subtract tool for 10 - 3") result = await client.call_tool("subtract", {"a": 10, "b": 3}) - print(f"<<< ✅ Result: {result[0].text}") + print(f"<<< ✅ Result: {result.content[0].text}") + if __name__ == "__main__": asyncio.run(test_server()) # [END cloudrun_mcpserver_test] +# [END cloudrun_mcpserver_test_otel] \ No newline at end of file diff --git a/run/mcp-server/uv.lock b/run/mcp-server/uv.lock index 184999d5857..4d787934105 100644 --- a/run/mcp-server/uv.lock +++ b/run/mcp-server/uv.lock @@ -1,6 +1,12 @@ version = 1 revision = 3 requires-python = ">=3.10" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version == '3.13.*'", + "python_full_version >= '3.11' and python_full_version < '3.13'", + "python_full_version < '3.11'", +] [[package]] name = "aiofile" @@ -439,6 +445,92 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/67/684fa2d2de1e7504549d4ca457b4f854ccec3cd3be03bd86b33b599fbf58/fastmcp-3.2.0-py3-none-any.whl", hash = "sha256:e71aba3df16f86f546a4a9e513261d3233bcc92bef0dfa647bac3fa33623f681", size = 705550, upload-time = "2026-03-30T20:25:35.499Z" }, ] +[[package]] +name = "google-auth" +version = "2.49.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "pyasn1-modules" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/80/6a696a07d3d3b0a92488933532f03dbefa4a24ab80fb231395b9a2a1be77/google_auth-2.49.1.tar.gz", hash = "sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64", size = 333825, upload-time = "2026-03-12T19:30:58.135Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/eb/c6c2478d8a8d633460be40e2a8a6f8f429171997a35a96f81d3b680dec83/google_auth-2.49.1-py3-none-any.whl", hash = "sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7", size = 240737, upload-time = "2026-03-12T19:30:53.159Z" }, +] + +[[package]] +name = "googleapis-common-protos" +version = "1.74.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/18/a746c8344152d368a5aac738d4c857012f2c5d1fd2eac7e17b647a7861bd/googleapis_common_protos-1.74.0.tar.gz", hash = "sha256:57971e4eeeba6aad1163c1f0fc88543f965bb49129b8bb55b2b7b26ecab084f1", size = 151254, upload-time = "2026-04-02T21:23:26.679Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/b0/be5d3329badb9230b765de6eea66b73abd5944bdeb5afb3562ddcd80ae84/googleapis_common_protos-1.74.0-py3-none-any.whl", hash = "sha256:702216f78610bb510e3f12ac3cafd281b7ac45cc5d86e90ad87e4d301a3426b5", size = 300743, upload-time = "2026-04-02T21:22:49.108Z" }, +] + +[[package]] +name = "grpcio" +version = "1.80.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/48/af6173dbca4454f4637a4678b67f52ca7e0c1ed7d5894d89d434fecede05/grpcio-1.80.0.tar.gz", hash = "sha256:29aca15edd0688c22ba01d7cc01cb000d72b2033f4a3c72a81a19b56fd143257", size = 12978905, upload-time = "2026-03-30T08:49:10.502Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/cd/bb7b7e54084a344c03d68144450da7ddd5564e51a298ae1662de65f48e2d/grpcio-1.80.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:886457a7768e408cdce226ad1ca67d2958917d306523a0e21e1a2fdaa75c9c9c", size = 6050363, upload-time = "2026-03-30T08:46:20.894Z" }, + { url = "https://files.pythonhosted.org/packages/16/02/1417f5c3460dea65f7a2e3c14e8b31e77f7ffb730e9bfadd89eda7a9f477/grpcio-1.80.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:7b641fc3f1dc647bfd80bd713addc68f6d145956f64677e56d9ebafc0bd72388", size = 12026037, upload-time = "2026-03-30T08:46:25.144Z" }, + { url = "https://files.pythonhosted.org/packages/43/98/c910254eedf2cae368d78336a2de0678e66a7317d27c02522392f949b5c6/grpcio-1.80.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:33eb763f18f006dc7fee1e69831d38d23f5eccd15b2e0f92a13ee1d9242e5e02", size = 6602306, upload-time = "2026-03-30T08:46:27.593Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f8/88ca4e78c077b2b2113d95da1e1ab43efd43d723c9a0397d26529c2c1a56/grpcio-1.80.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:52d143637e3872633fc7dd7c3c6a1c84e396b359f3a72e215f8bf69fd82084fc", size = 7301535, upload-time = "2026-03-30T08:46:29.556Z" }, + { url = "https://files.pythonhosted.org/packages/f9/96/f28660fe2fe0f153288bf4a04e4910b7309d442395135c88ed4f5b3b8b40/grpcio-1.80.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c51bf8ac4575af2e0678bccfb07e47321fc7acb5049b4482832c5c195e04e13a", size = 6808669, upload-time = "2026-03-30T08:46:31.984Z" }, + { url = "https://files.pythonhosted.org/packages/47/eb/3f68a5e955779c00aeef23850e019c1c1d0e032d90633ba49c01ad5a96e0/grpcio-1.80.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:50a9871536d71c4fba24ee856abc03a87764570f0c457dd8db0b4018f379fed9", size = 7409489, upload-time = "2026-03-30T08:46:34.684Z" }, + { url = "https://files.pythonhosted.org/packages/5b/a7/d2f681a4bfb881be40659a309771f3bdfbfdb1190619442816c3f0ffc079/grpcio-1.80.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a72d84ad0514db063e21887fbacd1fd7acb4d494a564cae22227cd45c7fbf199", size = 8423167, upload-time = "2026-03-30T08:46:36.833Z" }, + { url = "https://files.pythonhosted.org/packages/97/8a/29b4589c204959aa35ce5708400a05bba72181807c45c47b3ec000c39333/grpcio-1.80.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f7691a6788ad9196872f95716df5bc643ebba13c97140b7a5ee5c8e75d1dea81", size = 7846761, upload-time = "2026-03-30T08:46:40.091Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d2/ed143e097230ee121ac5848f6ff14372dba91289b10b536d54fb1b7cbae7/grpcio-1.80.0-cp310-cp310-win32.whl", hash = "sha256:46c2390b59d67f84e882694d489f5b45707c657832d7934859ceb8c33f467069", size = 4156534, upload-time = "2026-03-30T08:46:42.026Z" }, + { url = "https://files.pythonhosted.org/packages/d5/c9/df8279bb49b29409995e95efa85b72973d62f8aeff89abee58c91f393710/grpcio-1.80.0-cp310-cp310-win_amd64.whl", hash = "sha256:dc053420fc75749c961e2a4c906398d7c15725d36ccc04ae6d16093167223b58", size = 4889869, upload-time = "2026-03-30T08:46:44.219Z" }, + { url = "https://files.pythonhosted.org/packages/5d/db/1d56e5f5823257b291962d6c0ce106146c6447f405b60b234c4f222a7cde/grpcio-1.80.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:dfab85db094068ff42e2a3563f60ab3dddcc9d6488a35abf0132daec13209c8a", size = 6055009, upload-time = "2026-03-30T08:46:46.265Z" }, + { url = "https://files.pythonhosted.org/packages/6e/18/c83f3cad64c5ca63bca7e91e5e46b0d026afc5af9d0a9972472ceba294b3/grpcio-1.80.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5c07e82e822e1161354e32da2662f741a4944ea955f9f580ec8fb409dd6f6060", size = 12035295, upload-time = "2026-03-30T08:46:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/0f/8e/e14966b435be2dda99fbe89db9525ea436edc79780431a1c2875a3582644/grpcio-1.80.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba0915d51fd4ced2db5ff719f84e270afe0e2d4c45a7bdb1e8d036e4502928c2", size = 6610297, upload-time = "2026-03-30T08:46:52.123Z" }, + { url = "https://files.pythonhosted.org/packages/cc/26/d5eb38f42ce0e3fdc8174ea4d52036ef8d58cc4426cb800f2610f625dd75/grpcio-1.80.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:3cb8130ba457d2aa09fa6b7c3ed6b6e4e6a2685fce63cb803d479576c4d80e21", size = 7300208, upload-time = "2026-03-30T08:46:54.859Z" }, + { url = "https://files.pythonhosted.org/packages/25/51/bd267c989f85a17a5b3eea65a6feb4ff672af41ca614e5a0279cc0ea381c/grpcio-1.80.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:09e5e478b3d14afd23f12e49e8b44c8684ac3c5f08561c43a5b9691c54d136ab", size = 6813442, upload-time = "2026-03-30T08:46:57.056Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d9/d80eef735b19e9169e30164bbf889b46f9df9127598a83d174eb13a48b26/grpcio-1.80.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:00168469238b022500e486c1c33916acf2f2a9b2c022202cf8a1885d2e3073c1", size = 7414743, upload-time = "2026-03-30T08:46:59.682Z" }, + { url = "https://files.pythonhosted.org/packages/de/f2/567f5bd5054398ed6b0509b9a30900376dcf2786bd936812098808b49d8d/grpcio-1.80.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8502122a3cc1714038e39a0b071acb1207ca7844208d5ea0d091317555ee7106", size = 8426046, upload-time = "2026-03-30T08:47:02.474Z" }, + { url = "https://files.pythonhosted.org/packages/62/29/73ef0141b4732ff5eacd68430ff2512a65c004696997f70476a83e548e7e/grpcio-1.80.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ce1794f4ea6cc3ca29463f42d665c32ba1b964b48958a66497917fe9069f26e6", size = 7851641, upload-time = "2026-03-30T08:47:05.462Z" }, + { url = "https://files.pythonhosted.org/packages/46/69/abbfa360eb229a8623bab5f5a4f8105e445bd38ce81a89514ba55d281ad0/grpcio-1.80.0-cp311-cp311-win32.whl", hash = "sha256:51b4a7189b0bef2aa30adce3c78f09c83526cf3dddb24c6a96555e3b97340440", size = 4154368, upload-time = "2026-03-30T08:47:08.027Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d4/ae92206d01183b08613e846076115f5ac5991bae358d2a749fa864da5699/grpcio-1.80.0-cp311-cp311-win_amd64.whl", hash = "sha256:02e64bb0bb2da14d947a49e6f120a75e947250aebe65f9629b62bb1f5c14e6e9", size = 4894235, upload-time = "2026-03-30T08:47:10.839Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e8/a2b749265eb3415abc94f2e619bbd9e9707bebdda787e61c593004ec927a/grpcio-1.80.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:c624cc9f1008361014378c9d776de7182b11fe8b2e5a81bc69f23a295f2a1ad0", size = 6015616, upload-time = "2026-03-30T08:47:13.428Z" }, + { url = "https://files.pythonhosted.org/packages/3e/97/b1282161a15d699d1e90c360df18d19165a045ce1c343c7f313f5e8a0b77/grpcio-1.80.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:f49eddcac43c3bf350c0385366a58f36bed8cc2c0ec35ef7b74b49e56552c0c2", size = 12014204, upload-time = "2026-03-30T08:47:15.873Z" }, + { url = "https://files.pythonhosted.org/packages/6e/5e/d319c6e997b50c155ac5a8cb12f5173d5b42677510e886d250d50264949d/grpcio-1.80.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d334591df610ab94714048e0d5b4f3dd5ad1bee74dfec11eee344220077a79de", size = 6563866, upload-time = "2026-03-30T08:47:18.588Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f6/fdd975a2cb4d78eb67769a7b3b3830970bfa2e919f1decf724ae4445f42c/grpcio-1.80.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0cb517eb1d0d0aaf1d87af7cc5b801d686557c1d88b2619f5e31fab3c2315921", size = 7273060, upload-time = "2026-03-30T08:47:21.113Z" }, + { url = "https://files.pythonhosted.org/packages/db/f0/a3deb5feba60d9538a962913e37bd2e69a195f1c3376a3dd44fe0427e996/grpcio-1.80.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4e78c4ac0d97dc2e569b2f4bcbbb447491167cb358d1a389fc4af71ab6f70411", size = 6782121, upload-time = "2026-03-30T08:47:23.827Z" }, + { url = "https://files.pythonhosted.org/packages/ca/84/36c6dcfddc093e108141f757c407902a05085e0c328007cb090d56646cdf/grpcio-1.80.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2ed770b4c06984f3b47eb0517b1c69ad0b84ef3f40128f51448433be904634cd", size = 7383811, upload-time = "2026-03-30T08:47:26.517Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ef/f3a77e3dc5b471a0ec86c564c98d6adfa3510d38f8ee99010410858d591e/grpcio-1.80.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:256507e2f524092f1473071a05e65a5b10d84b82e3ff24c5b571513cfaa61e2f", size = 8393860, upload-time = "2026-03-30T08:47:29.439Z" }, + { url = "https://files.pythonhosted.org/packages/9b/8d/9d4d27ed7f33d109c50d6b5ce578a9914aa68edab75d65869a17e630a8d1/grpcio-1.80.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a6284a5d907c37db53350645567c522be314bac859a64a7a5ca63b77bb7958f", size = 7830132, upload-time = "2026-03-30T08:47:33.254Z" }, + { url = "https://files.pythonhosted.org/packages/14/e4/9990b41c6d7a44e1e9dee8ac11d7a9802ba1378b40d77468a7761d1ad288/grpcio-1.80.0-cp312-cp312-win32.whl", hash = "sha256:c71309cfce2f22be26aa4a847357c502db6c621f1a49825ae98aa0907595b193", size = 4140904, upload-time = "2026-03-30T08:47:35.319Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2c/296f6138caca1f4b92a31ace4ae1b87dab692fc16a7a3417af3bb3c805bf/grpcio-1.80.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe648599c0e37594c4809d81a9e77bd138cc82eb8baa71b6a86af65426723ff", size = 4880944, upload-time = "2026-03-30T08:47:37.831Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/7c3c25789e3f069e581dc342e03613c5b1cb012c4e8c7d9d5cf960a75856/grpcio-1.80.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:e9e408fc016dffd20661f0126c53d8a31c2821b5c13c5d67a0f5ed5de93319ad", size = 6017243, upload-time = "2026-03-30T08:47:40.075Z" }, + { url = "https://files.pythonhosted.org/packages/04/19/21a9806eb8240e174fd1ab0cd5b9aa948bb0e05c2f2f55f9d5d7405e6d08/grpcio-1.80.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:92d787312e613754d4d8b9ca6d3297e69994a7912a32fa38c4c4e01c272974b0", size = 12010840, upload-time = "2026-03-30T08:47:43.11Z" }, + { url = "https://files.pythonhosted.org/packages/18/3a/23347d35f76f639e807fb7a36fad3068aed100996849a33809591f26eca6/grpcio-1.80.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8ac393b58aa16991a2f1144ec578084d544038c12242da3a215966b512904d0f", size = 6567644, upload-time = "2026-03-30T08:47:46.806Z" }, + { url = "https://files.pythonhosted.org/packages/ff/40/96e07ecb604a6a67ae6ab151e3e35b132875d98bc68ec65f3e5ab3e781d7/grpcio-1.80.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:68e5851ac4b9afe07e7f84483803ad167852570d65326b34d54ca560bfa53fb6", size = 7277830, upload-time = "2026-03-30T08:47:49.643Z" }, + { url = "https://files.pythonhosted.org/packages/9b/e2/da1506ecea1f34a5e365964644b35edef53803052b763ca214ba3870c856/grpcio-1.80.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:873ff5d17d68992ef6605330127425d2fc4e77e612fa3c3e0ed4e668685e3140", size = 6783216, upload-time = "2026-03-30T08:47:52.817Z" }, + { url = "https://files.pythonhosted.org/packages/44/83/3b20ff58d0c3b7f6caaa3af9a4174d4023701df40a3f39f7f1c8e7c48f9d/grpcio-1.80.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2bea16af2750fd0a899bf1abd9022244418b55d1f37da2202249ba4ba673838d", size = 7385866, upload-time = "2026-03-30T08:47:55.687Z" }, + { url = "https://files.pythonhosted.org/packages/47/45/55c507599c5520416de5eefecc927d6a0d7af55e91cfffb2e410607e5744/grpcio-1.80.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba0db34f7e1d803a878284cd70e4c63cb6ae2510ba51937bf8f45ba997cefcf7", size = 8391602, upload-time = "2026-03-30T08:47:58.303Z" }, + { url = "https://files.pythonhosted.org/packages/10/bb/dd06f4c24c01db9cf11341b547d0a016b2c90ed7dbbb086a5710df7dd1d7/grpcio-1.80.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8eb613f02d34721f1acf3626dfdb3545bd3c8505b0e52bf8b5710a28d02e8aa7", size = 7826752, upload-time = "2026-03-30T08:48:01.311Z" }, + { url = "https://files.pythonhosted.org/packages/f9/1e/9d67992ba23371fd63d4527096eb8c6b76d74d52b500df992a3343fd7251/grpcio-1.80.0-cp313-cp313-win32.whl", hash = "sha256:93b6f823810720912fd131f561f91f5fed0fda372b6b7028a2681b8194d5d294", size = 4142310, upload-time = "2026-03-30T08:48:04.594Z" }, + { url = "https://files.pythonhosted.org/packages/cf/e6/283326a27da9e2c3038bc93eeea36fb118ce0b2d03922a9cda6688f53c5b/grpcio-1.80.0-cp313-cp313-win_amd64.whl", hash = "sha256:e172cf795a3ba5246d3529e4d34c53db70e888fa582a8ffebd2e6e48bc0cba50", size = 4882833, upload-time = "2026-03-30T08:48:07.363Z" }, + { url = "https://files.pythonhosted.org/packages/c5/6d/e65307ce20f5a09244ba9e9d8476e99fb039de7154f37fb85f26978b59c3/grpcio-1.80.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:3d4147a97c8344d065d01bbf8b6acec2cf86fb0400d40696c8bdad34a64ffc0e", size = 6017376, upload-time = "2026-03-30T08:48:10.005Z" }, + { url = "https://files.pythonhosted.org/packages/69/10/9cef5d9650c72625a699c549940f0abb3c4bfdb5ed45a5ce431f92f31806/grpcio-1.80.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d8e11f167935b3eb089ac9038e1a063e6d7dbe995c0bb4a661e614583352e76f", size = 12018133, upload-time = "2026-03-30T08:48:12.927Z" }, + { url = "https://files.pythonhosted.org/packages/04/82/983aabaad82ba26113caceeb9091706a0696b25da004fe3defb5b346e15b/grpcio-1.80.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f14b618fc30de822681ee986cfdcc2d9327229dc4c98aed16896761cacd468b9", size = 6574748, upload-time = "2026-03-30T08:48:16.386Z" }, + { url = "https://files.pythonhosted.org/packages/07/d7/031666ef155aa0bf399ed7e19439656c38bbd143779ae0861b038ce82abd/grpcio-1.80.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4ed39fbdcf9b87370f6e8df4e39ca7b38b3e5e9d1b0013c7b6be9639d6578d14", size = 7277711, upload-time = "2026-03-30T08:48:19.627Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/f437a78f7f4f1d311804189e8f11fb311a01049b2e08557c1068d470cb2e/grpcio-1.80.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2dcc70e9f0ba987526e8e8603a610fb4f460e42899e74e7a518bf3c68fe1bf05", size = 6785372, upload-time = "2026-03-30T08:48:22.373Z" }, + { url = "https://files.pythonhosted.org/packages/93/3d/f6558e9c6296cb4227faa5c43c54a34c68d32654b829f53288313d16a86e/grpcio-1.80.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:448c884b668b868562b1bda833c5fce6272d26e1926ec46747cda05741d302c1", size = 7395268, upload-time = "2026-03-30T08:48:25.638Z" }, + { url = "https://files.pythonhosted.org/packages/06/21/0fdd77e84720b08843c371a2efa6f2e19dbebf56adc72df73d891f5506f0/grpcio-1.80.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a1dc80fe55685b4a543555e6eef975303b36c8db1023b1599b094b92aa77965f", size = 8392000, upload-time = "2026-03-30T08:48:28.974Z" }, + { url = "https://files.pythonhosted.org/packages/f5/68/67f4947ed55d2e69f2cc199ab9fd85e0a0034d813bbeef84df6d2ba4d4b7/grpcio-1.80.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:31b9ac4ad1aa28ffee5503821fafd09e4da0a261ce1c1281c6c8da0423c83b6e", size = 7828477, upload-time = "2026-03-30T08:48:32.054Z" }, + { url = "https://files.pythonhosted.org/packages/44/b6/8d4096691b2e385e8271911a0de4f35f0a6c7d05aff7098e296c3de86939/grpcio-1.80.0-cp314-cp314-win32.whl", hash = "sha256:367ce30ba67d05e0592470428f0ec1c31714cab9ef19b8f2e37be1f4c7d32fae", size = 4218563, upload-time = "2026-03-30T08:48:34.538Z" }, + { url = "https://files.pythonhosted.org/packages/e5/8c/bbe6baf2557262834f2070cf668515fa308b2d38a4bbf771f8f7872a7036/grpcio-1.80.0-cp314-cp314-win_amd64.whl", hash = "sha256:3b01e1f5464c583d2f567b2e46ff0d516ef979978f72091fd81f5ab7fa6e2e7f", size = 5019457, upload-time = "2026-03-30T08:48:37.308Z" }, +] + [[package]] name = "h11" version = "0.16.0" @@ -663,10 +755,22 @@ version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "fastmcp" }, + { name = "google-auth" }, + { name = "grpcio" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-grpc" }, + { name = "opentelemetry-sdk" }, ] [package.metadata] -requires-dist = [{ name = "fastmcp", specifier = "==3.2.0" }] +requires-dist = [ + { name = "fastmcp", specifier = "==3.2.0" }, + { name = "google-auth", specifier = "==2.49.1" }, + { name = "grpcio", specifier = "==1.80.0" }, + { name = "opentelemetry-api", specifier = "==1.40.0" }, + { name = "opentelemetry-exporter-otlp-proto-grpc", specifier = "==1.40.0" }, + { name = "opentelemetry-sdk", specifier = "==1.40.0" }, +] [[package]] name = "mdurl" @@ -700,15 +804,84 @@ wheels = [ [[package]] name = "opentelemetry-api" -version = "1.39.1" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-metadata" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/b9/3161be15bb8e3ad01be8be5a968a9237c3027c5be504362ff800fca3e442/opentelemetry_api-1.39.1.tar.gz", hash = "sha256:fbde8c80e1b937a2c61f20347e91c0c18a1940cecf012d62e65a7caf08967c9c", size = 65767, upload-time = "2025-12-11T13:32:39.182Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/1d/4049a9e8698361cc1a1aa03a6c59e4fa4c71e0c0f94a30f988a6876a2ae6/opentelemetry_api-1.40.0.tar.gz", hash = "sha256:159be641c0b04d11e9ecd576906462773eb97ae1b657730f0ecf64d32071569f", size = 70851, upload-time = "2026-03-04T14:17:21.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/bf/93795954016c522008da367da292adceed71cca6ee1717e1d64c83089099/opentelemetry_api-1.40.0-py3-none-any.whl", hash = "sha256:82dd69331ae74b06f6a874704be0cfaa49a1650e1537d4a813b86ecef7d0ecf9", size = 68676, upload-time = "2026-03-04T14:17:01.24Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-proto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/51/bc/1559d46557fe6eca0b46c88d4c2676285f1f3be2e8d06bb5d15fbffc814a/opentelemetry_exporter_otlp_proto_common-1.40.0.tar.gz", hash = "sha256:1cbee86a4064790b362a86601ee7934f368b81cd4cc2f2e163902a6e7818a0fa", size = 20416, upload-time = "2026-03-04T14:17:23.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/ca/8f122055c97a932311a3f640273f084e738008933503d0c2563cd5d591fc/opentelemetry_exporter_otlp_proto_common-1.40.0-py3-none-any.whl", hash = "sha256:7081ff453835a82417bf38dccf122c827c3cbc94f2079b03bba02a3165f25149", size = 18369, upload-time = "2026-03-04T14:17:04.796Z" }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-grpc" +version = "1.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/7f/b9e60435cfcc7590fa87436edad6822240dddbc184643a2a005301cc31f4/opentelemetry_exporter_otlp_proto_grpc-1.40.0.tar.gz", hash = "sha256:bd4015183e40b635b3dab8da528b27161ba83bf4ef545776b196f0fb4ec47740", size = 25759, upload-time = "2026-03-04T14:17:24.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/6f/7ee0980afcbdcd2d40362da16f7f9796bd083bf7f0b8e038abfbc0300f5d/opentelemetry_exporter_otlp_proto_grpc-1.40.0-py3-none-any.whl", hash = "sha256:2aa0ca53483fe0cf6405087a7491472b70335bc5c7944378a0a8e72e86995c52", size = 20304, upload-time = "2026-03-04T14:17:05.942Z" }, +] + +[[package]] +name = "opentelemetry-proto" +version = "1.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/77/dd38991db037fdfce45849491cb61de5ab000f49824a00230afb112a4392/opentelemetry_proto-1.40.0.tar.gz", hash = "sha256:03f639ca129ba513f5819810f5b1f42bcb371391405d99c168fe6937c62febcd", size = 45667, upload-time = "2026-03-04T14:17:31.194Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/b2/189b2577dde745b15625b3214302605b1353436219d42b7912e77fa8dc24/opentelemetry_proto-1.40.0-py3-none-any.whl", hash = "sha256:266c4385d88923a23d63e353e9761af0f47a6ed0d486979777fe4de59dc9b25f", size = 72073, upload-time = "2026-03-04T14:17:16.673Z" }, +] + +[[package]] +name = "opentelemetry-sdk" +version = "1.40.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/fd/3c3125b20ba18ce2155ba9ea74acb0ae5d25f8cd39cfd37455601b7955cc/opentelemetry_sdk-1.40.0.tar.gz", hash = "sha256:18e9f5ec20d859d268c7cb3c5198c8d105d073714db3de50b593b8c1345a48f2", size = 184252, upload-time = "2026-03-04T14:17:31.87Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/df/d3f1ddf4bb4cb50ed9b1139cc7b1c54c34a1e7ce8fd1b9a37c0d1551a6bd/opentelemetry_api-1.39.1-py3-none-any.whl", hash = "sha256:2edd8463432a7f8443edce90972169b195e7d6a05500cd29e6d13898187c9950", size = 66356, upload-time = "2025-12-11T13:32:17.304Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c5/6a852903d8bfac758c6dc6e9a68b015d3c33f2f1be5e9591e0f4b69c7e0a/opentelemetry_sdk-1.40.0-py3-none-any.whl", hash = "sha256:787d2154a71f4b3d81f20524a8ce061b7db667d24e46753f32a7bc48f1c1f3f1", size = 141951, upload-time = "2026-03-04T14:17:17.961Z" }, +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.61b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/c0/4ae7973f3c2cfd2b6e321f1675626f0dab0a97027cc7a297474c9c8f3d04/opentelemetry_semantic_conventions-0.61b0.tar.gz", hash = "sha256:072f65473c5d7c6dc0355b27d6c9d1a679d63b6d4b4b16a9773062cb7e31192a", size = 145755, upload-time = "2026-03-04T14:17:32.664Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/37/cc6a55e448deaa9b27377d087da8615a3416d8ad523d5960b78dbeadd02a/opentelemetry_semantic_conventions-0.61b0-py3-none-any.whl", hash = "sha256:fa530a96be229795f8cef353739b618148b0fe2b4b3f005e60e262926c4d38e2", size = 231621, upload-time = "2026-03-04T14:17:19.33Z" }, ] [[package]] @@ -738,6 +911,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", size = 18651, upload-time = "2025-10-08T17:44:47.223Z" }, ] +[[package]] +name = "protobuf" +version = "6.33.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" }, + { url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" }, + { url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" }, + { url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" }, + { url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" }, +] + [[package]] name = "py-key-value-aio" version = "0.4.4" @@ -763,6 +951,27 @@ memory = [ { name = "cachetools" }, ] +[[package]] +name = "pyasn1" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/5f/6583902b6f79b399c9c40674ac384fd9cd77805f9e6205075f828ef11fb2/pyasn1-0.6.3.tar.gz", hash = "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf", size = 148685, upload-time = "2026-03-17T01:06:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl", hash = "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde", size = 83997, upload-time = "2026-03-17T01:06:52.036Z" }, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, +] + [[package]] name = "pycparser" version = "2.22" @@ -954,11 +1163,11 @@ wheels = [ [[package]] name = "python-dotenv" -version = "1.1.0" +version = "1.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, ] [[package]] @@ -1279,14 +1488,15 @@ wheels = [ [[package]] name = "starlette" -version = "0.47.0" +version = "0.49.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/d0/0332bd8a25779a0e2082b0e179805ad39afad642938b371ae0882e7f880d/starlette-0.47.0.tar.gz", hash = "sha256:1f64887e94a447fed5f23309fb6890ef23349b7e478faa7b24a851cd4eb844af", size = 2582856, upload-time = "2025-05-29T15:45:27.628Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/3f/507c21db33b66fb027a332f2cb3abbbe924cc3a79ced12f01ed8645955c9/starlette-0.49.1.tar.gz", hash = "sha256:481a43b71e24ed8c43b11ea02f5353d77840e01480881b8cb5a26b8cae64a8cb", size = 2654703, upload-time = "2025-10-28T17:34:10.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/81/c60b35fe9674f63b38a8feafc414fca0da378a9dbd5fa1e0b8d23fcc7a9b/starlette-0.47.0-py3-none-any.whl", hash = "sha256:9d052d4933683af40ffd47c7465433570b4949dc937e20ad1d73b34e72f10c37", size = 72796, upload-time = "2025-05-29T15:45:26.305Z" }, + { url = "https://files.pythonhosted.org/packages/51/da/545b75d420bb23b5d494b0517757b351963e974e79933f01e05c929f20a6/starlette-0.49.1-py3-none-any.whl", hash = "sha256:d92ce9f07e4a3caa3ac13a79523bd18e3bc0042bb8ff2d759a8e7dd0e1859875", size = 74175, upload-time = "2025-10-28T17:34:09.13Z" }, ] [[package]] diff --git a/run/pubsub/e2e_test.py b/run/pubsub/e2e_test.py index 917657cd5da..3bb78a73566 100644 --- a/run/pubsub/e2e_test.py +++ b/run/pubsub/e2e_test.py @@ -233,7 +233,7 @@ def test_end_to_end(pubsub_topic): future.result() # Check the logs for "Hello Runner" - time.sleep(20) # Slight delay writing to stackdriver + time.sleep(20) # Slight delay writing to Cloud Logging client = LoggingServiceV2Client() resource_names = [f"projects/{PROJECT}"] @@ -246,7 +246,7 @@ def test_end_to_end(pubsub_topic): f"AND resource.labels.service_name={CLOUD_RUN_SERVICE} " ) - # Retry a maximum number of 10 times to find results in stackdriver + # Retry a maximum number of 10 times to find results in Cloud Logging found = False for x in range(10): iterator = client.list_log_entries( diff --git a/run/pubsub/requirements-test.txt b/run/pubsub/requirements-test.txt index 53e3abc66ec..305f4f14156 100644 --- a/run/pubsub/requirements-test.txt +++ b/run/pubsub/requirements-test.txt @@ -1,4 +1,4 @@ backoff==2.2.1 pytest==8.2.0 -google-cloud-logging==3.11.4 -google-cloud-pubsub==2.28.0 +google-cloud-logging==3.15.0 +google-cloud-pubsub==2.36.0 diff --git a/secretmanager/snippets-adk/README.md b/secretmanager/snippets-adk/README.md new file mode 100644 index 00000000000..73e1c7faf03 --- /dev/null +++ b/secretmanager/snippets-adk/README.md @@ -0,0 +1,99 @@ +# ADK Secret Manager Samples + +This directory contains samples demonstrating how to use the Agent Development Kit (ADK) with Google Cloud Secret Manager. + +## Folders +* `agent_global`: Sample for accessing secrets from a global Secret Manager instance. +* `agent_regional`: Sample for accessing secrets from a regional Secret Manager endpoint. + +## Prerequisites + +1. **Create and activate a virtual environment**: + ```bash + python3 -m venv .venv + source .venv/bin/activate + ``` + +2. **Set up Application Default Credentials**: + ```bash + gcloud auth application-default login + ``` + +3. **Install dependencies**: + You need to install dependencies for the specific sample or test you want to run. + + For global agent samples and tests: + ```bash + pip install -r agent_global/requirements.txt + ``` + + For regional agent samples and tests: + ```bash + pip install -r agent_regional/requirements.txt + ``` + +4. **Set up environment variables**: + * `GOOGLE_CLOUD_PROJECT`: Your Google Cloud Project ID. (Required for both samples and tests). + + The following environment variables are **only required when running the samples manually**. The tests will generate and use their own temporary secrets automatically. + + * `ADK_TEST_SECRET_ID`: The ID of the secret to access. + * `ADK_TEST_SECRET_VERSION` (Optional): The version of the secret (defaults to `latest`). + * `GOOGLE_CLOUD_PROJECT_LOCATION` (Required for regional samples): The region where the secret is located (e.g., `us-central1`). + +## Running the Samples + +The samples are designed to be run from this directory (`snippets-adk`) using the `adk run` command. + +### Global Secret Manager Agent + +1. **Create a `.env` file** alongside `agent_global.py` in the `agent_global` directory: + ```env + GOOGLE_GENAI_USE_VERTEXAI=1 + GOOGLE_CLOUD_PROJECT=your-project-id + GOOGLE_CLOUD_LOCATION=your-region + ``` + *Note: Replace `your-project-id` with your GCP project ID and `your-region` with your desired region.* + +2. **Run the agent**: + ```bash + export GOOGLE_CLOUD_PROJECT="your-project-id" + export ADK_TEST_SECRET_ID="your-secret-id" + adk run agent_global + ``` + +### Regional Secret Manager Agent + +1. **Create a `.env` file** alongside `agent_regional.py` in the `agent_regional` directory: + ```env + GOOGLE_GENAI_USE_VERTEXAI=1 + GOOGLE_CLOUD_PROJECT=your-project-id + GOOGLE_CLOUD_LOCATION=your-region + ``` + *Note: Replace `your-project-id` with your GCP project ID and `your-region` with your desired region.* + +2. **Run the agent**: + ```bash + export GOOGLE_CLOUD_PROJECT="your-project-id" + export GOOGLE_CLOUD_PROJECT_LOCATION="your-region" + export ADK_TEST_SECRET_ID="your-secret-id" + adk run agent_regional + ``` + +## Running the Tests + +The tests are located within the specific agent folders and run the samples using `adk run`. + +To run tests for the global agent: +```bash +pip install -r agent_global/requirements.txt +pip install -r agent_global/requirements-test.txt +pytest agent_global/snippets_adk_test.py +``` + +To run tests for the regional agent: +```bash +pip install -r agent_regional/requirements.txt +pip install -r agent_regional/requirements-test.txt +pytest agent_regional/snippets_adk_test.py +``` diff --git a/secretmanager/snippets-adk/agent_global/agent.py b/secretmanager/snippets-adk/agent_global/agent.py new file mode 100644 index 00000000000..af5dea9d531 --- /dev/null +++ b/secretmanager/snippets-adk/agent_global/agent.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# Copyright 2026 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 +""" +ADK agent for accessing secrets from global Secret Manager. +""" + +import os + +from google.adk import Agent +from google.adk.integrations.secret_manager.secret_client import SecretManagerClient + +# Fetch secret from global Secret Manager +project_id = os.environ.get("GOOGLE_CLOUD_PROJECT") +secret_id = os.environ.get("ADK_TEST_SECRET_ID") +secret_version = os.environ.get("ADK_TEST_SECRET_VERSION", "latest") + +if not project_id or not secret_id: + raise ValueError("GOOGLE_CLOUD_PROJECT and ADK_TEST_SECRET_ID environment variables must be set.") + +resource_name = f"projects/{project_id}/secrets/{secret_id}/versions/{secret_version}" + +print("Fetching secret from global Secret Manager...") +# Initialize Secret Manager Client (Global) +client = SecretManagerClient() + +# Fetch secret +try: + secret_payload = client.get_secret(resource_name) + print("Successfully fetched secret.") + # The secret_payload can now be used by the agent or its tools as required. +except Exception as e: + print(f"Error fetching secret: {e}") + raise e + +# Initialize Agent +root_agent = Agent( + model='gemini-2.5-flash', + name='root_agent', + description='A helpful assistant for user questions.', + instruction='Answer user questions to the best of your knowledge', +) + +print("Agent initialized successfully.") diff --git a/secretmanager/snippets-adk/agent_global/noxfile_config.py b/secretmanager/snippets-adk/agent_global/noxfile_config.py new file mode 100644 index 00000000000..873ef83d52a --- /dev/null +++ b/secretmanager/snippets-adk/agent_global/noxfile_config.py @@ -0,0 +1,38 @@ +# Copyright 2020 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": True, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # "gcloud_project_env": "BUILD_SPECIFIC_GCLOUD_PROJECT", + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} diff --git a/secretmanager/snippets-adk/agent_global/requirements-test.txt b/secretmanager/snippets-adk/agent_global/requirements-test.txt new file mode 100644 index 00000000000..b3b2b3ca4cc --- /dev/null +++ b/secretmanager/snippets-adk/agent_global/requirements-test.txt @@ -0,0 +1 @@ +pytest==9.0.3 diff --git a/secretmanager/snippets-adk/agent_global/requirements.txt b/secretmanager/snippets-adk/agent_global/requirements.txt new file mode 100644 index 00000000000..a4f5a5371c3 --- /dev/null +++ b/secretmanager/snippets-adk/agent_global/requirements.txt @@ -0,0 +1 @@ +google-adk>=1.29 diff --git a/secretmanager/snippets-adk/agent_global/snippets_adk_test.py b/secretmanager/snippets-adk/agent_global/snippets_adk_test.py new file mode 100644 index 00000000000..3d2501cf405 --- /dev/null +++ b/secretmanager/snippets-adk/agent_global/snippets_adk_test.py @@ -0,0 +1,102 @@ +# Copyright 2026 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 + +import os +import subprocess +import time +from typing import Iterator +import uuid + +from google.api_core import exceptions +from google.cloud import secretmanager +import pytest + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PARENT_DIR = os.path.dirname(CURRENT_DIR) + + +@pytest.fixture() +def client() -> secretmanager.SecretManagerServiceClient: + return secretmanager.SecretManagerServiceClient() + + +@pytest.fixture() +def project_id() -> str: + return os.environ["GOOGLE_CLOUD_PROJECT"] + + +@pytest.fixture() +def secret_id( + client: secretmanager.SecretManagerServiceClient, project_id: str +) -> Iterator[str]: + secret_id = f"python-adk-test-{uuid.uuid4()}" + yield secret_id + + # Teardown: delete the secret + secret_path = client.secret_path(project_id, secret_id) + print(f"Deleting secret {secret_id}...") + try: + # Wait a bit to avoid conflicts if operations are still pending + time.sleep(2) + client.delete_secret(request={"name": secret_path}) + except exceptions.NotFound: + pass + + +def test_agent_global( + client: secretmanager.SecretManagerServiceClient, project_id: str, secret_id: str +) -> None: + # Create the secret + parent = f"projects/{project_id}" + print(f"Creating secret {secret_id}...") + client.create_secret( + request={ + "parent": parent, + "secret_id": secret_id, + "secret": {"replication": {"automatic": {}}}, + } + ) + + # Add a version + secret_path = client.secret_path(project_id, secret_id) + print(f"Adding version to {secret_id}...") + client.add_secret_version( + request={ + "parent": secret_path, + "payload": {"data": b"test-payload"}, + } + ) + + # Set environment variables required by the agent + # GOOGLE_CLOUD_PROJECT is already set in the environment (required to run this test) + os.environ["ADK_TEST_SECRET_ID"] = secret_id + os.environ["ADK_TEST_SECRET_VERSION"] = "latest" + + print(f"Running adk run agent_global from {PARENT_DIR}...") + # Run the sample using adk run + result = subprocess.run( + ["adk", "run", "agent_global"], + input="exit\n", + capture_output=True, + text=True, + cwd=PARENT_DIR, + ) + + print("STDOUT:") + print(result.stdout) + print("STDERR:") + print(result.stderr) + + assert result.returncode == 0 + assert "Successfully fetched secret" in result.stdout + assert "Agent initialized successfully" in result.stdout diff --git a/secretmanager/snippets-adk/agent_regional/agent.py b/secretmanager/snippets-adk/agent_regional/agent.py new file mode 100644 index 00000000000..b5c6edfc1ee --- /dev/null +++ b/secretmanager/snippets-adk/agent_regional/agent.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +# Copyright 2026 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 +""" +ADK agent for accessing secrets from regional Secret Manager. +""" + +import os + +from google.adk import Agent +from google.adk.integrations.secret_manager.secret_client import SecretManagerClient + +# Fetch secret from regional Secret Manager +project_id = os.environ.get("GOOGLE_CLOUD_PROJECT") +location = os.environ.get("GOOGLE_CLOUD_PROJECT_LOCATION") +secret_id = os.environ.get("ADK_TEST_SECRET_ID") +secret_version = os.environ.get("ADK_TEST_SECRET_VERSION", "latest") + +if not project_id or not location or not secret_id: + raise ValueError("GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_PROJECT_LOCATION, and ADK_TEST_SECRET_ID environment variables must be set.") + +resource_name = f"projects/{project_id}/locations/{location}/secrets/{secret_id}/versions/{secret_version}" + +print(f"Fetching secret from regional Secret Manager ({location})...") +# Initialize Secret Manager Client (Regional) +client = SecretManagerClient(location=location) + +# Fetch secret +try: + secret_payload = client.get_secret(resource_name) + print("Successfully fetched secret.") + # The secret_payload can now be used by the agent or its tools as required. +except Exception as e: + print(f"Error fetching secret: {e}") + raise e + +# Initialize the agent +root_agent = Agent( + model='gemini-2.5-flash', + name='root_agent', + description='A helpful assistant for user questions.', + instruction='Answer user questions to the best of your knowledge', +) + +print("Agent initialized successfully.") diff --git a/secretmanager/snippets-adk/agent_regional/noxfile_config.py b/secretmanager/snippets-adk/agent_regional/noxfile_config.py new file mode 100644 index 00000000000..873ef83d52a --- /dev/null +++ b/secretmanager/snippets-adk/agent_regional/noxfile_config.py @@ -0,0 +1,38 @@ +# Copyright 2020 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"], + # Old samples are opted out of enforcing Python type hints + # All new samples should feature them + "enforce_type_hints": True, + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + "gcloud_project_env": "GOOGLE_CLOUD_PROJECT", + # "gcloud_project_env": "BUILD_SPECIFIC_GCLOUD_PROJECT", + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + "envs": {}, +} diff --git a/secretmanager/snippets-adk/agent_regional/requirements-test.txt b/secretmanager/snippets-adk/agent_regional/requirements-test.txt new file mode 100644 index 00000000000..b3b2b3ca4cc --- /dev/null +++ b/secretmanager/snippets-adk/agent_regional/requirements-test.txt @@ -0,0 +1 @@ +pytest==9.0.3 diff --git a/secretmanager/snippets-adk/agent_regional/requirements.txt b/secretmanager/snippets-adk/agent_regional/requirements.txt new file mode 100644 index 00000000000..a4f5a5371c3 --- /dev/null +++ b/secretmanager/snippets-adk/agent_regional/requirements.txt @@ -0,0 +1 @@ +google-adk>=1.29 diff --git a/secretmanager/snippets-adk/agent_regional/snippets_adk_test.py b/secretmanager/snippets-adk/agent_regional/snippets_adk_test.py new file mode 100644 index 00000000000..f530c5ae72f --- /dev/null +++ b/secretmanager/snippets-adk/agent_regional/snippets_adk_test.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +# Copyright 2026 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 + +import os +import subprocess +import time +from typing import Iterator +import uuid + +from google.api_core import exceptions +from google.cloud import secretmanager +import pytest + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PARENT_DIR = os.path.dirname(CURRENT_DIR) + + +@pytest.fixture() +def location() -> str: + return "us-east5" + + +@pytest.fixture() +def client(location: str) -> secretmanager.SecretManagerServiceClient: + client_options = {"api_endpoint": f"secretmanager.{location}.rep.googleapis.com"} + return secretmanager.SecretManagerServiceClient(client_options=client_options) + + +@pytest.fixture() +def project_id() -> str: + return os.environ["GOOGLE_CLOUD_PROJECT"] + + +@pytest.fixture() +def secret_id( + client: secretmanager.SecretManagerServiceClient, project_id: str, location: str +) -> Iterator[str]: + secret_id = f"python-adk-test-{uuid.uuid4()}" + yield secret_id + + # Teardown: delete the secret + secret_path = f"projects/{project_id}/locations/{location}/secrets/{secret_id}" + print(f"Deleting secret {secret_id}...") + try: + # Wait a bit to avoid conflicts if operations are still pending + time.sleep(2) + client.delete_secret(request={"name": secret_path}) + except exceptions.NotFound: + pass + + +def test_agent_regional( + client: secretmanager.SecretManagerServiceClient, + project_id: str, + location: str, + secret_id: str, +) -> None: + # Create the secret + parent = f"projects/{project_id}/locations/{location}" + print(f"Creating regional secret {secret_id} in {location}...") + client.create_secret( + request={ + "parent": parent, + "secret_id": secret_id, + } + ) + + # Add a version + secret_path = f"projects/{project_id}/locations/{location}/secrets/{secret_id}" + print(f"Adding version to {secret_id}...") + client.add_secret_version( + request={ + "parent": secret_path, + "payload": {"data": b"test-payload"}, + } + ) + + # Set environment variables required by the agent + os.environ["ADK_TEST_SECRET_ID"] = secret_id + os.environ["ADK_TEST_SECRET_VERSION"] = "latest" + os.environ["GOOGLE_CLOUD_PROJECT_LOCATION"] = location + + print(f"Running adk run agent_regional from {PARENT_DIR}...") + # Run the sample using adk run + result = subprocess.run( + ["adk", "run", "agent_regional"], + input="exit\n", + capture_output=True, + text=True, + cwd=PARENT_DIR, + ) + + print("STDOUT:") + print(result.stdout) + print("STDERR:") + print(result.stderr) + + assert result.returncode == 0 + assert "Successfully fetched secret" in result.stdout + assert "Agent initialized successfully" in result.stdout diff --git a/storage/cloudbuild/run_zonal_tests.sh b/storage/cloudbuild/run_zonal_tests.sh new file mode 100644 index 00000000000..25a8e714c7d --- /dev/null +++ b/storage/cloudbuild/run_zonal_tests.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Copyright 2026 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. +# + + +set -euxo pipefail +echo '--- Installing git and cloning repository on VM ---' +sudo apt-get update && sudo apt-get install -y git python3-pip python3-venv + +# Clone the repository and checkout the specific commit from the build trigger. +git clone --no-checkout --depth 1 --sparse --filter=blob:none https://github.com/GoogleCloudPlatform/python-docs-samples +cd python-docs-samples +git sparse-checkout set storage +git fetch origin "refs/pull/${_PR_NUMBER}/head" +git checkout ${COMMIT_SHA} +cd storage + + +echo '--- Installing Python and dependencies on VM ---' +python3 -m venv env +source env/bin/activate + +echo 'Install testing libraries explicitly, as they are not in setup.py' +pip install --upgrade pip +pip install pytest pytest-timeout pytest-subtests pytest-asyncio +pip install google-cloud-testutils google-cloud-kms +pip install google-cloud-storage[grpc,testing] + +echo '--- Setting up environment variables on VM ---' +export ZONAL_BUCKET=${_ZONAL_BUCKET} +export RUN_ZONAL_SYSTEM_TESTS=True +export GCE_METADATA_MTLS_MODE=None +CURRENT_ULIMIT=$(ulimit -n) +echo '--- Running Zonal tests on VM with ulimit set to ---' $CURRENT_ULIMIT +pytest -vv -s --log-format='%(asctime)s %(levelname)s %(message)s' --log-date-format='%H:%M:%S' samples/snippets/zonal_buckets/zonal_snippets_test.py diff --git a/storage/cloudbuild/zb-system-tests-cloudbuild.yaml b/storage/cloudbuild/zb-system-tests-cloudbuild.yaml new file mode 100644 index 00000000000..b968a0df18a --- /dev/null +++ b/storage/cloudbuild/zb-system-tests-cloudbuild.yaml @@ -0,0 +1,152 @@ +# Copyright 2026 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. +# + +substitutions: + _REGION: "us-central1" + _ZONE: "us-central1-a" + _SHORT_BUILD_ID: ${BUILD_ID:0:8} + _VM_NAME: "py-sdk-sys-test-${_SHORT_BUILD_ID}" + _ULIMIT: "10000" # 10k, for gRPC bidi streams + + + +steps: + # Step 0: Generate a persistent SSH key for this build run. + # This prevents gcloud from adding a new key to the OS Login profile on every ssh/scp command. + - name: "gcr.io/google.com/cloudsdktool/cloud-sdk" + id: "generate-ssh-key" + entrypoint: "bash" + args: + - "-c" + - | + mkdir -p /workspace/.ssh + # Generate the SSH key + ssh-keygen -t rsa -f /workspace/.ssh/google_compute_engine -N '' -C gcb + # Save the public key content to a file for the cleanup step + cat /workspace/.ssh/google_compute_engine.pub > /workspace/gcb_ssh_key.pub + waitFor: ["-"] + + - name: "gcr.io/google.com/cloudsdktool/cloud-sdk" + id: "cleanup-old-keys" + entrypoint: "bash" + args: + - "-c" + - | + #!/bin/bash + set -e + + echo "Fetching OS Login SSH keys..." + echo "Removing all keys." + echo "---------------------------------------------------------------------" + + FINGERPRINTS_TO_DELETE=$$(gcloud compute os-login ssh-keys list \ + --format="value(fingerprint)") + + echo "Keys to delete: $$FINGERPRINTS_TO_DELETE" + + if [ -z "$$FINGERPRINTS_TO_DELETE" ]; then + echo "No keys found to delete. Nothing to do." + exit 0 + fi + + while IFS= read -r FINGERPRINT; do + if [ -n "$$FINGERPRINT" ]; then + echo "Deleting key with fingerprint: $$FINGERPRINT" + gcloud compute os-login ssh-keys remove \ + --key="$$FINGERPRINT" \ + --quiet || true + fi + done <<< "$$FINGERPRINTS_TO_DELETE" + + echo "---------------------------------------------------------------------" + echo "Cleanup complete." + + # Step 1 Create a GCE VM to run the tests. + # The VM is created in the same zone as the buckets to test rapid storage features. + # It's given the 'cloud-platform' scope to allow it to access GCS and other services. + - name: "gcr.io/google.com/cloudsdktool/cloud-sdk" + id: "create-vm" + entrypoint: "gcloud" + args: + - "compute" + - "instances" + - "create" + - "${_VM_NAME}" + - "--project=${PROJECT_ID}" + - "--zone=${_ZONE}" + - "--machine-type=e2-medium" + - "--image-family=debian-13" + - "--image-project=debian-cloud" + - "--service-account=${_ZONAL_VM_SERVICE_ACCOUNT}" + - "--scopes=https://www.googleapis.com/auth/devstorage.full_control,https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/devstorage.read_write" + - "--metadata=enable-oslogin=TRUE" + waitFor: ["-"] + + # Step 2: Run the integration tests inside the newly created VM and cleanup. + # This step uses 'gcloud compute ssh' to execute a remote script. + # The VM is deleted after tests are run, regardless of success. + - name: "gcr.io/google.com/cloudsdktool/cloud-sdk" + id: "run-tests-and-delete-vm" + entrypoint: "bash" + args: + - "-c" + - | + set -e + # Wait for the VM to be fully initialized and SSH to be ready. + for i in {1..10}; do + if gcloud compute ssh ${_VM_NAME} --zone=${_ZONE} --internal-ip --ssh-key-file=/workspace/.ssh/google_compute_engine --command="echo VM is ready"; then + break + fi + echo "Waiting for VM to become available... (attempt $i/10)" + sleep 15 + done + # copy the script to the VM + gcloud compute scp storage/cloudbuild/run_zonal_tests.sh ${_VM_NAME}:~ --zone=${_ZONE} --internal-ip --ssh-key-file=/workspace/.ssh/google_compute_engine + + # Execute the script on the VM via SSH. + # Capture the exit code to ensure cleanup happens before the build fails. + set +e + gcloud compute ssh ${_VM_NAME} --zone=${_ZONE} --internal-ip --ssh-key-file=/workspace/.ssh/google_compute_engine --command="ulimit -n ${_ULIMIT}; COMMIT_SHA=${COMMIT_SHA} _ZONAL_BUCKET=${_ZONAL_BUCKET} CROSS_REGION_BUCKET=${_CROSS_REGION_BUCKET} _PR_NUMBER=${_PR_NUMBER} bash run_zonal_tests.sh" + EXIT_CODE=$? + set -e + + echo "--- Deleting GCE VM ---" + gcloud compute instances delete "${_VM_NAME}" --zone=${_ZONE} --quiet + + # Exit with the original exit code from the test script. + exit $$EXIT_CODE + waitFor: + - "create-vm" + - "generate-ssh-key" + - "cleanup-old-keys" + + - name: "gcr.io/google.com/cloudsdktool/cloud-sdk" + id: "cleanup-ssh-key" + entrypoint: "bash" + args: + - "-c" + - | + echo "--- Removing SSH key from OS Login profile to prevent accumulation ---" + gcloud compute os-login ssh-keys remove \ + --key-file=/workspace/gcb_ssh_key.pub || true + waitFor: + - "run-tests-and-delete-vm" + +timeout: "3600s" # 60 minutes + +options: + logging: CLOUD_LOGGING_ONLY + pool: + name: "projects/${PROJECT_ID}/locations/us-central1/workerPools/cloud-build-worker-pool" diff --git a/storage/hierarchical-namespace/delete_empty_folders.py b/storage/hierarchical-namespace/delete_empty_folders.py deleted file mode 100644 index c1075a742ff..00000000000 --- a/storage/hierarchical-namespace/delete_empty_folders.py +++ /dev/null @@ -1,397 +0,0 @@ -# Copyright 2025 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 concurrent.futures -import logging -import threading -import time - -from google.api_core import exceptions as google_exceptions -from google.api_core import retry -from google.cloud import storage_control_v2 -import grpc - -ThreadPoolExecutor = concurrent.futures.ThreadPoolExecutor - -# This script may be used to recursively delete a large number of nested empty -# folders in a GCS HNS bucket. Overview of the algorithm: -# 1. Folder Discovery: -# - Lists all folders under the BUCKET_NAME and FOLDER_PREFIX (if set). -# - Partitions all discovered folders into a map, keyed by depth -# (e.g. {1: [foo1/ foo2/], 2: [foo1/bar1/, foo1/bar2/, foo2/bar3/], ...} -# 2. Folder Deletion: -# - Processes depths in reverse order (from deepest to shallowest). -# - For each depth level, submits all folders at that level to a thread pool -# for parallel deletion. -# - Only moves to the next depth level once all folders at the current depth -# have been processed. This ensures that child folders are removed before -# their parents, respecting hierarhical constraints. -# -# Note: This script only deletes folders, not objects; any folders with child -# objects (immediate or nested) will fail to be deleted. -# -# Usage: See README.md for instructions. - -# --- Configuration --- -BUCKET_NAME = "your-gcs-bucket-name" - -# e.g. "archive/old_data/" or "" to delete all folders in the bucket. -# If specified, must end with '/'. -FOLDER_PREFIX = "chain_103/" - -# Max number of concurrent threads to use for deleting folders. -MAX_WORKERS = 100 - -# How often to log statistics during deletion, in seconds. -STATS_REPORT_INTERVAL = 5 - -# --- Data Structures & Globals --- -logging.basicConfig( - level=logging.INFO, format="%(asctime)s - %(threadName)s - %(message)s" -) - -# Global map to store folders by their depth -# { depth (int) -> set of full_resource_names (str) } -folders_by_depth = {} - -# Stats for monitoring progress -stats = { - "found_total": 0, - "successful_deletes": 0, - "failed_deletes_precondition": 0, - "failed_deletes_internal": 0, -} -stats_lock = threading.Lock() - -# Initialize the Storage Control API client -storage_control_client = storage_control_v2.StorageControlClient() - - -def _get_simple_path_and_depth(full_resource_name: str) -> tuple[str, int]: - """Extracts bucket-relative path and depth from a GCS folder resource name. - - The "simple path" is relative to the bucket (e.g., 'archive/logs/' for - 'projects/_/buckets/my-bucket/folders/archive/logs/'). - - The "depth" is the number of '/' in the simple path (e.g. 'archive/logs/' is - depth 2). - - Args: - full_resource_name: The full resource name of the GCS folder, e.g., - 'projects/_/buckets/your-bucket-name/folders/path/to/folder/'. - - Returns: - A tuple (simple_path: str, depth: int). - - Raises: - ValueError: If the resource name does not match the expected format - (i.e. start with 'projects/_/buckets/BUCKET_NAME/folders/FOLDER_PREFIX' - and ends with a trailing slash). - """ - base_folders_prefix = f"projects/_/buckets/{BUCKET_NAME}/folders/" - # The full prefix to validate against, including the global FOLDER_PREFIX. - # If FOLDER_PREFIX is "", this is equivalent to base_folders_prefix. - expected_validation_prefix = base_folders_prefix + FOLDER_PREFIX - - if not full_resource_name.startswith( - expected_validation_prefix - ) or not full_resource_name.endswith("/"): - raise ValueError( - f"Folder resource name '{full_resource_name}' does not match expected" - f" prefix '{expected_validation_prefix}' or missing trailing slash." - ) - - simple_path = full_resource_name[len(base_folders_prefix) :] - depth = simple_path.count("/") - if depth < 1: - raise ValueError( - f"Folder resource name '{full_resource_name}' has invalid depth" - f" {depth} (expected at least 1)." - ) - return simple_path, depth - - -def discover_and_partition_folders(): - """Discovers all folders in the bucket and partitions them by depth. - - Result is stored in the global folders_by_depth dictionary. - """ - parent_resource = f"projects/_/buckets/{BUCKET_NAME}" - - logging.info( - "Starting folder discovery and partitioning for bucket '%s'." - " Using prefix filter: '%s'.", - BUCKET_NAME, - FOLDER_PREFIX if FOLDER_PREFIX else "NONE (all folders)", - ) - - list_folders_request = storage_control_v2.ListFoldersRequest( - parent=parent_resource, prefix=FOLDER_PREFIX - ) - - num_folders_found = 0 - try: - for folder in storage_control_client.list_folders( - request=list_folders_request - ): - full_resource_name = folder.name - _, depth = _get_simple_path_and_depth(full_resource_name) - - if depth not in folders_by_depth: - folders_by_depth[depth] = set() - folders_by_depth[depth].add(full_resource_name) - - num_folders_found += 1 - with stats_lock: - stats["found_total"] = num_folders_found - - except Exception as e: - logging.error("Failed to list folders: %s", e, exc_info=True) - return - - logging.info( - "Finished discovery. Total folders found: %s.", num_folders_found - ) - if not folders_by_depth: - logging.info("No folders found in the bucket.") - else: - logging.info("Folders partitioned by depth:") - for depth_val in sorted(folders_by_depth.keys()): - logging.info( - " Depth %s: %s folders", depth_val, len(folders_by_depth[depth_val]) - ) - - -# Defines retriable error codes for the DeleteFolder API call. -def should_retry(exception): - if not isinstance( - exception, (google_exceptions.GoogleAPICallError, grpc.RpcError) - ): - return False - - # gRPC status codes to retry on, matching the JSON - retryable_grpc_codes = [ - grpc.StatusCode.RESOURCE_EXHAUSTED, - grpc.StatusCode.UNAVAILABLE, - grpc.StatusCode.INTERNAL, - grpc.StatusCode.UNKNOWN, - ] - - status_code = None - if isinstance(exception, google_exceptions.GoogleAPICallError): - status_code = exception.code - elif isinstance(exception, grpc.RpcError): - # For grpc.RpcError, code() returns the status code enum - status_code = exception.code() - - return status_code in retryable_grpc_codes - - -def delete_folder(folder_full_resource_name: str): - """Attempts to delete a single GCS HNS folder. - - Includes retry logic for transient errors. - - Stores stats in the global stats dictionary. - - Args: - folder_full_resource_name: The full resource name of the GCS folder to - delete, e.g., - 'projects/_/buckets/your-bucket-name/folders/path/to/folder/'. - """ - simple_path, _ = _get_simple_path_and_depth(folder_full_resource_name) - - retry_policy = retry.Retry( - predicate=should_retry, - initial=1.0, # Initial backoff: 1s - maximum=60.0, # Max backoff: 60s - multiplier=2.0, # Backoff multiplier: 2 - deadline=120.0, # Total time allowed for all retries and calls - ) - - try: - request = storage_control_v2.DeleteFolderRequest( - name=folder_full_resource_name - ) - storage_control_client.delete_folder(request=request, retry=retry_policy) - - with stats_lock: - stats["successful_deletes"] += 1 - return # Success - - except google_exceptions.NotFound: - # This can happen if the folder was deleted by another process. - logging.warning( - "Folder not found for deletion (already gone?): %s", simple_path - ) - return # Not a retriable error - except google_exceptions.FailedPrecondition as e: - # This typically means the folder contains objects. - logging.warning("Deletion failed for '%s': %s.", simple_path, e.message) - with stats_lock: - stats["failed_deletes_precondition"] += 1 - return # Not a retriable error - except Exception as e: - logging.error( - "Failed to delete '%s': %s", - simple_path, - e, - exc_info=True, - ) - with stats_lock: - stats["failed_deletes_internal"] += 1 - return # All retries exhausted - - -# --- STATS REPORTER THREAD --- -def stats_reporter_thread_logic(stop_event: threading.Event, start_time: float): - """Logs current statistics periodically.""" - logging.info("Stats Reporter: Started.") - while not stop_event.wait(STATS_REPORT_INTERVAL): - with stats_lock: - elapsed = time.time() - start_time - rate = stats["successful_deletes"] / elapsed if elapsed > 0 else 0 - logging.info( - "[STATS] Total Folders Found: %s | Successful Deletes: %s | Failed" - " Deletes (precondition): %s | Failed Deletes (internal): %s | Rate:" - " %.2f folders/sec", - stats["found_total"], - stats["successful_deletes"], - stats["failed_deletes_precondition"], - stats["failed_deletes_internal"], - rate, - ) - logging.info("Stats Reporter: Shutting down.") - - -# --- MAIN EXECUTION BLOCK --- -if __name__ == "__main__": - if BUCKET_NAME == "your-gcs-bucket-name": - print( - "\nERROR: Please update the BUCKET_NAME variable in the script before" - " running." - ) - exit(1) - - if FOLDER_PREFIX and not FOLDER_PREFIX.endswith("/"): - print("\nERROR: FOLDER_PREFIX must end with a '/' if specified.") - exit(1) - - start_time = time.time() - - logging.info("Starting GCS HNS folder deletion for bucket: %s", BUCKET_NAME) - - # Event to signal threads to stop gracefully. - stop_event = threading.Event() - - # Start the stats reporter thread. - stats_thread = threading.Thread( - target=stats_reporter_thread_logic, - args=(stop_event, start_time), - name="StatsReporter", - daemon=True, - ) - stats_thread.start() - - # Step 1: Discover and Partition Folders. - discover_and_partition_folders() - - if not folders_by_depth: - logging.info("No folders found to delete. Exiting.") - exit(0) - - # Prepare for multi-threaded deletion within each depth level. - deletion_executor = ThreadPoolExecutor( - max_workers=MAX_WORKERS, thread_name_prefix="DeleteFolderWorker" - ) - - try: - # Step 2: Iterate and delete by depth (from max to min). - sorted_depths = sorted(folders_by_depth.keys(), reverse=True) - for current_depth in sorted_depths: - folders_at_current_depth = folders_by_depth.get(current_depth, set()) - - if not folders_at_current_depth: - logging.info( - "Skipping depth %s: No folders found at this depth.", current_depth - ) - continue - - logging.info( - "\nProcessing depth %s: Submitting %s folders for deletion...", - current_depth, - len(folders_at_current_depth), - ) - - # Submit deletion tasks to the executor. - futures = [ - deletion_executor.submit(delete_folder, folder_path) - for folder_path in folders_at_current_depth - ] - - # Wait for all tasks at the current depth to complete. - # This is critical: we must ensure all nested folders are gone before - # tackling their parents. - concurrent.futures.wait(futures) - - logging.info( - "Finished processing all folders at depth %s.", current_depth - ) - - except KeyboardInterrupt: - logging.info( - "Main: Keyboard interrupt received. Attempting graceful shutdown..." - ) - except Exception as e: - logging.error( - "An unexpected error occurred in the main loop: %s", e, exc_info=True - ) - finally: - # Signal all threads to stop. - stop_event.set() - - # Shut down deletion executor and wait for any pending tasks to complete. - logging.info( - "Main: Shutting down deletion workers. Waiting for any final tasks..." - ) - deletion_executor.shutdown(wait=True) - - # Wait for the stats reporter to finish. - if stats_thread.is_alive(): - stats_thread.join( - timeout=STATS_REPORT_INTERVAL + 2 - ) # Give it a bit more time. - - # Log final statistics. - final_elapsed_time = time.time() - start_time - logging.info("\n--- FINAL SUMMARY ---") - with stats_lock: - final_rate = ( - stats["successful_deletes"] / final_elapsed_time - if final_elapsed_time > 0 - else 0 - ) - logging.info( - " - Total Folders Found (Initial Scan): %s\n - Successful Folder" - " Deletes: %s\n - Failed Folder Deletes (Precondition): %s\n -" - " Failed Folder Deletes (Internal): %s\n - Total Runtime: %.2f" - " seconds\n - Average Deletion Rate: %.2f folders/sec", - stats["found_total"], - stats["successful_deletes"], - stats["failed_deletes_precondition"], - stats["failed_deletes_internal"], - final_elapsed_time, - final_rate, - ) - logging.info("Script execution finished.") diff --git a/storage/hierarchical-namespace/README.md b/storagecontrol/hierarchical-namespace/README.md similarity index 90% rename from storage/hierarchical-namespace/README.md rename to storagecontrol/hierarchical-namespace/README.md index abe0066526b..70fe6525e7a 100644 --- a/storage/hierarchical-namespace/README.md +++ b/storagecontrol/hierarchical-namespace/README.md @@ -34,4 +34,6 @@ This script recursively deletes empty folders within a specified GCS bucket and 3. **Run:** `bash python3 delete_empty_folders.py` **Note:** This script *only* deletes folders. Folders containing any objects -will not be deleted, and a "Failed Precondition" warning will be logged. +will not be deleted, and a "Failed Precondition" warning will be logged. Creating empty folders +through the web interface will result in folders that are not truly empty, with a hidden 0 byte +file. Use CLI instead. diff --git a/storagecontrol/hierarchical-namespace/delete_empty_folders.py b/storagecontrol/hierarchical-namespace/delete_empty_folders.py new file mode 100644 index 00000000000..2aa9d8bf054 --- /dev/null +++ b/storagecontrol/hierarchical-namespace/delete_empty_folders.py @@ -0,0 +1,387 @@ +# Copyright 2025 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 concurrent.futures +import logging +import threading +import time + +from google.api_core import exceptions as google_exceptions +from google.api_core import retry +from google.cloud import storage_control_v2 +import grpc + +ThreadPoolExecutor = concurrent.futures.ThreadPoolExecutor + +# This script may be used to recursively delete a large number of nested empty +# folders in a GCS HNS bucket. Overview of the algorithm: +# 1. Folder Discovery: +# - Lists all folders under the BUCKET_NAME and FOLDER_PREFIX (if set). +# - Partitions all discovered folders into a map, keyed by depth +# (e.g. {1: [foo1/ foo2/], 2: [foo1/bar1/, foo1/bar2/, foo2/bar3/], ...} +# 2. Folder Deletion: +# - Processes depths in reverse order (from deepest to shallowest). +# - For each depth level, submits all folders at that level to a thread pool +# for parallel deletion. +# - Only moves to the next depth level once all folders at the current depth +# have been processed. This ensures that child folders are removed before +# their parents, respecting hierarhical constraints. +# +# Note: This script only deletes folders, not objects; any folders with child +# objects (immediate or nested) will fail to be deleted. +# +# Usage: See README.md for instructions. + +# --- Configuration --- +BUCKET_NAME = "YOUR_BUCKET_NAME" + +# e.g. "archive/old_data/" or "" to delete all folders in the bucket. +# If specified, must end with '/'. +FOLDER_PREFIX = "YOUR_FOLDER_PREFIX/" + +# Max number of concurrent threads to use for deleting folders. +MAX_WORKERS = 32 + +# How often to log statistics during deletion, in seconds. +STATS_REPORT_INTERVAL = 5 + +# --- Data Structures & Globals --- +logging.basicConfig( + level=logging.INFO, format="%(asctime)s - %(threadName)s - %(message)s" +) + +# Global map to store folders by their depth +# { depth (int) -> set of full_resource_names (str) } +folders_by_depth = {} + +# Stats for monitoring progress +stats = { + "found_total": 0, + "successful_deletes": 0, + "failed_deletes_precondition": 0, + "failed_deletes_internal": 0, +} +stats_lock = threading.Lock() + +# Initialize the Storage Control API client +storage_control_client = storage_control_v2.StorageControlClient() + + +def _get_simple_path_and_depth(full_resource_name: str) -> tuple[str, int]: + """Extracts bucket-relative path and depth from a GCS folder resource name. + + The "simple path" is relative to the bucket (e.g., 'archive/logs/' for + 'projects/_/buckets/my-bucket/folders/archive/logs/'). + + The "depth" is the number of '/' in the simple path (e.g. 'archive/logs/' is + depth 2). + + Args: + full_resource_name: The full resource name of the GCS folder, e.g., + 'projects/_/buckets/your-bucket-name/folders/path/to/folder/'. + + Returns: + A tuple (simple_path: str, depth: int). + + Raises: + ValueError: If the resource name does not match the expected format + (i.e. start with 'projects/_/buckets/BUCKET_NAME/folders/FOLDER_PREFIX' + and ends with a trailing slash). + """ + base_folders_prefix = f"projects/_/buckets/{BUCKET_NAME}/folders/" + # The full prefix to validate against, including the global FOLDER_PREFIX. + # If FOLDER_PREFIX is "", this is equivalent to base_folders_prefix. + expected_validation_prefix = base_folders_prefix + FOLDER_PREFIX + + if not full_resource_name.startswith( + expected_validation_prefix + ) or not full_resource_name.endswith("/"): + raise ValueError( + f"Folder resource name '{full_resource_name}' does not match expected" + f" prefix '{expected_validation_prefix}' or missing trailing slash." + ) + + simple_path = full_resource_name[len(base_folders_prefix) :] + depth = simple_path.count("/") + if depth < 1: + raise ValueError( + f"Folder resource name '{full_resource_name}' has invalid depth" + f" {depth} (expected at least 1)." + ) + return simple_path, depth + + +def discover_and_partition_folders() -> None: + """Discovers all folders in the bucket and partitions them by depth. + + Result is stored in the global folders_by_depth dictionary. + """ + parent_resource = f"projects/_/buckets/{BUCKET_NAME}" + + logging.info( + "Starting folder discovery and partitioning for bucket '%s'." + " Using prefix filter: '%s'.", + BUCKET_NAME, + FOLDER_PREFIX if FOLDER_PREFIX else "NONE (all folders)", + ) + + list_folders_request = storage_control_v2.ListFoldersRequest( + parent=parent_resource, prefix=FOLDER_PREFIX + ) + + num_folders_found = 0 + try: + for folder in storage_control_client.list_folders(request=list_folders_request): + full_resource_name = folder.name + _, depth = _get_simple_path_and_depth(full_resource_name) + + if depth not in folders_by_depth: + folders_by_depth[depth] = set() + folders_by_depth[depth].add(full_resource_name) + + num_folders_found += 1 + with stats_lock: + stats["found_total"] = num_folders_found + + except Exception as e: + logging.error("Failed to list folders: %s", e, exc_info=True) + return + + logging.info("Finished discovery. Total folders found: %s.", num_folders_found) + if not folders_by_depth: + logging.info("No folders found in the bucket.") + else: + logging.info("Folders partitioned by depth:") + for depth_val in sorted(folders_by_depth.keys()): + logging.info( + " Depth %s: %s folders", depth_val, len(folders_by_depth[depth_val]) + ) + + +# Defines retriable error codes for the DeleteFolder API call. +def should_retry(exception: Exception) -> int | None: + if not isinstance(exception, (google_exceptions.GoogleAPICallError, grpc.RpcError)): + return False + + # gRPC status codes to retry on, matching the JSON + retryable_grpc_codes = [ + grpc.StatusCode.RESOURCE_EXHAUSTED, + grpc.StatusCode.UNAVAILABLE, + grpc.StatusCode.INTERNAL, + grpc.StatusCode.UNKNOWN, + ] + + status_code = None + if isinstance(exception, google_exceptions.GoogleAPICallError): + status_code = exception.code + elif isinstance(exception, grpc.RpcError): + # For grpc.RpcError, code() returns the status code enum + status_code = exception.code() + + return status_code in retryable_grpc_codes + + +def delete_folder(folder_full_resource_name: str) -> None: + """Attempts to delete a single GCS HNS folder. + + Includes retry logic for transient errors. + + Stores stats in the global stats dictionary. + + Args: + folder_full_resource_name: The full resource name of the GCS folder to + delete, e.g., + 'projects/_/buckets/your-bucket-name/folders/path/to/folder/'. + """ + simple_path, _ = _get_simple_path_and_depth(folder_full_resource_name) + + retry_policy = retry.Retry( + predicate=should_retry, + initial=1.0, # Initial backoff: 1s + maximum=60.0, # Max backoff: 60s + multiplier=2.0, # Backoff multiplier: 2 + deadline=120.0, # Total time allowed for all retries and calls + ) + + try: + request = storage_control_v2.DeleteFolderRequest(name=folder_full_resource_name) + storage_control_client.delete_folder(request=request, retry=retry_policy) + + with stats_lock: + stats["successful_deletes"] += 1 + return # Success + + except google_exceptions.NotFound: + # This can happen if the folder was deleted by another process. + logging.warning( + "Folder not found for deletion (already gone?): %s", simple_path + ) + return # Not a retriable error + except google_exceptions.FailedPrecondition as e: + # This typically means the folder contains objects. + logging.warning("Deletion failed for '%s': %s.", simple_path, e.message) + with stats_lock: + stats["failed_deletes_precondition"] += 1 + return # Not a retriable error + except Exception as e: + logging.error( + "Failed to delete '%s': %s", + simple_path, + e, + exc_info=True, + ) + with stats_lock: + stats["failed_deletes_internal"] += 1 + return # All retries exhausted + + +# --- STATS REPORTER THREAD --- +def stats_reporter_thread_logic(stop_event: threading.Event, start_time: float) -> None: + """Logs current statistics periodically.""" + logging.info("Stats Reporter: Started.") + while not stop_event.wait(STATS_REPORT_INTERVAL): + with stats_lock: + elapsed = time.time() - start_time + rate = stats["successful_deletes"] / elapsed if elapsed > 0 else 0 + logging.info( + "[STATS] Total Folders Found: %s | Successful Deletes: %s | Failed" + " Deletes (precondition): %s | Failed Deletes (internal): %s | Rate:" + " %.2f folders/sec", + stats["found_total"], + stats["successful_deletes"], + stats["failed_deletes_precondition"], + stats["failed_deletes_internal"], + rate, + ) + logging.info("Stats Reporter: Shutting down.") + + +# --- MAIN EXECUTION BLOCK --- +if __name__ == "__main__": + if BUCKET_NAME == "your-gcs-bucket-name": + print( + "\nERROR: Please update the BUCKET_NAME variable in the script before" + " running." + ) + exit(1) + + if FOLDER_PREFIX and not FOLDER_PREFIX.endswith("/"): + print("\nERROR: FOLDER_PREFIX must end with a '/' if specified.") + exit(1) + + start_time = time.time() + + logging.info("Starting GCS HNS folder deletion for bucket: %s", BUCKET_NAME) + + # Event to signal threads to stop gracefully. + stop_event = threading.Event() + + # Start the stats reporter thread. + stats_thread = threading.Thread( + target=stats_reporter_thread_logic, + args=(stop_event, start_time), + name="StatsReporter", + daemon=True, + ) + stats_thread.start() + + # Step 1: Discover and Partition Folders. + discover_and_partition_folders() + + if not folders_by_depth: + logging.info("No folders found to delete. Exiting.") + exit(0) + + # Prepare for multi-threaded deletion within each depth level. + deletion_executor = ThreadPoolExecutor( + max_workers=MAX_WORKERS, thread_name_prefix="DeleteFolderWorker" + ) + + try: + # Step 2: Iterate and delete by depth (from max to min). + sorted_depths = sorted(folders_by_depth.keys(), reverse=True) + for current_depth in sorted_depths: + folders_at_current_depth = folders_by_depth.get(current_depth, set()) + + if not folders_at_current_depth: + logging.info( + "Skipping depth %s: No folders found at this depth.", current_depth + ) + continue + + logging.info( + "\nProcessing depth %s: Submitting %s folders for deletion...", + current_depth, + len(folders_at_current_depth), + ) + + # Submit deletion tasks to the executor. + futures = [ + deletion_executor.submit(delete_folder, folder_path) + for folder_path in folders_at_current_depth + ] + + # Wait for all tasks at the current depth to complete. + # This is critical: we must ensure all nested folders are gone before + # tackling their parents. + concurrent.futures.wait(futures) + + logging.info("Finished processing all folders at depth %s.", current_depth) + + except KeyboardInterrupt: + logging.info( + "Main: Keyboard interrupt received. Attempting graceful shutdown..." + ) + except Exception as e: + logging.error( + "An unexpected error occurred in the main loop: %s", e, exc_info=True + ) + finally: + # Signal all threads to stop. + stop_event.set() + + # Shut down deletion executor and wait for any pending tasks to complete. + logging.info( + "Main: Shutting down deletion workers. Waiting for any final tasks..." + ) + deletion_executor.shutdown(wait=True) + + # Wait for the stats reporter to finish. + if stats_thread.is_alive(): + stats_thread.join( + timeout=STATS_REPORT_INTERVAL + 2 + ) # Give it a bit more time. + + # Log final statistics. + final_elapsed_time = time.time() - start_time + logging.info("\n--- FINAL SUMMARY ---") + with stats_lock: + final_rate = ( + stats["successful_deletes"] / final_elapsed_time + if final_elapsed_time > 0 + else 0 + ) + logging.info( + " - Total Folders Found (Initial Scan): %s\n - Successful Folder" + " Deletes: %s\n - Failed Folder Deletes (Precondition): %s\n -" + " Failed Folder Deletes (Internal): %s\n - Total Runtime: %.2f" + " seconds\n - Average Deletion Rate: %.2f folders/sec", + stats["found_total"], + stats["successful_deletes"], + stats["failed_deletes_precondition"], + stats["failed_deletes_internal"], + final_elapsed_time, + final_rate, + ) + logging.info("Script execution finished.") diff --git a/trace/trace-python-sample-opentelemetry/README.rst.in b/trace/trace-python-sample-opentelemetry/README.rst.in index 471ffa008eb..c97c06d71f3 100644 --- a/trace/trace-python-sample-opentelemetry/README.rst.in +++ b/trace/trace-python-sample-opentelemetry/README.rst.in @@ -1,11 +1,11 @@ # This file is used to generate README.rst product: - name: Stackdriver Trace - short_name: Stackdriver Trace + name: Cloud Trace + short_name: Cloud Trace url: https://cloud.google.com/trace/docs description: > - `Stackdriver Trace`_ collects latency data from applications and displays + `Cloud Trace`_ collects latency data from applications and displays it in near real time in the Google Cloud Platform Console. setup: diff --git a/trace/trace-python-sample/README.md b/trace/trace-python-sample/README.md deleted file mode 100644 index 91151999ab3..00000000000 --- a/trace/trace-python-sample/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## Google Cloud Trace Python Samples - -The Cloud Trace samples have been moved. - -[![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.png)](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=trace/trace-python-sample-opentelemetry/README.rst) - -This directory is no longer contains samples for Google Cloud Trace. To see how to use Cloud Trace with OpenTelemetry please see [trace-python-sample-opentelemetry](../trace-python-sample-opentelemetry/README.rst). diff --git a/vision/snippets/crop_hints/requirements.txt b/vision/snippets/crop_hints/requirements.txt index 0267eb1541f..e813a2c08ea 100644 --- a/vision/snippets/crop_hints/requirements.txt +++ b/vision/snippets/crop_hints/requirements.txt @@ -1,3 +1,3 @@ google-cloud-vision==3.8.1 -pillow==9.5.0; python_version < '3.8' +pillow==10.3.0; python_version < '3.8' pillow==10.4.0; python_version >= '3.8' diff --git a/vision/snippets/document_text/requirements.txt b/vision/snippets/document_text/requirements.txt index 0267eb1541f..e813a2c08ea 100644 --- a/vision/snippets/document_text/requirements.txt +++ b/vision/snippets/document_text/requirements.txt @@ -1,3 +1,3 @@ google-cloud-vision==3.8.1 -pillow==9.5.0; python_version < '3.8' +pillow==10.3.0; python_version < '3.8' pillow==10.4.0; python_version >= '3.8' diff --git a/vision/snippets/face_detection/requirements.txt b/vision/snippets/face_detection/requirements.txt index 0267eb1541f..e813a2c08ea 100644 --- a/vision/snippets/face_detection/requirements.txt +++ b/vision/snippets/face_detection/requirements.txt @@ -1,3 +1,3 @@ google-cloud-vision==3.8.1 -pillow==9.5.0; python_version < '3.8' +pillow==10.3.0; python_version < '3.8' pillow==10.4.0; python_version >= '3.8'