Repository navigation
fix(gapic-generator): [Approach 1] thread default_host to OTel helpers instead of mutating client_options - #18933
chalmerlowe wants to merge 4 commits into
Conversation
…t host for OpenTelemetry spans
…el interceptor tests
…tating client_options.api_endpoint
There was a problem hiding this comment.
Code Review
This pull request introduces support for passing a resolved 'default_host' fallback parameter to transport wrappers and OpenTelemetry interceptors in 'google-api-core' and generated GAPIC clients, ensuring correct endpoint attribute extraction when 'api_endpoint' is unset. Feedback on the changes highlights a critical issue in the generated compatibility check ('_compat.py.j2'), where checking 'kwdefaults' for 'default_host' will always evaluate to False because it is a positional-or-keyword argument; using 'inspect.signature' is recommended instead.
| SUPPORTS_DEFAULT_HOST = bool( | ||
| getattr(gapic_v1.method.wrap_method, "__kwdefaults__", None) | ||
| and "default_host" in gapic_v1.method.wrap_method.__kwdefaults__ | ||
| ) |
There was a problem hiding this comment.
The current check for default_host support relies on __kwdefaults__. However, default_host is defined as a standard positional-or-keyword argument (not a keyword-only argument) in gapic_v1.method.wrap_method. Therefore, __kwdefaults__ will be None, and SUPPORTS_DEFAULT_HOST will always evaluate to False, silently disabling the feature in generated clients.\n\nUsing inspect.signature is a robust and standard way to check if the parameter is supported.
import inspect\n\nSUPPORTS_DEFAULT_HOST = \"default_host\" in inspect.signature(gapic_v1.method.wrap_method).parameters
Summary
Comparison prototype (Clone 1 of #18869) implementing Approach 1: threading
default_hostexplicitly intogoogle.api_core._observabilityandgapic_v1.method.wrap_method/method_async.wrap_methodinstead of mutatingclient_options.api_endpoint.Changes on top of #18869
default_hostparameter (google-api-core&gapic-generator):default_host: Optional[str] = Noneto_extract_endpoint_attributes,get_otel_interceptor,get_otel_async_interceptor,apply_otel_async_channel_interceptors, andgapic_v1.method.wrap_method/method_async.wrap_method.self._client_optionsonTransportcompletely untouched (from_dictconversion only; no copying or mutation ofapi_endpoint)._ignore_credentials):self._default_host = None if self._ignore_credentials else self._hostso pre-constructedgrpc.Channel/grpc.aio.Channelinstances do not falsely reportDEFAULT_HOSTwhenapi_endpointis unset.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).