Python gRPC客户端调用服务提示缺少request参数的问题
gRPC客户端调用报错:缺少必填request参数问题解析
问题代码
greet_pb2_grpc.py
class GreetServiceStub(object): """service here refers to the method contract the client must fulfill in order to call this service """ def __init__(self, channel): """Constructor. Args: channel: A grpc.Channel. """ self.Greeting = channel.unary_unary( '/GreetService/Greeting', request_serializer=greet__pb2.GreetingRequest.SerializeToString, # 此处存在拼写错误:greet__pb2 应为 greet_pb2 response_deserializer=greet__pb2.GreetingResponse.FromString, # 同上拼写错误 )
main.py
import grpc from greet_pb2_grpc import GreetServiceStub def main(): channel = grpc.insecure_channel("localhost:8000") client = GreetServiceStub(channel) client.Greeting() # 调用时未传入必填参数 if __name__ == "__main__": main()
报错信息
Traceback (most recent call last): File "/home/xxxx/projects/grpc/grpc-client/grpc-client/greet/client.py", line 10, in <module> main() File "/home/xxxx/projects/grpc/grpc-client/grpc-client/greet/client.py", line 8, in main client.Greeting() TypeError: _UnaryUnaryMultiCallable.__call__() missing 1 required positional argument: 'request'
补充信息
生成代码用的proto文件
syntax = "proto3"; option go_package = "grpc-client/proto/greet"; // service here refers to the method contract the client must fulfill in order to call this service service GreetService{ rpc Greeting(GreetingRequest) returns (GreetingResponse){} } // The request message contains the user's name message GreetingRequest{ string name = 1; } // The response message contains the greetings message GreetingResponse{ string message = 1; }
生成的greet_pb2.py代码
# greet_pb2.py # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: greet.proto """Generated protocol buffer code.""" from google.protobuf.internal import builder as _builder from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bgreet.proto\" \x1f\n\x0fGreetingRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"#\n\x10GreetingResponse\x12\x0f\n\x07message\x18\x01 \x01(\t2A\n\x0cGreetService\x12\x31\n\x08Greeting\x12\x10.GreetingRequest\x1a\x11.GreetingResponse\" \x00\x42\x19Z\x17grpc-client/proto/greetb\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'greet_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'Z\027grpc-client/proto/greet' _GREETINGREQUEST._serialized_start=15 _GREETINGREQUEST._serialized_end=46 _GREETINGRESPONSE._serialized_start=48 _GREETINGRESPONSE._serialized_end=83 _GREETSERVICE._serialized_start=85 _GREETSERVICE._serialized_end=150 # @@protoc_insertion_point(module_scope)
问题解析与解决方案
报错中的必填参数是什么?
报错里的必填参数是**GreetingRequest类型的请求对象**,对应proto定义中Greeting接口要求的入参。
为什么找不到GreetingRequest?
生成的greet_pb2.py中虽然没有显式写出GreetingRequest类,但通过_builder.BuildTopDescriptorsAndMessages方法已经在全局命名空间中生成了该类,只是需要正确导入使用。另外greet_pb2_grpc.py中存在拼写错误:greet__pb2应为greet_pb2(多了一个下划线),这会导致找不到请求类。
修正步骤
修正
greet_pb2_grpc.py中的拼写错误:# 将greet__pb2改为greet_pb2 request_serializer=greet_pb2.GreetingRequest.SerializeToString, response_deserializer=greet_pb2.GreetingResponse.FromString,修改
main.py,导入请求类并构造请求对象:import grpc from greet_pb2_grpc import GreetServiceStub import greet_pb2 # 导入生成的消息类 def main(): channel = grpc.insecure_channel("localhost:8000") client = GreetServiceStub(channel) # 构造GreetingRequest请求对象 request = greet_pb2.GreetingRequest(name="你的名字") # 传入request调用Greeting方法 response = client.Greeting(request) print("服务器响应:", response.message) if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者disguisedtoast
相关产品推荐
相关产品推荐

