Python gRPC Protobuf 生成文件提示找不到模块
背景
最近学习抽空学习gRPC,准备为后面项目的需求提前做好预研,主要是Java与Python的交互,所以就打算使用gRPC来实现这个功能,在学习过程中遇到了这个问题,在此记录一下,避免过段时间就忘了。
项目结构
1 | pygrpc |
生成命令
1 | python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. ./helloworld.proto |
1 | /home/charles/miniconda3/bin/conda run -n py_grpc --no-capture-output python /mnt/d/Program Files/JetBrains/PyCharm 2022.2.1/plugins/python/helpers/pydev/pydevd.py --multiprocess --qt-support=auto --client 127.0.0.1 --port 41177 --file /mnt/d/PycharmProjects/pygrpc/client/greeter_client.py |
报错分析
由于*_pb2_grpc.py会使用*_pb2.py中定义的各种类型,因此两者之间存在import关系,而问题恰恰出在这个import上。
注意我使用的指令:
*python -m grpc_tools.protoc --proto_path=. --python_out=. --grpc_python_out=. helloworld.proto
中间的空格都被我给区分开了,上述指令的意思我们解读一下:
helloworld.proto将所在目录为当前目录的``helloworld.proto`进行处理
--proto_path=. 将当前目录添加到搜索路径,用这个参数来寻找你proto文件中的import的文件路径
--python_out=.生成的_pb2.py存放于当前目录
--grpc_python_out=.生成的_pb2_grpc.py存放于当前目录
原因
在GitHub上找到了issue,问题在helloworld.proto路径,同时也是执行目录的问题(./helloworld.proto)。
Python下protoc的解析方案是根据proto文件的相对路径来确定导入路径的,也就是说,假如我的目录如下:
1 | pygrpc |
我如果想正确的编译,那么我应该在pygrpc下使用
1 | python -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. example/helloworld.proto |
注意到指令末尾改为了相对路径example/helloworld.proto,而--python_out和--grpc_python_out的目录相对于当前目录,执行完该指令后,protoc将会在--python_out生成proto/helloworld_pb2.py,在--grpc_python_out下生成example/helloworld_pb2_grpc.py,一般我们会将--python_out和--grpc_python_out指定为同一个目录。
再次展示我们的项目文件路径:
1 | │ main.py |


