Repository navigation
fix(gapic-generator): [Approach 2] attach _host via internal _TransportClientOptions subclass - #18934
chalmerlowe wants to merge 4 commits into
Conversation
…t host for OpenTelemetry spans
…el interceptor tests
There was a problem hiding this comment.
Code Review
This pull request introduces a mechanism to attach the resolved transport host as a separate _host attribute on an internal _TransportClientOptions subclass without mutating api_endpoint. This allows OpenTelemetry spans to fall back to _host when api_endpoint is not set, which is also supported by updates to google-api-core's observability module. The changes include extensive updates to generated base transports, unit tests, and system tests. The reviewer suggests simplifying the conditional check for wrapping client_options to always wrap it when credentials are not ignored, ensuring robust support for dynamic OpenTelemetry enablement.
| if not self._ignore_credentials and ( | ||
| client_options is not None | ||
| or ( | ||
| _observability is not None | ||
| and _observability.is_otel_capabilities_enabled(None) | ||
| ) | ||
| ): |
There was a problem hiding this comment.
The current condition only wraps client_options when it is not None OR when OpenTelemetry is already enabled at startup.
This introduces an inconsistency:
- If a user passes
client_options=ClientOptions(), it is always wrapped and_hostis attached, even if OTEL is disabled at startup. If OTEL is enabled later dynamically, the host fallback works. - If a user passes
client_options=Noneand OTEL is disabled at startup, it is NOT wrapped. If OTEL is enabled later dynamically, the host fallback fails becauseself._client_optionsremainsNone.
To ensure consistent behavior and support dynamic OpenTelemetry enablement robustly, we should always wrap client_options in _TransportClientOptions when not self._ignore_credentials.
if not self._ignore_credentials:
Summary
Comparison prototype (Clone 2 of #18869) implementing Approach 2: wrapping
client_optionsin an internal_TransportClientOptions(client_options_lib.ClientOptions)subclass that attaches_hostseparately while keepingapi_endpointpristine.Changes on top of #18869
_TransportClientOptionssubclass (gapic-generator&google-api-core):_TransportClientOptions(client_options_lib.ClientOptions)intransports/base.py.j2to store_hostseparately without mutatingapi_endpointor changing publicwrap_method/ interceptor signatures._extract_endpoint_attributesingoogle/api_core/_observability.pyto fall back togetattr(client_options, "_host", None)(orclient_options.get("_host")) whenapi_endpointis unset._ignore_credentials):_TransportClientOptionswhenself._ignore_credentialsisTrueso pre-constructedgrpc.Channel/grpc.aio.Channelinstances do not falsely reportDEFAULT_HOST.construct_observability_clientintest_span_compliance.pyto pass a callable channel factory (_insecure_channel_factory) so local Showcase gRPC compliance tests exercise the primary host-managed path (self._ignore_credentials = False).dictconversion:dictclient_optionsupfront viaclient_options_lib.from_dict(client_options).