Skip to content

Expose response metadata from generated client calls #241

Description

@theruziev

Problem

Currently, betterproto2 generated client methods return only the protobuf response message after a gRPC call.

The metadata argument can be used to send metadata to the server, but there is no convenient way to access metadata returned by the server, such as initial metadata or trailing metadata.

This becomes inconvenient in production use cases where services return useful information through gRPC metadata, for example request IDs, trace IDs, pagination tokens, rate-limit data, diagnostic information, or additional service-level statuses.

Right now, to access this metadata, users have to bypass the generated betterproto2 client method and work directly with the lower-level grpclib stream API. This makes client code more verbose, less ergonomic, and harder to maintain.

Proposed Solution

It would be helpful if betterproto2 provided an optional way to access response metadata from generated client calls while keeping the current API backward compatible.

The existing behavior could stay unchanged:

response = await client.some_method(request)

For users who need metadata, betterproto2 could expose an additional API, for example:

response, metadata = await client.some_method.with_metadata(request)

or return a wrapper object when explicitly requested:

result = await client.some_method(request, return_metadata=True)

print(result.response)
print(result.initial_metadata)
print(result.trailing_metadata)

This would allow users to access both the protobuf response and the metadata returned by the server without manually using the lower-level grpclib stream API.

Such an API would make betterproto2 more convenient for real production scenarios where metadata is used for observability, tracing, debugging, pagination, rate limiting, and passing service-level information between systems.

Alternatives Considered

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions