-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Description
What version of gRPC and what language are you using?
gRPC 1.56.2
Python 3.11
What operating system (Linux, Windows,...) and version?
Ubuntu 22.04
What runtime / compiler are you using (e.g. python version or version of gcc)
Python 3.11
What did you do?
I am writing an async client side interceptor, which adds some metadata to requests before they are sent to the server.
Inside of this interceptor I used the add method of the metadata object on the client_call_details.
from grpc.aio import UnaryUnaryClientInterceptor
class Interceptor(UnaryUnaryClientInterceptor):
async def intercept_unary_unary(
self,
continuation: Callable[[ClientCallDetails, Message], UnaryUnaryCall],
client_call_details: ClientCallDetails,
request: Message,
) -> Union[UnaryUnaryCall, Message]:
client_call_details.metadata.add("my-key", "my-value")
response = await continuation(client_call_details, request)
return responseWhen calling the RPC on the corresponding client stub I passed the metadata as a Sequence[Tuple[str, str]], as this is how it works for the synchronous version.
async with grpc.aio.insecure_channel(f"localhost:{AIO_PORT}") as channel:
stub = gRPCTestServiceStub(channel)
await stub.TestServe(gRPCTestMessage(text="test"), metadata=(("my-call-md", "my-call-md-value"),))What did you expect to see? / What did you see instead?
This then led to AttributeError: 'tuple' object has no attribute 'add' because the tuple is passed on to the interceptor instead of a grpc.aio.Metadata object.
I understand that this is more of a wrong usage from my side as I should use the metadata object instead of a tuple, however, I think the general behavior could be improved to avoid confusion. IMO it is very likely for this to happen because of the corresponding call pattern on the synchronous version and without digging into the library code it was not obvious to me that in the async version the metadata should be passed differently.
IMO, as grpc.aio.Metadata even already has a method to do this, if a tuple is passed as call metadata it could be transformed into the object of the correct class. If not that, then maybe at least raise an understandable exception.