grpcio-status

1.78.0 · active · verified Fri Mar 27

grpcio-status provides the Python binding for the google.rpc.Status protobuf, enabling rich (structured) error details to be packed into gRPC trailing metadata and unpacked on the client side. It sits on top of grpcio and protobuf, exposing two primary helpers — rpc_status.to_status() and rpc_status.from_call() — both marked EXPERIMENTAL in the source. The package is versioned in strict lockstep with grpcio (current: 1.78.0) and is released on the same cadence, typically every 4–6 weeks.

Warnings

Install

Imports

Quickstart

Server aborts with a rich google.rpc.Status; client unpacks the structured error detail.

# pip install grpcio grpcio-status googleapis-common-protos
import grpc
from grpc_status import rpc_status
from google.rpc import status_pb2, code_pb2, error_details_pb2
from google.protobuf import any_pb2

# --- SERVER SIDE (inside a servicer method) ---
def MyRpc(request, context):
    # Build a structured error detail
    detail = any_pb2.Any()
    detail.Pack(
        error_details_pb2.BadRequest(
            field_violations=[
                error_details_pb2.BadRequest.FieldViolation(
                    field="name",
                    description="must not be empty",
                )
            ]
        )
    )
    rich_status = status_pb2.Status(
        code=code_pb2.INVALID_ARGUMENT,
        message="Invalid request",
        details=[detail],
    )
    # abort_with_status atomically sets code + message + trailing metadata
    context.abort_with_status(rpc_status.to_status(rich_status))

# --- CLIENT SIDE ---
def call_rpc(stub):
    try:
        stub.MyRpc(request=object())  # placeholder
    except grpc.RpcError as rpc_error:
        # from_call returns None when no rich status was packed
        status = rpc_status.from_call(rpc_error)
        if status is None:
            print("No rich status; plain code:", rpc_error.code())
            return
        print("gRPC status code:", rpc_error.code())
        for detail in status.details:
            if detail.Is(error_details_pb2.BadRequest.DESCRIPTOR):
                info = error_details_pb2.BadRequest()
                detail.Unpack(info)
                for v in info.field_violations:
                    print(f"Field '{v.field}': {v.description}")

view raw JSON →