Python gRPC客户端报错:'module' object is not callable 求助排查
gRPC客户端调用报错排查:'module' object is not callable
问题背景
使用Python编写gRPC客户端调用图像分类服务时,触发grpc._channel._InactiveRpcError,错误详情显示服务端抛出'module' object is not callable异常,已确认服务端运行正常,需排查客户端代码问题。
客户端代码
import grpc import classification_pb2 import classification_pb2_grpc from io import BytesIO class ClassificationClient: def __init__(self): self.channel = grpc.insecure_channel(service_route) self.stub = classification_pb2_grpc.ClassificationStub(self.channel) def classify_image(self, image_bytes: bytes): # 创建请求协议对象 request_proto = classification_pb2.ImageClassificationRequest( image_bytes=image_bytes ) # 发送请求到分类服务 classification_results = self.stub.ClassifyImage(request_proto) if __name__ == "__main__": client = ClassificationClient(hostname="localhost") with open("image.jpg", "rb") as f: image_bytes = f.read() client.classify_image(image_bytes)
报错信息
Traceback (most recent call last): File "/home/user/project/client.py", line 43, in <module> client.classify_image(image_bytes) File "/home/user/project/client.py", line 31, in classify_image classification_results = self.stub.ClassifyImage(request_proto) File "/home/user/project/env/lib/python3.10/site-packages/grpc/_channel.py", line 1181, in __call__ return _end_unary_response_blocking(state, call, False, None) File "/home/user/project/env/lib/python3.10/site-packages/grpc/_channel.py", line 1006, in _end_unary_response_blocking raise _InactiveRpcError(state) # pytype: disable=not-instantiable grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with: status = StatusCode.UNKNOWN details = "Exception calling application: 'module' object is not callable" debug_error_string = "UNKNOWN:Error received from peer {created_time:"2024-07-04T16:44:36.384919944-04:00", grpc_status:2, grpc_message:"Exception calling application: \'module\' object is not callable"}" >
对应Proto文件
syntax = "proto3"; service Classification { rpc ClassifyImage (ImageClassificationRequest) returns (ClassificationResult) {} } message ImageClassificationRequest { bytes image_bytes = 1; } message ClassificationResult { string class_name = 1; } message ClassificationResponse { repeated ClassificationResult results = 1; }
排查与修复方案
1. 修复客户端初始化参数问题
- 原代码
__init__方法未定义hostname参数,但实例化时传入了该参数,会触发TypeError;同时service_route变量未定义,无法建立有效通道。 - 修改
__init__方法,接收服务端地址并构造正确的通道:def __init__(self, hostname): # 替换为服务端实际监听的端口,示例用默认gRPC端口50051 self.channel = grpc.insecure_channel(f"{hostname}:50051") self.stub = classification_pb2_grpc.ClassificationStub(self.channel)
2. 确认Proto生成文件有效性
- 确保通过protoc命令正确生成
classification_pb2.py和classification_pb2_grpc.py,避免因文件损坏或生成错误导致的类/方法调用异常:
(路径根据实际项目结构调整)python -m grpc_tools.protoc -I./proto --python_out=. --grpc_python_out=. ./proto/classification.proto
3. 处理服务端返回结果
- 原代码未接收服务端返回的
ClassificationResult,可添加结果打印或后续处理逻辑,确保调用流程完整:def classify_image(self, image_bytes: bytes): request_proto = classification_pb2.ImageClassificationRequest( image_bytes=image_bytes ) classification_result = self.stub.ClassifyImage(request_proto) print(f"分类结果:{classification_result.class_name}")
修复后的完整客户端代码
import grpc import classification_pb2 import classification_pb2_grpc class ClassificationClient: def __init__(self, hostname): self.channel = grpc.insecure_channel(f"{hostname}:50051") self.stub = classification_pb2_grpc.ClassificationStub(self.channel) def classify_image(self, image_bytes: bytes): request_proto = classification_pb2.ImageClassificationRequest( image_bytes=image_bytes ) classification_result = self.stub.ClassifyImage(request_proto) print(f"分类结果:{classification_result.class_name}") if __name__ == "__main__": client = ClassificationClient(hostname="localhost") with open("image.jpg", "rb") as f: image_bytes = f.read() client.classify_image(image_bytes)
内容的提问来源于stack exchange,提问作者Cj Ryan
相关产品推荐
相关产品推荐

