-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
protoc-gen-openapiv2/options/*.proto
paths don't match package name
#5182
Comments
Hi, thanks for your issue. This sounds like a dupe of #2173, but I appreciate the amount of detail you've added and since stalebot closed the other one (we've since removed stalebot), lets keep this open. I have a few thoughts, but mostly they echo what I said in the original issue - this is a very unfortunate consequence of the original path to these files and the way python creates its imports. We cannot move these files as it would break a lot of existing users. As far as I can tell, the suggested fix hasn't considered the consequences of this breaking change. Am I missing something? I'd be happy to accept any PRs that modify our bazel setup to make this work better for users, but we cannot move the protobuf files, sorry. |
Hi @johanbrandhorst, I understand the concern about not moving the .proto files to avoid breaking existing users. Would it be helpful if I submit a PR that implements a non-breaking solution supporting both paths? The approach would be: Keep existing files where they are I can start with the build system changes first for review if this approach seems viable. Let me know if you’d like me to proceed or if you have any other suggestions. Thanks! |
Does git even support symbolic links? I don't know if that would work at all. If we can come up with some solution that helps users I'd be happy to consider it though. Please feel free to experiment. |
I'd say that #2173 (and also #4407, and probably others) are symptoms of the same underlying issue, and would be fixed if the directory structure matched the package names. I think the path of the Golang package could stay as There's a reason there's linter rules for this. 😉
Unfortunately, I don't think that would help me, because I'm not currently using Bazel, and I don't want to add it as a build dependency. Just looking at Python, Bazel does not (cleanly) integrate as PEP-517 build frontend. Because my
Yes. It even works on Windows now, but requires some manual configuration. However, some other tooling may exclude symbolic links – eg:
If Bazel is the intended build tool for
Eventually, |
I'll just reiterate that we will not be able to change the folder structure without breaking users, certainly many more than the number of python users it would help. Any resolution here would have to be backwards compatible. Please do experiment and make practical proposals if we can find a solution though. |
I agree not that breaking existing users is important, but it's not clear to me who would be broken by such a change. I will need your help to identify them. 😄 The use cases I can think of:
Python is not the only Protobuf supported language which does not allow
But doesn't affect:
I couldn't figure out if it affected Ruby or not, but it seems like a pretty common restriction. Protobuf has special attributes in some cases (eg: I acknowledge that fixing the bug comes with risks and a migration cost, but that doesn't prevent it from working where it already works today, and opens it up to a much larger ecosystem. There is a lint for this, it's just unfortunate the original author dismissed it because Golang does not have namespaces. I think the approach proposed is on the right track, it could just use a couple of tweaks. I worry that the fear of breaking things will lead to inaction. 😅 |
Unfortunately, I've found a flaw in in using symlinks as a compatibility measure: Using @rohitlohar45's approach as an example, you'd end up with this folder structure:
If you left
You would build Golang descriptors for protoc --proto_path=. --go_out=. --go_opt=paths=source_relative protoc-gen-openapiv2/options/*.proto And that would be fine. But if you tried to build descriptors using protoc --proto_path=proto --go_out=out --go_opt=paths=source_relative proto/grpc/gateway/protoc_gen_openapiv2/options/*.proto Then If you switched it around (like I previously suggested) and made AlternativesThere's a few ways around this, but they all have drawbacks:
What do you think? 😄 |
Thank you for exploring the alternatives, however, I feel that we sort of skipped over one of the solutions that already exists today - the buf schema registry. We push the descriptors to the schema registry, which make them a first party source for others to depend on them. Why isn't that good enough? The 10/hr BSR rate limits applies to anonymous requests only, it's 960/hr for authenticated requests: https://buf.build/docs/bsr/rate-limits. Is this not good enough? |
I’ve previously evaluated using a Buf-based toolchain for my project, and hit those rate limits extremely easily. Passing build secrets to Docker is tedious (I know how), and also very easy to end up with them baked into your final images. Setting up bot accounts (which I’d need for CI) are locked behind a Pro/Enterprise subscription, and it looks like they only support using static API keys, which I’d need to store as secrets, and copy to every repository which uses Buf. Shared secrets like that are really unsafe, and I’d rather use OIDC delegated identities – and it looks like while Buf supports OIDC (on Pro plans), it’s only for humans. I could possibly setup a caching BSR proxy with some credentials, but that’s infrastructure to roll out and maintain. Compare this with something like Docker, where the Docker Hub rate limits are difficult to hit, they have higher rate limits when fetching “blessed” open source projects (which if BSR did something similar, I’d expect it to qualify), and GitLab has a built-in dependency proxy. And Docker ships a lot more data around. Using Buf doesn’t really solve the problem though, because even if I fetched the I don’t see what value there is in using BSR vs. using a plain What I’ve done at the moment is copied the files into a repository with the patches applied (and a Python package which builds out of the box with entirely native build tools, thanks to |
OK so the alternative of having something like an auto-syncing downstream repository might be the easiest thing then. It wouldn't necessarily need to be associated with the grpc-gateway itself, but we could link to it in this issue and the README. Do you already have a script to set something like this up? |
🐛 Bug Report
protoc-gen-openapiv2
's Protobuf annotations file paths don't match the package name (protoc-gen-openapiv2/options/*.proto
vsgrpc.gateway.protoc_gen_openapiv2.options
).The present behaviour conflicts with the Protobuf style guide (emphasis added):
This also would have been flagged by the Buf lint rules
PACKAGE_DIRECTORY_MATCH
andPACKAGE_LOWER_SNAKE_CASE
, but this project currently disables them in itsbuf.yaml
.Background / expected behaviour
As an example, the
google.api
andgoogle.protobuf
types are ingoogle/api/*.proto
andgoogle/protobuf/*.proto
respectively, and can be used in your own descriptors with:The
.proto
file paths are consistent with their package names, and it's possible to ship.proto
files along side other built artefacts in Java, JavaScript, Python and probably some other languages.It's also possible to reflect these annotations at runtime from your application code.
protoc-gen-openapiv2
annotations should be usable in the same way, with animport
that matches the complete package name:But this is not possible due to this inconsistency.
Existing behaviour
protoc
requires that allimport
s and types resolve properly, including annotations, when generating either client or server-side stubs, even they are never referenced at run-time. This also constrainsprotoc-gen-openapiv2
's annotations to the intersection of all language-specific Protobuf rules, not just Golang's.Some tooling (like
hatch-protobuf
) will recursively enumerate all.proto
files in a directory and attempt to build stubs, with no way to selectively include/exclude files. When applied to this repository, this means including a bunch of examples and internal implementation details.The existing behaviour forces downstream consumers to keep a locally-modified copy of the descriptors with corrected
import
s and folder layout. However, this risks version skew, and all downstream consumers need to apply similar fixes.Suggested fixes
Move
annotations.proto
andopenapiv2.proto
into a new directory:protoc-gen-openapiv2/proto/grpc/gateway/protoc_gen_openapiv2/options/
Make
annotations.proto
's animport
ofopenapiv2.proto
relative to//
, rather than//grpc/gateway
Re-enable
PACKAGE_DIRECTORY_MATCH
andPACKAGE_LOWER_SNAKE_CASE
buf
linter rules forannotations.proto
andopenapiv2.proto
.This makes everything consistent with the defined
package
name, and also means the file paths use hyphens, rather than underscores (which is nice for Java, Python, Rust and probably others).This also makes it possible to include
grpc-gateway
as agit
submodule, and have a--proto_path
flag likethird_party/grpc-gateway/protoc-gen-openapiv2/proto/
, and only pick up the publicprotoc-gen-openapiv2
Protobuf descriptors.It would also make it easier to make a regular Python package with something like
hatch-protobuf
, and take advantage of consistent import paths between Python andprotoc
, like you can withgoogleapis-common-protos
and basegoogle.protobuf
types.Alternatives considered
Using
buf
's schema registry to pull inprotoc-gen-openapiv2
descriptors side-steps the path issues, but has a very low rate limit (10 requests/hour).I'm aware of the
py_protoc_gen_openapiv2
package – but I don't like the approach as it buildsbuf
from source (so depends on a Golang toolchain), it doesn't include.proto
files as artefacts that other tooling can use, and its releases don't match withgrpc-gateway
versions. There are other forks which usebuf
in different ways, but they all have similar problems.I've got an alternative local package for Python which has corrected import paths and don't depend on any of the
buf
tooling, and it's just apyproject.toml
file that useshatch-protobuf
– there's no need to manually installprotoc
(asgrpc-tools
includesprotoc
), and everything just works.The text was updated successfully, but these errors were encountered: