首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >grpc-gateway背后的python服务如何发送非ok状态的响应消息?

grpc-gateway背后的python服务如何发送非ok状态的响应消息?
EN

Stack Overflow用户
提问于 2019-03-09 20:26:53
回答 1查看 3K关注 0票数 3

我正在用python在grpc-gateway后面编写一个grpc服务,如果某个用户的请求太多,我想引发一个429响应,并在响应消息的正文中提供captcha-token。

实际上,我的问题是,当我使用下面的代码块引发状态代码429之后,我无法发送响应消息。

代码语言:javascript
复制
context.set_code(grpc.StatusCode.RESOURCE_EXHAUSTED)
context.set_details('Too many requests')
return MyServiceResponse()

据我所知,使用only-grpc是不可能的,但我认为使用第三方可能是可能的。

对此有什么解决方案吗?

EN

回答 1

Stack Overflow用户

发布于 2019-03-14 03:15:21

一元-一元RPC不允许发送非ok状态的响应(两端非流媒体)。对于流式RPC,服务器可能会在发送错误代码之前发送响应,但不建议这样做。混合正常响应和错误状态可能会导致未来的可维护性问题,例如,如果相同的错误适用于多个RPC,所有响应ProtoBuf消息是否都应该包括这些字段?

回到你的问题,"captcha-token“应该被认为是错误状态的一部分,因此它可以被添加为尾随元数据之一。在您的示例中,您可以通过在尾部元数据关键字中添加-bin后缀,将序列化的proto消息作为二进制尾部元数据添加。

此外,还有一个官方支持的包grpcio-status可以为您完成此任务。

服务器端将丰富的错误状态打包到"grpc_status.status_pb2.Status“原生消息中。下面的例子只使用了常见的错误协议,但是你可以将“任何”协议打包到details中,只要你的客户能够理解它们。

代码语言:javascript
复制
# Server side
from grpc_status import rpc_status
from google.protobuf import any_pb2

def ...Servicer(...):
    def AnRPCCall(request, context):
        ...
        detail = any_pb2.Any()
        detail.Pack(
            rpc_status.error_details_pb2.DebugInfo(
                stack_entries=traceback.format_stack(),
                detail="Can't recognize this argument",
            )
        )
        rich_status = grpc_status.status_pb2.Status(
            code=grpc_status.code_pb2.INVALID_ARGUMENT,
            message='Invalid argument',
            details=[detail]
        )
        context.abort_with_status(rpc_status.to_status(rich_status))
        # The method handler will abort

客户端对错误进行解码,并对其做出反应。

代码语言:javascript
复制
# Client side
try:
    self._channel.unary_unary(_ERROR_DETAILS).with_call(_REQUEST)
except grpc.RpcError as rpc_error:
    status = rpc_status.from_call(rpc_error)
    for detail in status.details:
        if detail.Is(error_details_pb2.DebugInfo.DESCRIPTOR):
            info = error_details_pb2.DebugInfo()
            detail.Unpack(info)
            # Handle the debug info
        elif detail.Is(OtherErrorProto.DESCRIPTOR):
            # Handle the other error proto
        else:
            # Handle unknown error

了解有关rich status的更多信息:https://github.com/grpc/proposal/blob/master/L44-python-rich-status.md

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55077340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档