簡體   English   中英

如何從grpc-gateway后面的python服務發送狀態為非ok的響應消息?

[英]How to send response message with non-ok status from a python service behind grpc-gateway?

我正在 python 中的 grpc-gateway 后面編寫一個 grpc 服務,如果某個用戶的請求過多,我想提出 429 響應並在響應消息正文中提供驗證碼令牌。

實際上我的問題是當我使用下面的代碼塊來引發狀態代碼 429 之后,我無法發送響應消息。

context.set_code(grpc.StatusCode.RESOURCE_EXHAUSTED)
context.set_details('Too many requests')
return MyServiceResponse()

據我所知,只有-grpc 是不可能的,但我認為第三方可能是可能的。

有什么解決辦法嗎?

一元-一元 RPC(雙方非流傳輸)不允許發送狀態為非確定的響應。 對於流式 RPC,服務器可能會在發送錯誤代碼之前發送響應,但不建議這樣做。 將正常響應與錯誤狀態混合可能會導致未來的可維護性問題,例如,如果同一錯誤適用於多個 RPC,那么所有響應 ProtoBuf 消息是否都應包含這些字段?

回到您的問題,“驗證碼令牌”應被視為錯誤狀態的一部分,因此可以將其添加為尾隨元數據之一。 在您的情況下,您可以通過在尾隨元數據鍵中添加-bin后綴來將序列化的 proto 消息添加為二進制尾隨元數據。

此外,還有一個官方支持的包grpcio-status可以為您執行此操作。

服務器端將豐富的錯誤狀態打包成“grpc_status.status_pb2.Status”proto 消息。 下面的示例僅使用常見的錯誤原型,但您可以將“任何”原型打包到details ,只要您的客戶理解它們即可。

# 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

客戶端解碼錯誤,並對它們做出反應。

# 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


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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM