python使用grpc服务的简单实例

     python使用grpc服务调用的实例,grpc是一款高性能的开源RPC框架,出自Google公司,基于ProtoBuf序列化协议进行开发,支持多语言跨平台。其中grpc对HTTP/2协议的支持,使得在各种客户端服务的开发领域具有很好的发展。grpc提供了一种简单的方法来定义服务,同时客户端充分使用http2 stream的特征,从而有助于节省带宽、降低tcp的链接次数、节省cpu使用率。

  安装相关安装包

pip install grpcio
pip install protobuf
pip install grpcio-tools

proto的中间信息定义模块,hello.proto文件

// [python quickstart](https://grpc.io/docs/quickstart/python.html#run-a-grpc-application)
// python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I. helloworld.proto

// helloworld.proto
syntax = "proto3";

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

message HelloRequest {
    string name = 1;
	string age = 2;
	string money = 3;
}

message HelloReply {
    string message = 1;
}

使用python继续生成服务文件,使得python服务调用使用:run_codegen.py

from grpc_tools import protoc
import os

files = os.listdir("./")
for f in files:
    if ".proto" in f:
        protoc.main((
            '',
            '-I.',
            '--python_out=.',
            '--grpc_python_out=.',
            '{}'.format(f), ))

    使用上述的代码,能够将proto文件解析生成,两个文件hello_pb2.py和hello_pb2_grpc.py, 其中hello_pb2.py主要是传输过程中的传输结构体,hello_pb2_grpc.py是通信过程中的服务传输,主要提供服务和调用服务使用。

   服务端的代码,提供服务,要实现proto中service的服务接口,重写处理函数,然后再grpc服务中调用重写后的实例化对象。这样创建的grpc服务器就可以实现自定义的proto传输服务了

from concurrent import futures
import time
import grpc
import hello_pb2
import hello_pb2_grpc

# 实现 proto 文件中定义的 GreeterServicer
class Greeter(hello_pb2_grpc.GreeterServicer):
    # 实现 proto 文件中定义的 rpc 调用
    def SayHello(self, request, context):
        return hello_pb2.HelloReply(message = 'hello {msg}, {m2}'.format(msg = request.name, m2=request.age))

    def SayHelloAgain(self, request, context):
        return hello_pb2.HelloReply(message='hello {msg}'.format(msg = request.name))

def serve():
    # 启动 rpc 服务
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) 
    hello_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    try:
        while True:
            time.sleep(60*60*24) # one day in seconds
    except KeyboardInterrupt:
        server.stop(0)

if __name__ == '__main__':
    serve()

客户端的代码就是基于生成的hello_pb2.py的传输协议,进行和服务端通信。

import grpc
import hello_pb2
import hello_pb2_grpc

def run():
    # 连接 rpc 服务器
    channel = grpc.insecure_channel('localhost:50051')
    # 调用 rpc 服务
    stub = hello_pb2_grpc.GreeterStub(channel)
    a = hello_pb2.HelloRequest()
    a.name = 'czl'
    a.age = '12'
    a.money = '1212'
    response = stub.SayHello(a)
    print("Greeter client received: " + response.message)
    response = stub.SayHelloAgain(hello_pb2.HelloRequest(name='daydaygo'))
    print("Greeter client received: " + response.message)

if __name__ == '__main__':
    run()

    多线程生成更新数据,迭代服务提供的最新数据简单demo,通过传入对象,对象的内部进行更新和计算的操作,对象中的方法进行更新和获取。

from concurrent import futures
import time
import grpc
import hello_pb2
import hello_pb2_grpc
import pandas as pd
import os
import threading
import time
from grpc_reflection.v1alpha import reflection

class Cal():
    def __init__(self, c):
        self.c = c
    def cal_c(self):
        self.c += 1
    def get_current_c(self):
        return self.c
 
# 实现 proto 文件中定义的 GreeterServicer
class Greeter1(hello_pb2_grpc.GreeterServicer):
    def __init__(self, f):
        self.f = f
    
    # 实现 proto 文件中定义的 rpc 调用
    def SayHello(self, request, context):
        return hello_pb2.HelloReply(message = 'hello {msg}, {m2}'.format(msg = request.name, m2=self.f.get_current_c()))

    def SayHelloAgain(self, request, context):
        return hello_pb2.HelloReply(message='hello {msg}'.format(msg = request.name))

def serve():
    # 启动 rpc 服务
    c = Cal(0)
    work = threading.Thread(target=targetf, args=(c,))
    work.start()
    start_server(Greeter1(c))
    
def start_server(grpc_server):
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    server.add_insecure_port('[::]:50051')
    hello_pb2_grpc.add_GreeterServicer_to_server(grpc_server, server)
    service_names = "service_name"
    reflection.enable_server_reflection(service_names, server)
    server.start()
    server.wait_for_termination()
    
def targetf(c):
    while True:
        c.cal_c()
        time.sleep(2)
        print(c.get_current_c())
    
if __name__ == '__main__':
    serve()

在Cal()类中,进行累加的计算和获取当前值的计算。

<think> 我们正在查找基于PythongRPC应用实例。根据引用内容,我们可以从grpc的官方示例开始,特别是helloworld示例。 引用[2]提到:克隆案例代码并进入helloworld目录。引用[3]和[4]则涉及如何通过protobuf定义服务并生成代码。 步骤: 1. 获取官方示例代码:克隆grpc仓库并进入helloworld示例目录。 2. 定义服务使用protobuf定义服务接口(.proto文件)。 3. 生成代码:使用protoc工具生成Python代码。 4. 实现服务端:编写服务端代码,实现定义的服务。 5. 实现客户端:编写客户端代码,调用服务端方法。 下面我们将详细描述一个简单的helloworld示例: 步骤1:环境准备 确保已安装grpc库和protobuf编译器。可以通过pip安装: ``` pip install grpcio grpcio-tools ``` 步骤2:编写proto文件(helloworld.proto) 在helloworld.proto文件中,我们定义一个简单服务Greeter,其中包含一个SayHello方法。 步骤3:生成代码 使用以下命令生成Python代码: ``` python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto ``` 这将生成helloworld_pb2.py(消息类)和helloworld_pb2_grpc.py(服务类)。 步骤4:实现服务端(greeter_server.py) 在服务端,我们需要实现Greeter服务,并启动一个gRPC服务器。 步骤5:实现客户端(greeter_client.py) 客户端将创建通道并调用服务端的SayHello方法。 下面是一个简化的代码示例: 首先,helloworld.proto文件内容: ```protobuf syntax = "proto3"; package helloworld; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ``` 然后,生成代码(如步骤3所示)。 接着,服务端代码(greeter_server.py): ```python import grpc from concurrent import futures import helloworld_pb2 import helloworld_pb2_grpc class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination() if __name__ == '__main__': serve() ``` 客户端代码(greeter_client.py): ```python import grpc import helloworld_pb2 import helloworld_pb2_grpc def run(): with grpc.insecure_channel('localhost:50051') as channel: stub = helloworld_pb2_grpc.GreeterStub(channel) response = stub.SayHello(helloworld_pb2.HelloRequest(name='World')) print("Greeter client received: " + response.message) if __name__ == '__main__': run() ``` 运行: 1. 在一个终端运行服务端:`python greeter_server.py` 2. 在另一个终端运行客户端:`python greeter_client.py`,客户端将输出:`Greeter client received: Hello, World!` 以上就是一个简单Python gRPC应用实例。 此外,引用[2]中还提到了grpc的4种通信方式(在grpc basic中),包括: 1. 一元RPC(Unary RPC):客户端发送一个请求,服务端返回一个响应(如上面的例子)。 2. 服务端流RPCServer streaming RPC):客户端发送一个请求,服务端返回多个响应(流式)。 3. 客户端流RPC(Client streaming RPC):客户端发送多个请求(流式),服务端返回一个响应。 4. 双向流RPC(Bidirectional streaming RPC):客户端和服务端都可以发送多个请求和响应。 如果需要更复杂的示例,可以参考grpc官方仓库中examples目录下的其他示例。 引用来源: [^1]: grpc 的基础: protobuf [^2]: python实现grpc,克隆案例代码 [^3]: Python使用GRPC,编译生成proto对应源文件 [^4]: grpcpython使用,介绍序列化和调用流程 相关问题: 1. 如何定义gRPC服务中的流式通信? 2. 如何在gRPC中实现身份验证? 3. gRPC与RESTful API相比有哪些优势? 4. 如何处理gRPC中的错误? </think> 以下是基于PythongRPC应用实例详解,结合官方示例和核心开发步骤: ### 一、完整开发流程 1. **定义服务接口**(.proto文件) ```protobuf syntax = "proto3"; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ``` 2. **生成Python代码** ```bash python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto ``` 生成两个文件: - `helloworld_pb2.py`(数据结构) - `helloworld_pb2_grpc.py`(服务端/客户端存根)[^3][^4] 3. **实现服务端**(server.py) ```python import grpc from concurrent import futures from helloworld_pb2 import HelloReply from helloworld_pb2_grpc import GreeterServicer class Greeter(GreeterServicer): def SayHello(self, request, context): return HelloReply(message=f"Hello, {request.name}!") def serve(): server = grpc.server(futures.ThreadPoolExecutor()) add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() print("Server running on port 50051...") server.wait_for_termination() ``` 4. **实现客户端**(client.py) ```python import grpc from helloworld_pb2 import HelloRequest from helloworld_pb2_grpc import GreeterStub def run(): channel = grpc.insecure_channel('localhost:50051') stub = GreeterStub(channel) response = stub.SayHello(HelloRequest(name="Python")) print("Received: " + response.message) ``` ### 二、运行示例 1. 启动服务端: ```bash python server.py ``` 2. 运行客户端: ```bash python client.py # 输出: Received: Hello, Python! ``` ### 三、关键特性实现 1. **流式处理**(服务端流示例) ```protobuf service Greeter { rpc StreamNumbers (Request) returns (stream NumberResponse) {} } ``` 服务端实现: ```python def StreamNumbers(self, request, context): for i in range(5): yield NumberResponse(value=i) ``` 2. **错误处理** ```python def SayHello(self, request, context): if not request.name: context.abort(grpc.StatusCode.INVALID_ARGUMENT, "Name cannot be empty") ``` ### 四、实际应用场景 1. 微服务间通信(订单服务调用支付服务) 2. 移动应用后端API(高效二进制传输) 3. IoT设备数据采集(低带宽场景) 4. 实时视频分析(流式处理)[^1][^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值