so1n / protobuf_to_pydantic Goto Github PK
View Code? Open in Web Editor NEWGenerate a pydantic.BaseModel with parameter verification function from the Python Message object(by the Protobuf file).
License: Apache License 2.0
Generate a pydantic.BaseModel with parameter verification function from the Python Message object(by the Protobuf file).
License: Apache License 2.0
python -m grpc_tools.protoc -I. --protobuf-to-pydantic_out=. proxy.proto
Traceback (most recent call last):
File "/Users/wangmingli/.local/share/virtualenvs/pythonProject3-USoLf3Xu/bin/protoc-gen-protobuf-to-pydantic", line 5, in
from protobuf_to_pydantic.plugin.main import main
File "/Users/wangmingli/.local/share/virtualenvs/pythonProject3-USoLf3Xu/lib/python3.8/site-packages/protobuf_to_pydantic/plugin/main.py", line 13, in
from mypy_protobuf.main import Descriptors, code_generation
ModuleNotFoundError: No module named 'mypy_protobuf'
--protobuf-to-pydantic_out: protoc-gen-protobuf-to-pydantic: Plugin failed with status code 1.
(pythonProject3) (base) wangmingli@wangminglidemac pythonProject3 % python -m grpc_tools.protoc -I. --protobuf-to-pydantic_out=. proxy.proto
Traceback (most recent call last):
File "/Users/wangmingli/.local/share/virtualenvs/pythonProject3-USoLf3Xu/bin/protoc-gen-protobuf-to-pydantic", line 5, in
from protobuf_to_pydantic.plugin.main import main
File "/Users/wangmingli/.local/share/virtualenvs/pythonProject3-USoLf3Xu/lib/python3.8/site-packages/protobuf_to_pydantic/plugin/main.py", line 13, in
from mypy_protobuf.main import Descriptors, code_generation
ModuleNotFoundError: No module named 'mypy_protobuf'
--protobuf-to-pydantic_out: protoc-gen-protobuf-to-pydantic: Plugin failed with status code 1.
(pythonProject3) (base) wangmingli@wangminglidemac pythonProject3 % python -m grpc_tools.protoc -I. --protobuf-to-pydantic_out=config_path=plugin_config.py:. proxy.proto
Traceback (most recent call last):
File "/Users/wangmingli/.local/share/virtualenvs/pythonProject3-USoLf3Xu/bin/protoc-gen-protobuf-to-pydantic", line 5, in
from protobuf_to_pydantic.plugin.main import main
File "/Users/wangmingli/.local/share/virtualenvs/pythonProject3-USoLf3Xu/lib/python3.8/site-packages/protobuf_to_pydantic/plugin/main.py", line 13, in
from mypy_protobuf.main import Descriptors, code_generation
ModuleNotFoundError: No module named 'mypy_protobuf'
--protobuf-to-pydantic_out: protoc-gen-protobuf-to-pydantic: Plugin failed with status code 1.
Is your feature request related to a problem? Please describe.
I got an error when using the plugin, I was on latest protoc
at the time:
TypeError: Descriptors cannot not be created directly.
If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0.
If you cannot immediately regenerate your protos, some other possible workarounds are:
1. Downgrade the protobuf package to 3.20.x or lower.
2. Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and will be much slower).
Describe the solution you'd like
protoc > 3.19
support
Describe alternatives you've considered
Downgrade.
Is your feature request related to a problem? Please describe.
I would like to use FieldMask, but I have an error when I try to do so:
syntax = "proto3";
package chat;
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "validate.proto";
...
message ChatUpdate {
optional string name = 1;
optional bool is_group = 2;
optional bool is_personal_assistant = 3;
optional string starred_at = 4;
optional google.protobuf.FieldMask field_mask = 100;
}
When I try to convert my protos, I get this:
docker run --rm -it -v `pwd`:/data --workdir /data naas-models-builder:latest python3 -m grpc_tools.protoc \
-I=protos \
-I=/usr/local/include/include/google/protobuf \
-I=lib/protoc-gen-validate/validate \
--protobuf-to-pydantic_out=python/naas_models/pydantic \
--python_out=python/naas_models \
--go_out=go \
--validate_out="lang=go:go" \
space.proto registry.proto iam.proto aimodel.proto chat.proto credit.proto secret.proto workspace.proto validate.proto
iam.proto:7:1: warning: Import validate.proto is unused.
chat.proto:9:1: warning: Import google/protobuf/struct.proto is unused.
credit.proto:7:1: warning: Import validate.proto is unused.
secret.proto:7:1: warning: Import validate.proto is unused.
parse command-line error:not enough values to unpack (expected 2, got 1)
Writing protobuf-to-pydantic code to space_p2p.py
Writing protobuf-to-pydantic code to registry_p2p.py
Writing protobuf-to-pydantic code to iam_p2p.py
Writing protobuf-to-pydantic code to aimodel_p2p.py
Not support type .google.protobuf.FieldMask
Traceback (most recent call last):
File "/usr/local/bin/protoc-gen-protobuf-to-pydantic", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.10/dist-packages/protobuf_to_pydantic/plugin/main.py", line 67, in main
generate_pydantic_model(Descriptors(request), response, parse_param(request))
File "/usr/local/lib/python3.10/dist-packages/protobuf_to_pydantic/plugin/main.py", line 32, in generate_pydantic_model
file.content = config.file_descriptor_proto_to_code(fd=fd, descriptors=descriptors, config=config).content
File "/usr/local/lib/python3.10/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 53, in __init__
self._parse_field_descriptor()
File "/usr/local/lib/python3.10/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 396, in _parse_field_descriptor
self._content_deque.append(self._message(desc, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER]))
File "/usr/local/lib/python3.10/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 309, in _message
if field.type == 11 and self._get_protobuf_type_model(field).type_factory is AnyMessage:
File "/usr/local/lib/python3.10/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 379, in _get_protobuf_type_model
return ProtobufTypeModel(
File "/usr/local/lib/python3.10/dist-packages/pydantic/main.py", line 341, in __init__
raise validation_error
pydantic.error_wrappers.ValidationError: 1 validation error for ProtobufTypeModel
rule_type_str
none is not an allowed value (type=type_error.none.not_allowed)
--protobuf-to-pydantic_out: protoc-gen-protobuf-to-pydantic: Plugin failed with status code 1.
make: *** [generate] Error 1
Describe the solution you'd like
I would just like the FieldMask to work by default.
Describe alternatives you've considered
I considered created my own version of the FieldMask
message but I would like to avoid this:
message FieldMask {
// The set of field mask paths.
repeated string paths = 1;
}
message ChatUpdate {
optional string name = 1;
optional bool is_group = 2;
optional bool is_personal_assistant = 3;
optional string starred_at = 4;
FieldMask field_mask = 100;
}
Describe the bug
When generating pydantic models for the mapbox tile definition,
the following errors occur in the resulting model:
To Reproduce
Steps to reproduce the behavior:
python -m grpc_tools.protoc -I. --protobuf-to-pydantic_out=. vector_tile.proto
The repo located here reconstructs the scenario.
Expected behavior
Actual behaviour
The following file is generated.
# This is an automatically generated file, please do not change
# gen by protobuf_to_pydantic[v0.2.5](https://github.com/so1n/protobuf_to_pydantic)
# Protobuf Version: 4.25.3
# Pydantic Version: 2.6.3
from enum import IntEnum
from google.protobuf.message import Message # type: ignore
from pydantic import BaseModel
from pydantic import Field
import typing
class Feature(BaseModel):
id: int = Field(default=0)
tags: typing.List[int] = Field(default_factory=list)
type: GeomType = Field(default=0)
geometry: typing.List[int] = Field(default_factory=list)
class Value(BaseModel):
string_value: str = Field(default="")
float_value: float = Field(default=0.0)
double_value: float = Field(default=0.0)
int_value: int = Field(default=0)
uint_value: int = Field(default=0)
sint_value: int = Field(default=0)
bool_value: bool = Field(default=False)
class Tile(BaseModel):
class Value(BaseModel):
string_value: str = Field(default="")
float_value: float = Field(default=0.0)
double_value: float = Field(default=0.0)
int_value: int = Field(default=0)
uint_value: int = Field(default=0)
sint_value: int = Field(default=0)
bool_value: bool = Field(default=False)
class Feature(BaseModel):
id: int = Field(default=0)
tags: typing.List[int] = Field(default_factory=list)
type: GeomType = Field(default=0)
geometry: typing.List[int] = Field(default_factory=list)
class Layer(BaseModel):
version: int = Field(default=0)
name: str = Field(default="")
features: typing.List[Feature] = Field(default_factory=list)
keys: typing.List[str] = Field(default_factory=list)
values: typing.List[Value] = Field(default_factory=list)
extent: int = Field(default=0)
class GeomType(IntEnum):
UNKNOWN = 0
POINT = 1
LINESTRING = 2
POLYGON = 3
layers: typing.List[Layer] = Field(default_factory=list)
Environment
GRPC proto have all fields optional in messages.
with p2p we can annotate defailt values, title, etc. however is there a way to have no default, i.e. making a field required?
This library generating messages in good format. But no support of generating proto services to python and creating server and client
Describe the bug
Unusable pydantic model is generated.
To Reproduce
Steps to reproduce the behavior:
syntax = "proto3";
message A {
bool a = 1;
}
message B {
bool b = 1;
}
message C {
oneof z {
A a = 1;
B b = 2;
}
optional B c = 3;
}
generates this:
class A(BaseModel):
a: bool = Field(default=False)
class B(BaseModel):
b: bool = Field(default=False)
class C(BaseModel):
_one_of_dict = {"C._c": {"fields": {"c"}}, "C.z": {"fields": {"a", "b"}}}
one_of_validator = model_validator(mode="before")(check_one_of)
a: A = Field()
b: B = Field()
c: typing.Optional[B] = Field(default=None)
Expected behavior
class A(BaseModel):
a: bool = Field(default=False)
class B(BaseModel):
b: bool = Field(default=False)
class C(BaseModel):
_one_of_dict = {"C._c": {"fields": {"c"}}, "C.z": {"fields": {"a", "b"}}}
one_of_validator = model_validator(mode="before")(check_one_of)
a: typing.Optional[A] = Field(default=None)
b: typing.Optional[B] = Field(default=None)
c: typing.Optional[B] = Field(default=None)
Is your feature request related to a problem? Please describe.
I tried to find if there is an easy way to convert objects form one format into another. The easiest I found is using dicts as a intermediate format.
Describe the solution you'd like
<PydanticType>.from_proto(msg: <ProtoType>) -> <PydanticType>
class method and <PydanticType>.to_proto() -> <ProtoType>
method.Describe alternatives you've considered
The dict method: convert proto/pydantic to dict, use that dict with two stars as input.
Describe the bug
Follow up on #22
For certain protobufs, this plugin generates a default and a default_factory in Pydantic which causes an error.
To Reproduce
Steps to reproduce the behavior:
syntax = "proto3";
message A {
optional string a = 2;
repeated string b = 3;
}
Output:
# This is an automatically generated file, please do not change
# gen by protobuf_to_pydantic[v0.2.0.1](https://github.com/so1n/protobuf_to_pydantic)
# Protobuf Version: 4.24.3
# Pydantic Version: 1.10.12
from google.protobuf.message import Message # type: ignore
from pydantic import BaseModel
from pydantic import Field
import typing
class A(BaseModel):
a: typing.Optional[str] = Field(default="")
b: typing.Optional[typing.List[str]] = Field(default_factory=list, default=None)
Expected behavior
It should only generate the default factory list for repeated
and not default=None
.
Describe the bug
Using google.protobuf.DoubleValue
from wrappers import "google/protobuf/wrappers.proto";
does not seem to work
To Reproduce
Steps to reproduce the behavior:
Create a .proto
with DoubleValue
e.g.
syntax = "proto3";
import "google/protobuf/wrappers.proto";
message CalculatedValue {
// p2p: {"type": "p2p@builtin|float"}
google.protobuf.DoubleValue myValue = 1;
}
It tries to get google.protobuf.double_value_pb2
, which is not from wrappers
Error: No module named 'google.protobuf.double_value_pb2'
Full Error:
ERROR:protobuf_to_pydantic.plugin.main:No module named 'google.protobuf.double_value_pb2'
Traceback (most recent call last):
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/main.py", line 14, in main
CodeGen(ConfigModel)
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/code_gen.py", line 32, in __init__
self.generate_pydantic_model(Descriptors(request), response)
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/code_gen.py", line 136, in generate_pydantic_model
file.content = self.config.file_descriptor_proto_to_code(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 73, in __init__
self._parse_field_descriptor()
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 631, in _parse_field_descriptor
self._content_deque.append(self._message(desc, desc, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 484, in _message
_content_tuple: Optional[Tuple[str, str]] = self._message_field_handle(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 198, in _message_field_handle
self._message(message, root_desc, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER])
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 481, in _message
if field.type == 11 and self._get_protobuf_type_model(field).use_custom_type:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/build-env-h9195zep/lib/python3.11/site-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 604, in _get_protobuf_type_model
type_factory = getattr(importlib.import_module(type_module_name), _type_str)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/bb/lib/python3.11/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
Expected behavior
Expect it to work
[DELETED]
Both files (README.md and README_ZH.md) contain a typo in some of the words "pydantic". In some places it says "pydanitc":
the command
python -m pip install protobuf-to-pydanitc[mypy-protobuf]
.
indicates the use of the
prorobuf-to-pydanitc
plugin
Describe the bug
The generated code does not pass mypy checks, as the field line is generated as
id: int = FieldInfo(default=0)
instead of
id: int = Field(default=0)
λ mypy protobuf_p2p.py
protobuf_p2p.py:8: error: Incompatible types in assignment (expression has type "FieldInfo", variable has type "int") [assignment]
protobuf_p2p.py:9: error: Incompatible types in assignment (expression has type "FieldInfo", variable has type "int") [assignment]
Found 2 errors in 1 file (checked 1 source file)
Expected behavior
The resulting file is mypy clean
ideas
I tried outputting Fields
instead of FieldInfo
in the two lines below and for my usecase, that was fine.
protobuf_to_pydantic/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py
Lines 269 to 270 in 8c7adf6
But I guess there might be content which does not fit into a Field
, but only into a FieldInfo
?
The other idea how to fix this would be to add a # type: ignore[assignment]
(specific, because otherwise ruff complains...) in the generated field code:
protobuf_to_pydantic/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py
Lines 278 to 281 in 8c7adf6
- " " * (self.code_indent + indent) + f"{field.name}: {type_str} = {field_name}({field_info_str})\n"
+ " " * (self.code_indent + indent) + f"{field.name}: {type_str} = {field_name}({field_info_str}) # type: ignore[assignment]\n"
relevant mypy config
I use the pydantic mypy plugin:
[tool.mypy]
plugins = [
# Better support for pydantic models
"pydantic.mypy"
]
Describe the bug
The following (shortend) proto file creates a non-valid pydantic python file:
syntax = "proto3";
package whatever.v1;
message Blub {
int64 whatever = 1;
}
message CheckCreateCommitFromPreparationResponse {
optional Blub blib = 1;
}
Converting with protobuf-to-pydantic gives this
# This is an automatically generated file, please do not change
# gen by protobuf_to_pydantic[v0.2.3](https://github.com/so1n/protobuf_to_pydantic)
# Protobuf Version: 4.25.2
# Pydantic Version: 2.6.1
from google.protobuf.message import Message # type: ignore
from pydantic import BaseModel
from pydantic import Field
class Blub(BaseModel):
whatever: int = Field(default=0)
class CheckCreateCommitFromPreparationResponse(BaseModel):
blib: typing.Optional[Blub] = Field(default=None)
Which misses the import for typing and therefore the last lines errors on import.
To Reproduce
Steps to reproduce the behavior:
NameError: name 'typing' is not defined. Did you forget to import 'typing'
Expected behavior
There is a typing import in the generated file and I can import the generated file without an error
Adding protobuf>=5
together with the latest protobuf-to-pydantic
to a python project clashes, as dependecy constraints are contradicting.
Because no versions of grpcio-tools match >1.40.0,<1.41.0 || >1.41.0,<1.41.1 || >1.41.1,<1.42.0 || >1.42.0,<1.43.0 || >1.43.0,<1.44.0 || >1.44.0,<1.45.0 || >1.45.0,<1.46.0 || >1.46.0,<1.46.1 || >1.46.1,<1.46.3 || >1.46.3,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.0rc1 || >1.54.0rc1,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.0rc2 || >1.56.0rc2,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0
and grpcio-tools (1.54.0rc1) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>1.40.0,<1.41.0 || >1.41.0,<1.41.1 || >1.41.1,<1.42.0 || >1.42.0,<1.43.0 || >1.43.0,<1.44.0 || >1.44.0,<1.45.0 || >1.45.0,<1.46.0 || >1.46.0,<1.46.1 || >1.46.1,<1.46.3 || >1.46.3,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.0rc2 || >1.56.0rc2,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=4.21.6,<5.0dev).
And because grpcio-tools (1.56.0rc2) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>1.40.0,<1.41.0 || >1.41.0,<1.41.1 || >1.41.1,<1.42.0 || >1.42.0,<1.43.0 || >1.43.0,<1.44.0 || >1.44.0,<1.45.0 || >1.45.0,<1.46.0 || >1.46.0,<1.46.1 || >1.46.1,<1.46.3 || >1.46.3,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=4.21.6,<5.0dev).
And because grpcio-tools (1.40.0) depends on protobuf (>=3.5.0.post1,<4.0dev)
and grpcio-tools (1.41.0) depends on protobuf (>=3.5.0.post1,<4.0dev), grpcio-tools (>=1.40.0,<1.41.1 || >1.41.1,<1.42.0 || >1.42.0,<1.43.0 || >1.43.0,<1.44.0 || >1.44.0,<1.45.0 || >1.45.0,<1.46.0 || >1.46.0,<1.46.1 || >1.46.1,<1.46.3 || >1.46.3,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.41.1) depends on protobuf (>=3.5.0.post1,<4.0dev)
and grpcio-tools (1.42.0) depends on protobuf (>=3.5.0.post1,<4.0dev), grpcio-tools (>=1.40.0,<1.43.0 || >1.43.0,<1.44.0 || >1.44.0,<1.45.0 || >1.45.0,<1.46.0 || >1.46.0,<1.46.1 || >1.46.1,<1.46.3 || >1.46.3,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.43.0) depends on protobuf (>=3.5.0.post1,<4.0dev)
and grpcio-tools (1.44.0) depends on protobuf (>=3.5.0.post1,<4.0dev), grpcio-tools (>=1.40.0,<1.45.0 || >1.45.0,<1.46.0 || >1.46.0,<1.46.1 || >1.46.1,<1.46.3 || >1.46.3,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.45.0) depends on protobuf (>=3.5.0.post1,<4.0dev)
and grpcio-tools (1.46.0) depends on protobuf (>=3.12.0,<4.0dev), grpcio-tools (>=1.40.0,<1.46.1 || >1.46.1,<1.46.3 || >1.46.3,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.46.1) depends on protobuf (>=3.12.0,<4.0dev)
and grpcio-tools (1.46.3) depends on protobuf (>=3.12.0,<4.0dev), grpcio-tools (>=1.40.0,<1.46.5 || >1.46.5,<1.47.0 || >1.47.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.46.5) depends on protobuf (>=3.12.0,<4.0dev)
and grpcio-tools (1.47.0) depends on protobuf (>=3.12.0,<4.0dev), grpcio-tools (>=1.40.0,<1.47.2 || >1.47.2,<1.47.5 || >1.47.5,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.47.2) depends on protobuf (>=3.12.0,<4.0dev)
and grpcio-tools (1.47.5) depends on protobuf (>=3.12.0,<4.0dev), grpcio-tools (>=1.40.0,<1.48.0 || >1.48.0,<1.48.1 || >1.48.1,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.48.0) depends on protobuf (>=3.12.0,<4.0dev)
and grpcio-tools (1.48.1) depends on protobuf (>=3.12.0,<4.0dev), grpcio-tools (>=1.40.0,<1.48.2 || >1.48.2,<1.49.0 || >1.49.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.6,<5.0dev).
And because grpcio-tools (1.48.2) depends on protobuf (>=3.12.0,<4.0dev)
and grpcio-tools (1.49.0) depends on protobuf (>=4.21.3,<5.0dev), grpcio-tools (>=1.40.0,<1.49.1 || >1.49.1,<1.50.0 || >1.50.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.49.1) depends on protobuf (>=4.21.3,<5.0dev)
and grpcio-tools (1.50.0) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.51.0 || >1.51.0,<1.51.1 || >1.51.1,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.51.0) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.51.1) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.51.3 || >1.51.3,<1.52.0 || >1.52.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.51.3) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.52.0) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.53.0 || >1.53.0,<1.53.1 || >1.53.1,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.53.0) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.53.1) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.53.2 || >1.53.2,<1.54.3 || >1.54.3,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.53.2) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.54.3) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.55.0 || >1.55.0,<1.55.3 || >1.55.3,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.55.0) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.55.3) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.56.2 || >1.56.2,<1.57.0 || >1.57.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.56.2) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.57.0) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.58.0 || >1.58.0,<1.59.0 || >1.59.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.58.0) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.59.0) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.59.2 || >1.59.2,<1.59.3 || >1.59.3,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.59.2) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.59.3) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.60.0 || >1.60.0,<1.60.1 || >1.60.1,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.60.0) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.60.1) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<1.62.0 || >1.62.0,<1.62.1 || >1.62.1,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
And because grpcio-tools (1.62.0) depends on protobuf (>=4.21.6,<5.0dev)
and grpcio-tools (1.62.1) depends on protobuf (>=4.21.6,<5.0dev), grpcio-tools (>=1.40.0,<2.0.0) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
Because no versions of protobuf-to-pydantic match >0.2.6
and protobuf-to-pydantic[mypy-protobuf] (0.2.6) depends on grpcio-tools (>=1.40.0,<2.0.0), protobuf-to-pydantic[mypy-protobuf] (>=0.2.6) requires grpcio-tools (>=1.40.0,<2.0.0).
Thus, protobuf-to-pydantic[mypy-protobuf] (>=0.2.6) requires protobuf (>=3.5.0.post1,<4.0dev || >=4.21.3,<5.0dev).
So, because mds-schema depends on both protobuf (>=5) and protobuf-to-pydantic[mypy-protobuf] (>=0.2.6), version solving failed.
Describe the bug
Seems the buf registry plugin doesn't exist.
To Reproduce
- plugin: buf.build/python-pai/protobuf-to-pydantic:v0.2.1
opt:
- plugin_config_py_code_base64=aW1wb3J0IGxvZ2dpbmcKCmxvZ2dpbmcuYmFzaWNDb25maWcoZm9ybWF0PSJbJShhc2N0aW1lKXMgJShsZXZlbG5hbWUpc10gJShtZXNzYWdlKXMiLCBkYXRlZm10PSIleS0lbS0lZCAlSDolTTolUyIsIGxldmVsPWxvZ2dpbmcuSU5GTykKCgpkZWYgZGVmYXVsdF9mdW5jKCkgLT4gaW50OgogICAgcmV0dXJuIDEKCmxvY2FsX2RpY3QgPSB7CiAgICAiZGVmYXVsdF9mdW5jIjogZGVmYXVsdF9mdW5jLAp9Cg
- plugin_config_module_name=plugin_config
Failure: plugin "buf.build/python-pai/protobuf-to-pydantic" was not found
Describe the bug
After update proto in #2 , I tried to parse my proto, and I get this error
Error Log
maximum recursion depth exceeded in instancecheck
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/main.py", line 12, in main
CodeGen(ConfigModel)
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/code_gen.py", line 30, in init
self.generate_pydantic_model(Descriptors(request), response)
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/code_gen.py", line 82, in generate_pydantic_model
file.content = self.config.file_descriptor_proto_to_code(
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 57, in init
self._parse_field_descriptor()
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 405, in _parse_field_descriptor
self._content_deque.append(self._message(desc, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER]))
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 321, in _message
_content_tuple: Optional[Tuple[str, str]] = self._message_field_handle(
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 168, in _message_field_handle
self._content_deque.append(self._message(message, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER]))
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 321, in _message
_content_tuple: Optional[Tuple[str, str]] = self._message_field_handle(
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 168, in _message_field_handle
self._content_deque.append(self._message(message, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER]))
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 321, in _message
_content_tuple: Optional[Tuple[str, str]] = self._message_field_handle(
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 168, in _message_field_handle
self._content_deque.append(self._message(message, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER]))
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 321, in _message
_content_tuple: Optional[Tuple[str, str]] = self._message_field_handle(......
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 168, in _message_field_handle
self._content_deque.append(self._message(message, [FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER]))
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 321, in _message
_content_tuple: Optional[Tuple[str, str]] = self._message_field_handle(
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 183, in _message_field_handle
protobuf_type_model = self._get_protobuf_type_model(field)
File "/usr/local/lib/python3.9/dist-packages/protobuf_to_pydantic/plugin/field_desc_proto_to_code.py", line 359, in _get_protobuf_type_model
return ProtobufTypeModel(
File "pydantic/main.py", line 339, in pydantic.main.BaseModel.init
File "pydantic/main.py", line 1076, in pydantic.main.validate_model
File "pydantic/fields.py", line 884, in pydantic.fields.ModelField.validate
File "pydantic/fields.py", line 1101, in pydantic.fields.ModelField._validate_singleton
File "pydantic/fields.py", line 1151, in pydantic.fields.ModelField._apply_validators
File "pydantic/class_validators.py", line 337, in pydantic.class_validators._generic_validator_basic.lambda13
File "pydantic/validators.py", line 61, in pydantic.validators.str_validator
RecursionError: maximum recursion depth exceeded in instancecheck
Is your feature request related to a problem? Please describe.
When message is empty, the generated code is empty after class.
message Empty{}
message Something {
string s = 1;
}
Generated code is like
class Empty(BaseModel):
class Something(BaseModel):
s : ...
Describe the solution you'd like
Add pass
statement to generated class if the message body is empty
Describe the bug
There is a typo in the readme. It says prorobuf_to_pydantic
instead of protobuf-to-pydantic
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The text should read protobuf-to-pydantic
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
N/A
Is your feature request related to a problem? Please describe.
Our team is using the buf cli to manage protobuf builds because
managing protoc
calls can be clunky.
Describe the solution you'd like
I'd like this plugin integrated with the CodeGeneratorRequest so that a Dockerfile can be implemented that will allow a custom plugin to be implemented.
Additionally, this will facilitate adoption by Buf to make it a hosted plugin, which will likely increase adoption of this plugin.
Describe alternatives you've considered
The alternative is to use the CLI as documented. However, buf generate
is a much friendlier interface to using this.
Additional context
bufbuild/plugins#589
The current step of converting BaseModel
to Protobuf Message
is tedious and has poor performance. e.g:
from google.protobuf.json_format import ParseDict
from pydantic import BaseModel
from demo_pb2 import DemoMessage
class Demo(BaseModel):
pass
ParseDict(Demo().dict(), DemoMessage())
Serialization can be optimized in the following ways:
1.Convert directly to Message:
from protobuf_to_pydantic.p2p_model import P2PBaseModel
class Demo(P2PBaseModel):
pass
Demo().to_message()
2.Serialized to dict, then converted to Message by the developer (pydantic/pydantic#1409 (comment))
from google.protobuf.json_format import ParseDict
from pydantic import BaseModel
from demo_pb2 import DemoMessage
class Demo(BaseModel):
pass
DemoMessage(**Demo().dict())
Is your feature request related to a problem? Please describe.
When the field name in *.proto file is PascalCase or camelCase
I want the p2p can convert the field name to snake_case when generate python file.
Describe the solution you'd like
Add some cli option or plugin , so I can given the output filed case.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
Describe the bug
A clear and concise description of what the bug is.
Using proto v3
Marking a field as optional in Proto doesn't seem to change anything in the generated Pydantic model.
To Reproduce
.proto
syntax = "proto3";
message A {
string a = 1;
}
message B {
optional A a = 1;
}
Output:
class A(BaseModel):
a: str = Field(default="")
class B(BaseModel):
a: typing.Optional[A] = Field()
Expected behavior
This is the expected output:
class A(BaseModel):
a: str = Field(default="")
class B(BaseModel):
a: typing.Optional[A] = Field(default=None)
Note that without setting default = None
in Pydantic, it's impossible to construct B()
with no args. You have to construct it via B(a=None)
.
Describe the bug
When we upgraded to pydantic
v2.7.1, there are deprecation warnings surfaced from the customer validator in this package.
The solution should be to replace FieldValidationInfo
with ValidationInfo
.
Further details on the deprecation:
https://docs.pydantic.dev/latest/concepts/validators/#field-validators
Plugin function cannot be used in Windows system
Describe the bug
After udating to the latest pydantic version, I get this:
cd ./build/proto && poetry run python -m grpc_tools.protoc -I. --protobuf-to-pydantic_out=. example_model/v1/classes.proto
/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/grpc_tools/protoc.py:21: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
import pkg_resources
Traceback (most recent call last):
File "/Users/jankatins/projects/project1/.venv/bin/protoc-gen-protobuf-to-pydantic", line 5, in <module>
from protobuf_to_pydantic.plugin.main import main
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/__init__.py", line 2, in <module>
from .gen_code import pydantic_model_to_py_code, pydantic_model_to_py_file
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/gen_code.py", line 33, in <module>
from protobuf_to_pydantic import _pydantic_adapter, customer_validator, gen_model
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/gen_model.py", line 18, in <module>
from protobuf_to_pydantic.get_desc import (
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/get_desc/__init__.py", line 1, in <module>
from .from_pb_option import get_desc_from_p2p, get_desc_from_pgv
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/get_desc/from_pb_option/__init__.py", line 1, in <module>
from .from_p2p import get_desc_from_p2p
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/get_desc/from_pb_option/from_p2p.py", line 5, in <module>
from .base import DescFromOptionTypedDict, ParseFromPbOption
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/get_desc/from_pb_option/base.py", line 7, in <module>
from protobuf_to_pydantic.customer_con_type import (
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/customer_con_type/__init__.py", line 6, in <module>
from .v2 import * # noqa
^^^^^^^^^^^^^^^^^
File "/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/protobuf_to_pydantic/customer_con_type/v2.py", line 6, in <module>
from pydantic._internal._fields import PydanticGeneralMetadata
ImportError: cannot import name 'PydanticGeneralMetadata' from 'pydantic._internal._fields' (/Users/jankatins/projects/project1/.venv/lib/python3.11/site-packages/pydantic/_internal/_fields.py)
--protobuf-to-pydantic_out: protoc-gen-protobuf-to-pydantic: Plugin failed with status code 1.
To Reproduce
Install the following versions:
λ poetry show
...
grpcio 1.59.3 HTTP/2-based RPC framework
grpcio-tools 1.59.3 Protobuf code generator for gRPC
mypy 1.7.1 Optional static typing for Python
mypy-extensions 1.0.0 Type system extensions for programs checked with the mypy type checker.
mypy-protobuf 3.5.0 Generate mypy stub files from protobuf specs
protobuf 4.25.1
protobuf-to-pydantic 0.2.1 Generate the `pydantic.BaseModel` class (and the corresponding source code) with parameter verification function through the Protobuf file
pydantic 2.5.2 Data validation using Python type hints
pydantic-core 2.14.5
types-protobuf 4.24.0.4 Typing stubs for protobuf
Expected behavior
This should work (and it did work with older versions) :-) -> will downgrade pydantic for now...
Thanks for the nice module!
Is your feature request related to a problem? Please describe.
The order of generated pydantic
classes (from python -m grpc_tools.protoc -I. --protobuf-to-pydantic_out=. example.proto
) can cause unresolved references: a class definition comes after its references in other classes.
Describe the solution you'd like
I'm using the following script to reorder generated classes, but it may be better to integrate this step.
import ast
def reorder_classes(source):
tree = ast.parse(source)
# Extract the classes from the AST and sort them topologically
class_nodes = [node for node in tree.body if isinstance(node, ast.ClassDef)]
class_dependencies = {}
for class_node in class_nodes:
class_dependencies[class_node] = {
dep.id for dep in ast.walk(class_node) if
isinstance(dep, ast.Name) and dep.id in [cls.name for cls in class_nodes]
}
sorted_classes = []
while class_dependencies:
acyclic_nodes = [node for node, deps in class_dependencies.items() if not deps]
if not acyclic_nodes:
raise ValueError('Circular dependency found')
for node in acyclic_nodes:
del class_dependencies[node]
sorted_classes.append(node)
for deps in class_dependencies.values():
deps.discard(node.name)
# Rewrite the source code with the sorted classes
sorted_source = '\n\n'.join([ast.unparse(node) for node in sorted_classes])
return sorted_source
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.