Repository navigation
fix(gapic-generator): forward quota_project_id, scopes, credentials_file and mTLS in REST transport - #18892
fix(gapic-generator): forward quota_project_id, scopes, credentials_file and mTLS in REST transport#18892kmelnikov wants to merge 1 commit into
Conversation
…ile and mTLS in REST transport In generated REST transports: - Forward credentials_file, scopes, and quota_project_id from <Service>RestTransport.__init__ through _Base<Service>RestTransport.__init__ to <Service>Transport.__init__. - Apply default/custom scopes (via ga_credentials.with_scopes_if_required) and quota_project_id (via with_quota_project) to explicit credentials in <Service>Transport.__init__, matching gRPC transport behavior in google.api_core.grpc_helpers. - Store client_cert_source_for_mtls on <Service>RestTransport and forward it to operations_v1.OperationsRestTransport in operations_client. - Update generated unit test template and integration goldens.
There was a problem hiding this comment.
Code Review
This pull request updates the GAPIC generator templates and golden files to correctly forward and apply scopes, quota project IDs, and credentials files in REST transports. It also introduces a new test suite to verify REST transport authentication. The code review identified a critical runtime issue in the base transport template where CredentialsWithQuotaProject is incorrectly accessed from google.api_core.credentials instead of google.auth.credentials, which would lead to an AttributeError.
| if quota_project_id and isinstance( | ||
| credentials, ga_credentials.CredentialsWithQuotaProject | ||
| ): | ||
| credentials = credentials.with_quota_project(quota_project_id) |
There was a problem hiding this comment.
In base.py.j2, ga_credentials is imported as from google.api_core import credentials as ga_credentials. However, CredentialsWithQuotaProject is defined in google.auth.credentials, not in google.api_core.credentials. This will cause an AttributeError at runtime when trying to access ga_credentials.CredentialsWithQuotaProject.
You should import google.auth.credentials separately (e.g., as google_auth_credentials) to perform this type check safely.
if quota_project_id and isinstance(
credentials, google.auth.credentials.CredentialsWithQuotaProject
):
There was a problem hiding this comment.
Thanks for the review. In this template ga_credentials is imported as from google.auth import credentials as ga_credentials (line 29), so ga_credentials.CredentialsWithQuotaProject already resolves to google.auth.credentials.CredentialsWithQuotaProject. The new test_<service>_base_transport_with_credentials test covers this branch, so no change is needed.
Summary
Generated REST transports (
<Service>RestTransport) acceptcredentials_file,scopes,quota_project_id, andclient_cert_source_for_mtlsin__init__, but previously dropped several of those arguments instead of forwarding them to the base transport or applying them consistently withGrpcTransport:credentials_file,scopes, andquota_project_idin REST transports:<Service>RestTransport.__init__and_Base<Service>RestTransport.__init__now passcredentials_file,scopes, andquota_project_idthroughsuper().__init__(...)to<Service>Transport.__init__(resolving theTODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.inrest.py.j2), so Application Default Credentials (google.auth.default) and file-loaded credentials (google.auth.load_credentials_from_file) receivequota_project_idandscopesundertransport="rest"just liketransport="grpc".scopesandquota_project_idto explicitcredentialsinbase.py.j2: When explicitcredentialsare passed to<Service>Transport,ga_credentials.with_scopes_if_required(credentials, scopes=scopes, default_scopes=self.AUTH_SCOPES)andcredentials.with_quota_project(quota_project_id)(whenisinstance(credentials, ga_credentials.CredentialsWithQuotaProject)) are now applied in the base transport, matchinggoogle.api_core.grpc_helpers._create_composite_credentials.client_cert_source_for_mtlstoOperationsRestTransport:<Service>RestTransportnow storesself._client_cert_source_for_mtls = client_cert_source_for_mtlsand passes it tooperations_v1.OperationsRestTransport(...)when constructingoperations_client.packages/gapic-generator/tests/unit/generator/test_rest_transport_auth.py.test_%service.py.j2to include<Service>RestTransportintest_<service>_transport_auth_adcand addedtest_<service>_base_transport_with_credentials.packages/gapic-generator/tests/integration/goldens/.