You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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(多了一个下划线),这会导致找不到请求类。

修正步骤

  1. 修正greet_pb2_grpc.py中的拼写错误:

    # 将greet__pb2改为greet_pb2
    request_serializer=greet_pb2.GreetingRequest.SerializeToString,
    response_deserializer=greet_pb2.GreetingResponse.FromString,
    
  2. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:35:17