Skip to content

fix(gapic-generator): forward quota_project_id, scopes, credentials_file and mTLS in REST transport - #18892

Open
kmelnikov wants to merge 1 commit into
googleapis:mainfrom
kmelnikov:fix/rest-transport-auth-mtls
Open

kmelnikov wants to merge 1 commit into
googleapis:mainfrom
kmelnikov:fix/rest-transport-auth-mtls

Conversation

@kmelnikov

Copy link
Copy Markdown

Summary

Generated REST transports (<Service>RestTransport) accept credentials_file, scopes, quota_project_id, and client_cert_source_for_mtls in __init__, but previously dropped several of those arguments instead of forwarding them to the base transport or applying them consistently with GrpcTransport:

  1. Forward credentials_file, scopes, and quota_project_id in REST transports: <Service>RestTransport.__init__ and _Base<Service>RestTransport.__init__ now pass credentials_file, scopes, and quota_project_id through super().__init__(...) to <Service>Transport.__init__ (resolving the TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc. in rest.py.j2), so Application Default Credentials (google.auth.default) and file-loaded credentials (google.auth.load_credentials_from_file) receive quota_project_id and scopes under transport="rest" just like transport="grpc".
  2. Apply scopes and quota_project_id to explicit credentials in base.py.j2: When explicit credentials are passed to <Service>Transport, ga_credentials.with_scopes_if_required(credentials, scopes=scopes, default_scopes=self.AUTH_SCOPES) and credentials.with_quota_project(quota_project_id) (when isinstance(credentials, ga_credentials.CredentialsWithQuotaProject)) are now applied in the base transport, matching google.api_core.grpc_helpers._create_composite_credentials.
  3. Forward client_cert_source_for_mtls to OperationsRestTransport: <Service>RestTransport now stores self._client_cert_source_for_mtls = client_cert_source_for_mtls and passes it to operations_v1.OperationsRestTransport(...) when constructing operations_client.
  4. Tests & Goldens:
    • Added unit tests in packages/gapic-generator/tests/unit/generator/test_rest_transport_auth.py.
    • Updated test_%service.py.j2 to include <Service>RestTransport in test_<service>_transport_auth_adc and added test_<service>_base_transport_with_credentials.
    • Updated the integration golden files in packages/gapic-generator/tests/integration/goldens/.

…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.
@kmelnikov
kmelnikov requested a review from a team as a code owner October 28, 2026 21:32

@gemini-code-assist 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.

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.

Comment on lines +155 to +158
if quota_project_id and isinstance(
credentials, ga_credentials.CredentialsWithQuotaProject
):
credentials = credentials.with_quota_project(quota_project_id)

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.

high

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
            ):

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.

This branch has not been deployed

No deployments
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.

1 participant