Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for reading selective GAPIC generation methods from service YAML #2272

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

gkevinzheng
Copy link
Contributor

This PR implements Selective GAPIC generation for Python. For more details, see:

Overall design doc: go/selective-gapic-generation
Implementation doc for Python: go/selective-gapic-gen-python

@gkevinzheng gkevinzheng requested a review from parthea December 4, 2024 16:07
@gkevinzheng gkevinzheng requested a review from a team as a code owner December 4, 2024 16:07
@product-auto-label product-auto-label bot added the size: xl Pull request size is extra large. label Dec 4, 2024
Copy link

snippet-bot bot commented Dec 4, 2024

Here is the summary of changes.

You are about to delete 12 region tags.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

Copy link
Contributor

@parthea parthea left a comment

Choose a reason for hiding this comment

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

LGTM but holding off on formal approval until tomorrow after the next release is shipped

@parthea
Copy link
Contributor

parthea commented Dec 18, 2024

Requesting review from @vchudnov-g as well

@parthea parthea requested a review from vchudnov-g December 18, 2024 18:22
@parthea parthea changed the title feat: Selective GAPIC phase 1 feat: Add support for reading selective GAPIC generation methods from service YAML Dec 18, 2024
Copy link
Contributor

@vchudnov-g vchudnov-g left a comment

Choose a reason for hiding this comment

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

I think this is looking good, but I have some questions/suggestions. PTAL.

@@ -237,6 +237,69 @@ def disambiguate(self, string: str) -> str:
return self.disambiguate(f'_{string}')
return string

def build_address_allowlist_for_selective_gapic(self, *,
Copy link
Contributor

Choose a reason for hiding this comment

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

In our code base (including comments), I would use a clearer name that "selective GAPIC"; I find it a bit of a misnomer. We're not selecting the GAPIC; we're selecting the RPCs to create a custom (non-standard) GAPIC. So I would have us choose one of selective_generation or custom_gapic and use that as the affix consistently everywhere, instead of selective_gapic.

@@ -237,6 +237,69 @@ def disambiguate(self, string: str) -> str:
return self.disambiguate(f'_{string}')
return string

def build_address_allowlist_for_selective_gapic(self, *,
Copy link
Contributor

Choose a reason for hiding this comment

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

(I've not seen the word address used in this context and I wish we weren't using it, but I see it's prior art already in use. Oh, well)

}

# For messages and enums we should only be pruning them from all_messages if they
# are proto plus types. This should apply to the Protos we are pruning from, but might
Copy link
Contributor

Choose a reason for hiding this comment

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

"but might not in the future."

WDYM? This seems cryptic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are we trying to move away from proto plus types? I'll remove the "in the future part" regardless

gapic/schema/api.py Outdated Show resolved Hide resolved
gapic/schema/api.py Outdated Show resolved Hide resolved

# We only prune services/messages/enums from protos that are not depepdencies.
for name, proto in api.all_protos.items():
if name not in api.protos:
Copy link
Contributor

Choose a reason for hiding this comment

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

What does it mean for a proto to be in api.all_protos but not in api.protos? (I'm not familiar with this part of the codebase)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Definition here:

def protos(self) -> Mapping[str, Proto]:
"""Return a map of all protos specific to this API.
This property excludes imported protos that are dependencies
of this API but not being directly generated.
"""
view = self.subpackage_view
return collections.OrderedDict([
(k, v) for k, v in self.all_protos.items()
if v.file_to_generate and
v.meta.address.subpackage[:len(view)] == view
])

Here I'm trying to prune only the proto objects corresponding to the files in this API package.

gapic/schema/wrappers.py Outdated Show resolved Hide resolved
if self.extended_lro:
# We need to add the service/method pointed to by self.operation_service to
# the allowlist, as it might not have been specified by selective_gapic_generation.
# We assume that the operation service lives in the same proto as this one.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a good assumption? (I honestly don't know.) Will it work with operation mixins?

Copy link
Contributor Author

@gkevinzheng gkevinzheng Dec 20, 2024

Choose a reason for hiding this comment

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

I have to make this assumption, otherwise the lookups won't work. The precedent for this is here where the Proto object is built:

def _maybe_get_extended_lro(
self,
service_address: metadata.Address,
meth_pb: descriptor_pb2.MethodDescriptorProto,
) -> Optional[wrappers.ExtendedOperationInfo]:
op_service_name = meth_pb.options.Extensions[ex_ops_pb2.operation_service]
if not op_service_name:
return None
# Manual lookups because services and methods haven't been loaded.
# Note: this assumes that the operation service lives in the same proto file.
# This is a reasonable assumption as of March '22, but it may (unlikely)
# change in the future.

for method in self.methods.values():
if method.ident.proto in method_names:
# Include this service if there are any types/methods in selective gapic for this service.
address_allowlist.add(self.meta.address)
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this allow-listing this service it it has any methods at all, not just allowlisted ones?

Should the logic be something like this pseudocode?

for method in self.methods.values():
  if method in allowlist:
    allowlist.add(self)
    allowlist.add(method)
    method.build_allowlist() 

Copy link
Contributor Author

Choose a reason for hiding this comment

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

method_names is the allowlist. I'll make that clearer by renaming it to method_allowlist or method_names_allowlist.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at this file, it seems to me that the build_address_allowlist name is descriptive for the method you're adding to the Service class, but the other classes should have their new methods names something like add_to_address_allowlist, to emphasize that they themselves are not checking for the RPC allowlist in the YAML, but are being included transitively. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: xl Pull request size is extra large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants