在python3中使用google的protobuf以及gRPC

下载源代码:地址

安装proto

#下载:protoc-3.9.1-linux-x86_64.zip
unzip protoc-3.9.1-linux-x86_64.zip -d protoc-3.9.1-linux-x86_64 # 解压
mv protoc-3.9.1-linux-x86_64 /usr/local/protoc # 移动
ln -s /usr/local/protoc/bin/protoc /usr/bin/protoc # 建立软连接
protoc --version # 测试

安装python的protof 扩展

protoc-3.9.1-linux-x86_64.zip 3 下载
unzip protobuf-python-3.9.1.zip
cd protobuf-3.9.1/python
python3 setup.py build 
python3 setup.py test 
python3 setup.py install
pip list # 参考protobuf         3.9.1

定义数据类型

syntax = "proto3";

package  tutorial;

message searchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
    enum Corpus {
        UNIVERSAL = 0;
        WEB = 1;
        IMAGES =2;
        LOCAL = 3;
        NEWS = 4;
        PRODUCTS = 5;
        VIDEO = 6;
    }

    Corpus corpus = 4;
}

message Person {

    string name = 1;

    int32 id = 2;

    string email = 3;

    enum PhoneType {

        HOME = 0;

        MOBILE = 1;

        WORK = 2;
    }

    message PhoneNumber {

        string number = 1;

        PhoneType type = 2;
    }

    repeated PhoneNumber phones = 4;
}

message AddressBook {

    repeated Person people = 1;
}

protoc --python_out=./ ./test.proto # 编译文件

测试案例

from google.protobuf import json_format

from scrapy_crawl.deal.service.proto.test_pb2 import *

person = Person()

person.id = 1
person.name = 'vic'
person.email = '3264245@qq.com'
person.phones.add(number='15901780', type=Person.MOBILE)

print(person.SerializeToString())

person1 = Person()
p1 = person1.ParseFromString(person.SerializeToString())
print(p1)

j1 = json_format.MessageToDict(person1, True)
print(j1)

person2 = Person()
json_format.Parse(json_format.MessageToJson(person1, True), person2)
print(person2)
# 下面是执行结果
b'\n\x03vic\x10\x01\x1a\x0e3264245@qq.com"\x0c\n\x0815901780\x10\x01'
37
{'name': 'vic', 'id': 1, 'email': '3264245@qq.com', 'phones': [{'number': '15901780', 'type': 'MOBILE'}]}
name: "vic"
id: 1
email: "3264245@qq.com"
phones {
  number: "15901780"
  type: MOBILE
}

grpc服务

定义test.proto

syntax = "proto3";

package  helloworld;


message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}

    rpc SayHelloAgain(HelloRequest) returns (HelloReply) {}
}

生产gRPC代码
python3 -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. helloworld.proto

创建server

import time
from concurrent import futures

from scrapy_crawl.deal.service.proto.test_pb2 import *
from scrapy_crawl.deal.service.proto.test_pb2_grpc import *


class Greeter(GreeterServicer):
    def SayHello(self, request, context):
        return HelloReply(message='hello world, %s' % request.name)

    def SayHelloAgain(self, request, context):
        return HelloReply(message='hello world, %s' % request.name)


def main():
    print("------")
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port("[::]:50051")
    server.start()

    try:
        while True:
            time.sleep(100)
    except KeyboardInterrupt:
        print("stop")
        server.stop(0)
main()

创建client


from scrapy_crawl.deal.service.proto.test_pb2_grpc import *


def run():
    channel = grpc.insecure_channel("localhost:50051")
    stub = GreeterStub(channel=channel)
    r = stub.SayHello(HelloRequest(name='vic'))
    print("greeter client received:%s" % r.message)

    r = stub.SayHelloAgain(HelloRequest(name='baby'))
    print("Greeter client received: %s" % r.message)


run()

错误

  1. test_pb2_grpc 引入了test_pb2文件,是绝对路径引入的,修改为先对路径即可
参考文档:参考1
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容