FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat: Add Feature Gating configuration helpers. by chalmerlowe · Pull Request #17524 · googleapis/google-cloud-python · GitHub

feat: Add Feature Gating configuration helpers. - #17524

Merged
chalmerlowe merged 34 commits into
mainfrom
feat/otel-prototype
Jul 23, 2026
Merged

feat: Add Feature Gating configuration helpers.#17524
chalmerlowe merged 34 commits into
mainfrom
feat/otel-prototype

Conversation

chalmerlowe commented Jun 22, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

This PR introduces a foundational configuration layer for integrating General Feature gating into Google Cloud Python client libraries.

Intent & Motivation

We are about be embark on adding observability (o11y) to entire suite of Cloud SDK libraries. To enable this functionality on an opt-in basis we are prepping a general feature gating capability. While the initial push is towards enabling o11y, we recognize that this can and should be more general than that.

Changes Included

  • Configuration Resolution Logic: Added the resolve_feature_flag function in the new _feature_gating_helpers package to resolve feature gates:

Resolves settings in the following order of precedence:
1. Programmatic overrides in configurations (checks for feature_key values)
2. Language-wide Environment Variable: GOOGLE_CLOUD_PYTHON_<FEATURE>_ENABLED
(natively checks for an EXPERIMENTAL token first e.g. GOOGLE_CLOUD_[EXPERIMENTAL]_PYTHON_<FEATURE>_ENABLED)
3. Default fallback

  • Experimental Fallbacks: Implemented fallback logic that automatically checks for EXPERIMENTAL prefixes within the environment variable definitions to support early-stage adoption and rollout phases safely.

  • Test Coverage: Provided test coverage using pytest for precedence rules and environmental scenarios.

gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Code Review

This pull request introduces observability environment variable and client options resolution helpers under a new observability module, including the is_signal_enabled function and corresponding unit tests. Feedback is provided to improve the resolution of client options by avoiding direct __dict__ access (which fails for classes using __slots__ or properties) in favor of getattr, and replacing rstrip('s') with a safer suffix removal method to prevent unintended character stripping.

chalmerlowe force-pushed the feat/otel-prototype branch from 53085c1 to 9aa54fb Compare July 6, 2026 12:18
chalmerlowe marked this pull request as ready for review July 6, 2026 18:24
chalmerlowe requested a review from a team as a code owner July 6, 2026 18:24
chalmerlowe added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

While it is likely that this PR is complete, we want to wait until the design doc (being handled internally) is complete and approved before merging.

chalmerlowe force-pushed the feat/otel-prototype branch from db771c1 to 0f92c35 Compare July 15, 2026 15:46
def resolve_feature_flags(
env_var: str,
provider_key: str,
client_options: Optional[Union[Dict[str, Any], Any]] = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I assume Any is for ClientOptions? Why not use the class directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Redundant

This hint is a bit redundant. Since Any covers everything (including dictionaries), putting Dict[str, Any] inside the Union with Any doesn't restrict anything for a type checker.

Optional[Union[Dict[str, Any], Any]]

Clarity

If we change it to:

client_options: Optional[Union[Dict[str, Any], ClientOptions]] = None

We do get some clarity. An engineer looking at the function signature knows exactly what is expected in one scenario.

Duck Typing

However, there is a reason to prefer Any (or object) here. It gives our customers flexibility to use their own custom options classes, as long as they implement the interface our code expects (i.e they can use duck typing).

In our implementation of _has_provider:

    if isinstance(client_options, dict):
        return client_options.get(provider_key) is not None
    return getattr(client_options, provider_key, None) is not None

We use getattr(). This means our helper doesn't care if the object is strictly a ClientOptions. It can be any object that happens to have the attribute we are looking for. We can see this intent in our tests in test_feature_gating_helpers.py:

class _MockOptions:
    def __init__(self):
        self.other_option = "value"

We pass this _MockOptions object to resolve_feature_flags. It is NOT a subclass of ClientOptions.

If we change the type hint to ClientOptions, strict type checkers (like mypy) will claim that _MockOptions is not a valid argument.
If we keep it as Any (or object), the type checker stays quiet because it understands we are using duck typing.

daniel-sanche Jul 22, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

How common do you expect that use case to be? Will customers even have reason to call this code? And if they did, couldn't they also achieve this by either:

  • subclassing ClientOptions with their own implementation
  • passing in a dict
  • using typing.cast

Personally, I think allowing arbitrary types here feels overkill, and potentially dangerous. Dict[str, Any] | ClientOptions makes more sense to me. Or really, ideally just one or the other

But it sounds like you have plans to extend this in the future, so maybe I'm missing context. If you want to keep it fully permissive, I'd suggest:

  • rename client_options to something more general
  • use object instead of Any (since only objects have getattr)
  • include ClientOptions in the type annotation, for the same reason you include Dict

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We included ClientOptions in the type annotation.

"""

# Check for programmatic feature provider
has_provider = _has_provider(client_options, provider_key)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

nit: this helper wouldn't be needed if you can simplify the client_options type (either by disallowing dicts, or doing a one-liner to convert them)

options = ClientOptions.from_dict(client_options) if isinstance(client_options, dict) else client_options
has_provider = getattr(options, provider_key, None) is not None

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I prefer to keep the code in the resolver lean and extensible thus the choice to use helper functions like _has_provider

Especially considering that at a future time I would like to add the ability for the resolver to resolve:

  • legacy environment variables (such as multiple env vars that we already have in Spanner and Storage)

In addition, there is also some benefit to being able to set env vars on a language level (turn on o11y in Python by not Node) OR on a per-service level (turn on o11y in Bigtable but not Firestore).

Being able to slip tiny helper functions into the resolver helps keep the resolution logic and precedence order the main priority AND not "how should we determine if something is set OR not set and how is that different from how we parsed providers 12 lines up OR parsed this customer env var"

  • Language-wide env vars (e.g., GOOGLE_CLOUD_<LANGUAGE>_TRACING_ENABLED)
  • Service-Specific env vars (e.g., GOOGLE_CLOUD_<SERVICE>_TRACING_ENABLED
  • etc

If we are running this function multiple times in a row (e.g., during client initialization to check GOOGLE_SDK_PYTHON_TRACING_ENABLED, then GOOGLE_SDK_PYTHON_METRICS_ENABLED, etc.), we want resolve_feature_flags to be straight forward for troubleshooting and maintenance.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It sounds like the function signature for resolve_feature_flags could be changing in the future then? Do you know what it would look like? We have to be careful about breaking changes, so if there's anything we can do now to make it more flexible, that would be great

I don't completely understand the plan yet, but a couple things to consider:

  • client_options could be given a more general name (like configuration), if we expect other config types in the future
  • We could add * to make client_options keyword only, so we can insert others in any order later
  • env_var and client_options could accept lists instead of single items (although I think we could add this without a breaking change later)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

These are good ideas for future-proofing. We agree on making arguments keyword-only and using more general names. We updated the signature to make all arguments keyword-only (placing * at the start) to prevent accidental parameter swapping and allow easy expansion later. We have also renamed provider_key to feature_key and client_options to configuration to reflect that this is a generic internal helper.

Regarding lists: the resolver is currently intended to be a simple one-specific-input, one-specific-output (e.g. a boolean) gate, so the idea of passing in lists of configs is not in line with the expected use. If we need to resolve several gates, we expect to call it multiple times, keeping the logic simple:

is_tracing_enabled = resolve_feature_flags(env_var="GOOGLE_CLOUD_PYTHON_TRACING_ENABLED") 
is_metrics_enabled = resolve_feature_flags(env_var="GOOGLE_CLOUD_EXPERIMENTAL_PYTHON_METRICS_ENABLED", feature_key="metrics_provider", configuration=client_options) 
is_creds_feature_enabled = resolve_feature_flags(env_var="GOOGLE_CLOUD_CREDENTIALS_FEATURE_ENABLED", feature_key="credential_type", configuration=credentials)

Comment thread packages/google-api-core/pyproject.toml Outdated

chalmerlowe commented Jul 22, 2026
edited
Loading

Copy link
Copy Markdown
Contributor Author

While it is likely that this PR is complete, we want to wait until the design doc (being handled internally) is complete and approved before merging.

Removing the do not merge label based on progress in the LLD.

chalmerlowe removed the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Jul 22, 2026

daniel-sanche left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Nothing blocking, but I left a few comments to consider, for things that could be hard to change after merging

If none of them seem concerning, I'm good to approve as-is


def resolve_feature_flags(
env_var: str,
provider_key: str,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

nit: I wonder if the provider naming is general enough? "Provider" is the term used for Otel, but does it apply equally to all features? Maybe this should be called feature_key? Or flag_id?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We updated the arg name.

if "EXPERIMENTAL" in env_var:
# Fail Fast if provider present but experimental environment variable is not enabled
if env_var_setting is not True and has_provider:
raise ValueError(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Do you think a custom error would be helpful here? ValueError seems a like an imperfect fit for this kind of thing. And, assuming this is being called as part of client init, we may be rasing other ValueErrors for other reasons, so it might be good to differentiate them some more

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We updated to a custom error.

def resolve_feature_flags(
env_var: str,
provider_key: str,
client_options: Optional[Union[Dict[str, Any], Any]] = None,

daniel-sanche Jul 22, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

How common do you expect that use case to be? Will customers even have reason to call this code? And if they did, couldn't they also achieve this by either:

  • subclassing ClientOptions with their own implementation
  • passing in a dict
  • using typing.cast

Personally, I think allowing arbitrary types here feels overkill, and potentially dangerous. Dict[str, Any] | ClientOptions makes more sense to me. Or really, ideally just one or the other

But it sounds like you have plans to extend this in the future, so maybe I'm missing context. If you want to keep it fully permissive, I'd suggest:

  • rename client_options to something more general
  • use object instead of Any (since only objects have getattr)
  • include ClientOptions in the type annotation, for the same reason you include Dict

"""

# Check for programmatic feature provider
has_provider = _has_provider(client_options, provider_key)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It sounds like the function signature for resolve_feature_flags could be changing in the future then? Do you know what it would look like? We have to be careful about breaking changes, so if there's anything we can do now to make it more flexible, that would be great

I don't completely understand the plan yet, but a couple things to consider:

  • client_options could be given a more general name (like configuration), if we expect other config types in the future
  • We could add * to make client_options keyword only, so we can insert others in any order later
  • env_var and client_options could accept lists instead of single items (although I think we could add this without a breaking change later)

if isinstance(client_options, dict):
return client_options.get(provider_key) is not None

return getattr(client_options, provider_key, None) is not None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Maybe we should have some limitations provider_key? Like returning False for __?

Something like __class__ or __dict__ would return True, but probably not what we're looking for

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We added protections against reading dunder_methods.

chalmerlowe left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Removed refs to otel in constraints.txt files.

Comment thread packages/google-api-core/pyproject.toml Outdated
chalmerlowe changed the title feat: Add OpenTelemetry environment variable and options configuration helpers. feat: Add Feature Gating configuration helpers. Jul 23, 2026
chalmerlowe merged commit eceea95 into main Jul 23, 2026
39 checks passed
chalmerlowe deleted the feat/otel-prototype branch July 23, 2026 17:49
release-please Bot mentioned this pull request Jul 23, 2026
sofisl pushed a commit that referenced this pull request Aug 6, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>bigquery-magics: 0.15.1</summary>

##
[0.15.1](bigquery-magics-v0.15.0...bigquery-magics-v0.15.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>gapic-generator: 1.38.0</summary>

##
[1.38.0](gapic-generator-v1.37.1...gapic-generator-v1.38.0)
(2026-08-06)


### Features

* **generator:** delegate REST transcoding to google-api-core
([#17766](#17766))
([7b05aab](7b05aab))
* **generator:** gapic generator centralization routing
([#17816](#17816))
([32a2442](32a2442))


### Bug Fixes

* add typing for header_params
([#17914](#17914))
([9e98b93](9e98b93))
* **api-core:** use truthiness check in setup_request_id to support
proto-plus messages
([#18000](#18000))
([ad8f93c](ad8f93c))
* avoid retaining routing parameter instances in cache
([#17961](#17961))
([f64ada2](f64ada2))
* bump aiohttp from 3.13.5 to 3.14.3 in /packages/gapic-generator
([#17990](#17990))
([6ff5815](6ff5815))
* bump cryptography from 48.0.1 to 50.0.0 in /packages/gapic-generator
([#17991](#17991))
([d607f25](d607f25))
* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* **generator:** use flat_ref_types in test templates and delete
remove-unused-imports
([#17900](#17900))
([395f764](395f764))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
* resolve collision with reserved words in samples
([#17912](#17912))
([588cda9](588cda9))
* upgrade Protobuf and gRPC in WORKSPACE
([#17882](#17882))
([5b5ece5](5b5ece5))
</details>

<details><summary>gcp-sphinx-docfx-yaml: 3.3.1</summary>

##
[3.3.1](gcp-sphinx-docfx-yaml-v3.3.0...gcp-sphinx-docfx-yaml-v3.3.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-ads-admanager: 0.10.1</summary>

##
[0.10.1](google-ads-admanager-v0.10.0...google-ads-admanager-v0.10.1)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-api-core: 2.34.0</summary>

##
[2.34.0](google-api-core-v2.33.0...google-api-core-v2.34.0)
(2026-08-06)


### Features

* Add Feature Gating configuration helpers.
([#17524](#17524))
([eceea95](eceea95))
* **api-core:** centralize rest transcoding helpers
([#17765](#17765))
([4f21b8b](4f21b8b))


### Bug Fixes

* **api-core:** use truthiness check in setup_request_id to support
proto-plus messages
([#18000](#18000))
([ad8f93c](ad8f93c))
* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* deduplicate x-goog-api-client headers
([#17616](#17616))
([6167e41](6167e41))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-apps-chat: 0.10.4</summary>

##
[0.10.4](google-apps-chat-v0.10.3...google-apps-chat-v0.10.4)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-auth: 2.56.3</summary>

##
[2.56.3](google-auth-v2.56.2...google-auth-v2.56.3)
(2026-08-06)


### Bug Fixes

* **auth:** avoid creating mTLS SSL context for custom async transports
([#17825](#17825))
([fbe33f9](fbe33f9)),
refs
[#17622](#17622)
* **auth:** only trigger mTLS certificate rotation on mTLS endpoints
([#17928](#17928))
([f7b49ea](f7b49ea))
* **auth:** properly extract stdout from gnubby webauthn plugin failures
([#17885](#17885))
([744e826](744e826))
* deduplicate x-goog-api-client headers
([#17616](#17616))
([6167e41](6167e41))
* **oauth2:** avoid redundant JWKS network fetches
([#17891](#17891))
([de53298](de53298))


### Performance Improvements

* **auth:** use generator expression in any() to allow short-circuiting
([735e565](735e565))
* **auth:** use generator expression in any() to allow short-circuiting
([#17937](#17937))
([735e565](735e565))
</details>

<details><summary>google-auth-httplib2: 0.4.1</summary>

##
[0.4.1](google-auth-httplib2-v0.4.0...google-auth-httplib2-v0.4.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-access-context-manager: 0.6.1</summary>

##
[0.6.1](google-cloud-access-context-manager-v0.6.0...google-cloud-access-context-manager-v0.6.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-agentidentitycredentials: 0.1.1</summary>

##
[0.1.1](google-cloud-agentidentitycredentials-v0.1.0...google-cloud-agentidentitycredentials-v0.1.1)
(2026-08-06)


### Features

* **google/cloud/agentidentitycredentials/v1beta:** add
google-cloud-agentidentitycredentials v1beta
([#17898](#17898))
([b692dae](b692dae))
* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-audit-log: 0.6.1</summary>

##
[0.6.1](google-cloud-audit-log-v0.6.0...google-cloud-audit-log-v0.6.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-backupdr: 0.10.1</summary>

##
[0.10.1](google-cloud-backupdr-v0.10.0...google-cloud-backupdr-v0.10.1)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-batch: 0.22.2</summary>

##
[0.22.2](google-cloud-batch-v0.22.1...google-cloud-batch-v0.22.2)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-biglake: 0.5.1</summary>

##
[0.5.1](google-cloud-biglake-v0.5.0...google-cloud-biglake-v0.5.1)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-biglake-hive: 0.3.2</summary>

##
[0.3.2](google-cloud-biglake-hive-v0.3.1...google-cloud-biglake-hive-v0.3.2)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-bigquery: 3.43.0</summary>

##
[3.43.0](google-cloud-bigquery-v3.42.3...google-cloud-bigquery-v3.43.0)
(2026-08-06)


### Features

* add pandas-gbq capability helper
([#17957](#17957))
([2207ca6](2207ca6))


### Bug Fixes

* **bigquery:** Fix bigquery socket leak
([#17953](#17953))
([8c26b38](8c26b38))
* remove stray debug print in RangeQueryParameter constructor
([#17973](#17973))
([fe7bfd0](fe7bfd0))


### Documentation

* add connector libraries overview table to package README
([#17939](#17939))
([71bc622](71bc622))
* correct return type in CellDataParser.time_to_py docstring
([#17972](#17972))
([bd1e224](bd1e224))
</details>

<details><summary>google-cloud-bigquery-storage: 2.40.0</summary>

##
[2.40.0](google-cloud-bigquery-storage-v2.39.0...google-cloud-bigquery-storage-v2.40.0)
(2026-08-06)


### Features

* delegate ReadRowsPage.to_arrow to pandas_gbq.arrow
([#17938](#17938))
([aedc66f](aedc66f))


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
</details>

<details><summary>google-cloud-binary-authorization: 1.19.1</summary>

##
[1.19.1](google-cloud-binary-authorization-v1.19.0...google-cloud-binary-authorization-v1.19.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-build: 3.38.1</summary>

##
[3.38.1](google-cloud-build-v3.38.0...google-cloud-build-v3.38.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-commerceproducer: 0.1.1</summary>

##
[0.1.1](google-cloud-commerceproducer-v0.1.0...google-cloud-commerceproducer-v0.1.1)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-containeranalysis: 2.22.1</summary>

##
[2.22.1](google-cloud-containeranalysis-v2.22.0...google-cloud-containeranalysis-v2.22.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-core: 2.6.1</summary>

##
[2.6.1](google-cloud-core-v2.6.0...google-cloud-core-v2.6.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-documentai-toolbox: 0.17.2</summary>

##
[0.17.2](google-cloud-documentai-toolbox-v0.17.1...google-cloud-documentai-toolbox-v0.17.2)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-filestore: 1.17.1</summary>

##
[1.17.1](google-cloud-filestore-v1.17.0...google-cloud-filestore-v1.17.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-firestore: 2.28.1</summary>

##
[2.28.1](google-cloud-firestore-v2.28.0...google-cloud-firestore-v2.28.1)
(2026-08-06)


### Bug Fixes

* **firestore:** BulkWriter pop from an empty deque
([#17490](#17490))
([8e826f0](8e826f0))
* **firestore:** preserve async limit_to_last ordering
([#17879](#17879))
([caf2fdb](caf2fdb))
</details>

<details><summary>google-cloud-gke-hub: 1.25.1</summary>

##
[1.25.1](google-cloud-gke-hub-v1.25.0...google-cloud-gke-hub-v1.25.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-iam: 2.24.1</summary>

##
[2.24.1](google-cloud-iam-v2.24.0...google-cloud-iam-v2.24.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-logging: 3.16.2</summary>

##
[3.16.2](google-cloud-logging-v3.16.1...google-cloud-logging-v3.16.2)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-memorystore: 0.5.4</summary>

##
[0.5.4](google-cloud-memorystore-v0.5.3...google-cloud-memorystore-v0.5.4)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-ndb: 2.5.1</summary>

##
[2.5.1](google-cloud-ndb-v2.5.0...google-cloud-ndb-v2.5.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-network-connectivity: 2.17.0</summary>

##
[2.17.0](google-cloud-network-connectivity-v2.16.0...google-cloud-network-connectivity-v2.17.0)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-network-services: 0.10.2</summary>

##
[0.10.2](google-cloud-network-services-v0.10.1...google-cloud-network-services-v0.10.2)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
* update googleapis and regenerate
([#17933](#17933))
([f7a23a0](f7a23a0))
</details>

<details><summary>google-cloud-pubsub: 2.39.1</summary>

##
[2.39.1](google-cloud-pubsub-v2.39.0...google-cloud-pubsub-v2.39.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
</details>

<details><summary>google-cloud-quotas: 0.6.2</summary>

##
[0.6.2](google-cloud-quotas-v0.6.1...google-cloud-quotas-v0.6.2)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-redis-cluster: 0.5.2</summary>

##
[0.5.2](google-cloud-redis-cluster-v0.5.1...google-cloud-redis-cluster-v0.5.2)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-service-control: 1.21.0</summary>

##
[1.21.0](google-cloud-service-control-v1.20.0...google-cloud-service-control-v1.21.0)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-spanner: 3.69.1</summary>

##
[3.69.1](google-cloud-spanner-v3.69.0...google-cloud-spanner-v3.69.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* **metrics:** fix GFE and AFE metrics publishing
([#17561](#17561))
([abf1178](abf1178))
* **spanner:** escape embedded backticks in dbapi escape_name
([#17810](#17810))
([c8b0b28](c8b0b28))
* **spanner:** implement dict protocol and nested unwrapping for
JsonObject
([#17915](#17915))
([06c1f05](06c1f05)),
refs
[#15870](#15870)
</details>

<details><summary>google-cloud-storage: 3.13.1</summary>

##
[3.13.1](google-cloud-storage-v3.13.0...google-cloud-storage-v3.13.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-cloud-storage-control: 1.13.0</summary>

##
[1.13.0](google-cloud-storage-control-v1.12.0...google-cloud-storage-control-v1.13.0)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-support: 0.5.2</summary>

##
[0.5.2](google-cloud-support-v0.5.1...google-cloud-support-v0.5.2)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17933](#17933))
([f7a23a0](f7a23a0))
</details>

<details><summary>google-cloud-tasks: 2.24.0</summary>

##
[2.24.0](google-cloud-tasks-v2.23.0...google-cloud-tasks-v2.24.0)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-cloud-testutils: 1.9.2</summary>

##
[1.9.2](google-cloud-testutils-v1.9.1...google-cloud-testutils-v1.9.2)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>google-developer-knowledge: 0.1.1</summary>

##
[0.1.1](google-developer-knowledge-v0.1.0...google-developer-knowledge-v0.1.1)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-maps-navconnect: 0.2.1</summary>

##
[0.2.1](google-maps-navconnect-v0.2.0...google-maps-navconnect-v0.2.1)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17893](#17893))
([e70ab6f](e70ab6f))
</details>

<details><summary>google-resumable-media: 2.10.1</summary>

##
[2.10.1](google-resumable-media-v2.10.0...google-resumable-media-v2.10.1)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>googleapis-common-protos: 1.75.1</summary>

##
[1.75.1](googleapis-common-protos-v1.75.0...googleapis-common-protos-v1.75.1)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>grafeas: 1.24.0</summary>

##
[1.24.0](grafeas-v1.23.0...grafeas-v1.24.0)
(2026-08-06)


### Features

* update googleapis and regenerate
([#17933](#17933))
([f7a23a0](f7a23a0))
</details>

<details><summary>grpc-google-iam-v1: 0.14.5</summary>

##
[0.14.5](grpc-google-iam-v1-v0.14.4...grpc-google-iam-v1-v0.14.5)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>proto-plus: 1.28.3</summary>

##
[1.28.3](proto-plus-v1.28.2...proto-plus-v1.28.3)
(2026-08-06)


### Bug Fixes

* bump grpcio to 1.59.0; require Python 3.10+
([#17351](#17351))
([a53487a](a53487a))
* **proto-plus:** add context to TypeErrors during message manipulation
([#17682](#17682))
([08f21a6](08f21a6))
* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

<details><summary>sqlalchemy-bigquery: 1.17.2</summary>

##
[1.17.2](sqlalchemy-bigquery-v1.17.1...sqlalchemy-bigquery-v1.17.2)
(2026-08-06)


### Bug Fixes

* require Protobuf 6.33.5+
([#17743](#17743))
([d267342](d267342))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants


Back | FazBrowse Home | New Git URL