如何从Protobuf生成Python类文件

18
我正在尝试将大量结构化数据从Java传输到Python。其中包括许多以某种形式相互关联的对象。当我在Python代码中接收它们时,使用protobuf提供的类型非常丑陋。我的VIM IDE在尝试对类型使用自动完成时崩溃了,PyCharm没有任何完整功能,通常它们不提供不同类型的干净类定义似乎很荒谬。
是否有一种方法可以在使用python中的protobuf消息时获得IDE支持?我正在查看20多种处理复杂消息的方法,如果没有IDE支持,我可能会像使用记事本一样编码。

enter image description here

我知道protobuf使用元类(尽管我不知道为什么他们这样做)。也许有一种方法可以从那些数据中生成Python类文件,或者可能有类似于typescript typing files的东西。
我可能误用了protobuf吗?我相信我可以以跨语言的方式描述我的领域模型。在Java中,我很满意生成的类,并且可以轻松地使用它们。我应该使用类似于swagger.io的东西吗?
4个回答

18
如果您使用的是最新版本的Python(3.7+),那么 https://github.com/danielgtaylor/python-betterproto (免责声明:我是作者) 将生成非常干净的Python数据类作为输出,这将为您提供适当的类型和IDE完整支持。
例如,以下是输入:
syntax = "proto3";

package hello;

// Greeting represents a message you can tell a user.
message Greeting {
  string message = 1;
}

将生成以下输出:

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: hello.proto
# plugin: python-betterproto
from dataclasses import dataclass

import betterproto


@dataclass
class Hello(betterproto.Message):
    """Greeting represents a message you can tell a user."""

    message: str = betterproto.string_field(1)

通常,此插件的输出模仿*.proto输入,并且如果您跳转到消息或字段的定义,它非常易于阅读。对我个人来说,这是一个巨大的改进,比官方的Google编译器插件更好,并且支持“async” gRPC开箱即用。


为什么 betterproto 使用自定义字段来代替 Python 内置的 field 来创建数据类? - moshevi
@moshevi 内部实际上是使用 dataclasses.field。这些 field 函数只是快捷方式。请参见 https://github.com/danielgtaylor/python-betterproto/blob/eec24e4ee85c581d5185c258d2ea2cbb4d39be20/betterproto/__init__.py#L175-L180 - Daniel
但这种方式会尝试将代码转换为Protobuf。拥有一个数据访问层,使用技术不可知的Python类型和数据类是有意义的。 - moshevi

3

1
虽然我没有找到解决方案,但我找到了这个可以生成类型提示文件的工具 https://github.com/dropbox/mypy-protobuf - pascalwhoop
@pascalwhoop - mypy-protobuf 能够与 protoc 2.5.0 和 python 2.7.6 兼容吗? - tuk
@tuk 不确定具体的版本,但它对我的项目起作用了。 - pascalwhoop
1
问题已经解决,新的选项是 --pyi_out=。也许你可以更新一下你的答案。我觉得这个比其他的好多了。 - Zaffy

2

mypy-protobuf 生成类型提示文件。但是,正如在这里所讨论的那样,它仅适用于 protobuf 3.0 和 python 2.7 及以上版本。


0

"-Zaffy"所说的对我有用。 (--pyi_out)

示例

注意:Protobuf文件名示例=addressbook.proto

创建智能感知信息的CLI命令(在此相同目录中编译)

protoc -I . --pyi_out=. addressbook.proto

接着创建 Python 代码。(在同一目录下编译)

protoc -I . --python_out=. addressbook.proto

这将创建一个 addressbook_pb2.py 和 addressbook_pb2.pyi 文件

然后开始使用 VS Code 吧!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接