Python Django寫的後臺,想要調用小夥伴的c++模塊方法,目前想到三種解決方案:http,gRPC,本地調用(ctypes,SWIG)
出於以下考慮:
- 後臺與模型模塊分離部署(部分模型模塊對GPU,顯存等有各類要求)
- 跨語言(Python 調用 c++方法)
- 簡單,學習時長短
決定學習並嘗試用gRPC完成此次調用。
步驟
- 編寫.proto文件定義服務,規定接口樣式。
- 通過.proto文件的服務定義中生成gRPC客戶端和服務器端的接口(python生成***_pb2.py和***_pb2_grpc.py),可以通過protocol buffer的編譯器protoc以及一個特殊的gRPC Python插件來完成(不同語言插件、包不同)
- 使用gRPC的API完成不同語言的client和server
安裝
#gRPC 的安裝:
$ pip install grpcio
#安裝 ProtoBuf 相關的 python 依賴庫:
$ pip install protobuf
#安裝 python grpc 的 protobuf 編譯工具:
$ pip install grpcio-tools
grpc git examples(python)
helloworld.proto
// Filename: helloworld.proto
syntax="proto3";
package helloworld;
//Greeter:服務名稱;SayHello:函數名;
//gRPC允許定義4種類型的service方法:
//簡單RPC;應答流式RPC;請求流式RPC;雙向流式RPC
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
//輸入參數
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
//輸出參數
// The response message containing the greetings
message HelloReply {
string message = 1;
}
生成接口文件:helloworld_pb2.py,helloworld_pb2_grpc.py
#-I:運行目錄路徑名
#--python_out:生成Python源文件
#--grpc_out:生成grpc源文件
#--plugin:指定要使用的插件可執行文件。這裏是Python路徑
#.是當前目錄 ..是當前目錄的上層目錄
$ protoc -I ../../protos --python_out=. --grpc_out=. --plugin=protoc-gen-grpc='which grpc_python_plugin' ../../protos/route_guide.proto
sercer.py
from concurrent import futures
import time
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
#Greeter:服務名;SayHello:方法名
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
#請求內容在request中,取數據:request.name
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
#max_workers:最大連接數
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
#服務啓動的ip和端口
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
logging.basicConfig()
serve()
client.py
from __future__ import print_function
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
def run():
#請求的ip和端口地址
with grpc.insecure_channel('localhost:50051') as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
#SayHello:請求方法;name:請求參數
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
logging.basicConfig()
run()
參考
gRPC官方文檔中文版_V1.0
http://doc.oschina.net/grpc?t=60138
Python:如何將proto文件編譯爲python文件
https://blog.csdn.net/Wendy_LWZ/article/details/80654703
Python:GRPC接口編寫之如何編寫服務端與客戶端
https://blog.csdn.net/Wendy_LWZ/article/details/81330799
gRPC 在Python中的應
https://blog.csdn.net/alanguoo/article/details/78635260