python GRPC的官網(wǎng)示例

環(huán)境

windows 10 + Python 3.7

相關(guān)依賴包:

image.png
>pip install grpcio-tools
>pip install protobuf
>pip install grpcio

錯誤問題:

C:\Users\mayn\.virtualenvs\dfgd\Scripts\python.exe: Error while finding module specification for 'grpc_tools.protoc' (ModuleNotFoundError: No module named 'grpc_tools')

上述錯誤是因為我們的沒安裝:grpcio-tools

項目示例

示例來源:http://www.itdecent.cn/p/9c947d98e192

image.png

調(diào)用流程圖示:


image.png
  • 步驟1:新建項目,通過protobuf定義接口和數(shù)據(jù)類型,創(chuàng)建存在user_info.proto文件夾
  • 步驟2:新建rpc_package python包,然后根據(jù)proto文件生成對應(yīng)文件
    命令:
python -m grpc_tools.protoc -I=./protos --python_out=./rpc_package --grpc_python_out=./rpc_package ./protos/helloworld.proto

結(jié)果:

(dfgd) D:\code\python\local_python\dfgd>python -m grpc_tools.protoc -I=./protos --python_out=./rpc_package --grpc_python_out=./rpc_package ./protos/helloworld.proto

改寫一下我們的生產(chǎn)的文件,導(dǎo)入的時候錯誤問題:


image.png
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc


# import helloworld_pb2 as helloworld__pb2
from .helloworld_pb2 import HelloRequest,HelloReply

class HelloWorldServiceStub(object):
    """define a service
    """

    def __init__(self, channel):
        """Constructor.

        Args:
            channel: A grpc.Channel.
        """
        self.SayHello = channel.unary_unary(
                '/rpc_package.HelloWorldService/SayHello',
                request_serializer=HelloRequest.SerializeToString,
                response_deserializer=HelloReply.FromString,
                )


class HelloWorldServiceServicer(object):
    """define a service
    """

    def SayHello(self, request, context):
        """define the interface and data type
        """
        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
        context.set_details('Method not implemented!')
        raise NotImplementedError('Method not implemented!')


def add_HelloWorldServiceServicer_to_server(servicer, server):
    rpc_method_handlers = {
            'SayHello': grpc.unary_unary_rpc_method_handler(
                    servicer.SayHello,
                    request_deserializer=HelloRequest.FromString,
                    response_serializer=HelloReply.SerializeToString,
            ),
    }
    generic_handler = grpc.method_handlers_generic_handler(
            'rpc_package.HelloWorldService', rpc_method_handlers)
    server.add_generic_rpc_handlers((generic_handler,))


 # This class is part of an EXPERIMENTAL API.
class HelloWorldService(object):
    """define a service
    """

    @staticmethod
    def SayHello(request,
            target,
            options=(),
            channel_credentials=None,
            call_credentials=None,
            insecure=False,
            compression=None,
            wait_for_ready=None,
            timeout=None,
            metadata=None):
        return grpc.experimental.unary_unary(request, target, '/rpc_package.HelloWorldService/SayHello',
            HelloRequest.SerializeToString,
            HelloReply.FromString,
            options, channel_credentials,
            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

  • 步驟3:編寫gRPC server服務(wù)端代碼 gfgd_grpc_server.py
#!/usr/bin/evn python
# coding=utf-8
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +
#        ┏┓   ┏┓+ +
#    ┏┛┻━━━┛┻┓ + +
#    ┃       ┃  
#    ┃   ━   ┃ ++ + + +
#    ████━████ ┃+
#    ┃       ┃ +
#    ┃   ┻   ┃
#    ┃       ┃ + +
#    ┗━┓   ┏━┛
#      ┃   ┃           
#      ┃   ┃ + + + +
#      ┃   ┃    Codes are far away from bugs with the animal protecting   
#      ┃   ┃ +     神獸保佑,代碼無bug  
#      ┃   ┃
#      ┃   ┃  +         
#      ┃    ┗━━━┓ + +
#      ┃        ┣┓
#      ┃        ┏┛
#      ┗┓┓┏━┳┓┏┛ + + + +
#       ┃┫┫ ┃┫┫
#       ┗┻┛ ┗┻┛+ + + +
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +"""
"""
# 版權(quán)說明
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +

# @Time  : 2021/2/2 11:43

# @Author : mayn

# @Project : dfgd

# @FileName: gfgd_grpc_server.py

# @Software: PyCharm

# 作者:小鐘同學(xué)

# 著作權(quán)歸作者所有

# 文件功能描述:
"""

from concurrent import futures
import grpc
import logging
import time

from rpc_package.helloworld_pb2_grpc import add_HelloWorldServiceServicer_to_server,HelloWorldServiceServicer
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply


class Hello(HelloWorldServiceServicer):

    # 這里實現(xiàn)我們定義的接口
    def SayHello(self, request, context):
        return HelloReply(message='Hello, %s!' % request.name)


def serve():
    # 這里通過thread pool來并發(fā)處理server的任務(wù)
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    # 將對應(yīng)的任務(wù)處理函數(shù)添加到rpc server中
    add_HelloWorldServiceServicer_to_server(Hello(), server)

    # 這里使用的非安全接口,世界gRPC支持TLS/SSL安全連接,以及各種鑒權(quán)機(jī)制
    server.add_insecure_port('[::]:50000')
    server.start()
    try:
        while True:
            time.sleep(60 * 60 * 24)
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == "__main__":
    logging.basicConfig()
    serve()
  • 步驟4:編寫gRPC client調(diào)用端代碼 dfgd_grpc_clien.py
#!/usr/bin/evn python
# coding=utf-8
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +
#        ┏┓   ┏┓+ +
#    ┏┛┻━━━┛┻┓ + +
#    ┃       ┃  
#    ┃   ━   ┃ ++ + + +
#    ████━████ ┃+
#    ┃       ┃ +
#    ┃   ┻   ┃
#    ┃       ┃ + +
#    ┗━┓   ┏━┛
#      ┃   ┃           
#      ┃   ┃ + + + +
#      ┃   ┃    Codes are far away from bugs with the animal protecting   
#      ┃   ┃ +     神獸保佑,代碼無bug  
#      ┃   ┃
#      ┃   ┃  +         
#      ┃    ┗━━━┓ + +
#      ┃        ┣┓
#      ┃        ┏┛
#      ┗┓┓┏━┳┓┏┛ + + + +
#       ┃┫┫ ┃┫┫
#       ┗┻┛ ┗┻┛+ + + +
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +"""
"""
# 版權(quán)說明
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
# + + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + ++ + + +

# @Time  : 2021/2/2 11:44

# @Author : mayn

# @Project : dfgd

# @FileName: dfgd_grpc_clien.py

# @Software: PyCharm

# 作者:小鐘同學(xué)

# 著作權(quán)歸作者所有

# 文件功能描述: 
"""

from __future__ import print_function
import logging

import grpc
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply
from rpc_package.helloworld_pb2_grpc import HelloWorldServiceStub

def run():
    # 使用with語法保證channel自動close
    with grpc.insecure_channel('localhost:50000') as channel:
        # 客戶端通過stub來實現(xiàn)rpc通信
        stub = HelloWorldServiceStub(channel)

        # 客戶端必須使用定義好的類型,這里是HelloRequest類型
        response = stub.SayHello(HelloRequest(name='eric'))
    print ("hello client received: " + response.message)

if __name__ == "__main__":
    logging.basicConfig()
    run()

啟動相關(guān)服務(wù)端服務(wù)和客戶端:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容