shabbyrobe / grpc-stubs

gRPC typing stubs for Python
MIT License
35 stars 21 forks source link

Make CallFuture `Awaitable` #20

Closed slessans closed 3 years ago

slessans commented 3 years ago

Description

Currently, you are unable to call await on the result of asyncio calls on client stubs. This is because we define our own Future and CallFuture objects, that are not marked as Awaitable -- so mypy thinks they cannot be used with await.

Original problem

I generated some stubs using mypy-protobuf. I also have grpc-stubs==1.24.6 installed.

My stub looks like this:

class FooServiceStub:
   ...
    ListFoo: grpc.UnaryUnaryMultiCallable[
        global___ListFooRequest,
        global___ListFooResponse] = ...

Later, when I try to use this like so:

client = FooServiceStub(...)
req = ListFooRequest()
result = await client.ListFoo(req).future()

However this yields a mypy error: Incompatible types in "await" (actual type "CallFuture[ListFooResponse]", expected type "Awaitable[Any]").

Alternate Solutions

Awaitable could be added to the base Future type instead of to CallFuture.

shabbyrobe commented 3 years ago

Thank you for the PR. Can you please send me a reference in the grpc source code that shows these Future types are actually Awaitable, or a short snippet that demonstrates the property? I don't see in the source any indication that they are.

slessans commented 3 years ago

@shabbyrobe it actually looks like there is no future method at all? Should this be removed from the library?

I found that in this library and was hoping it was a helper method to make typing work with async. It's unfortunate, right now there is no way I can tell to make the typing work with an async stub:

async with aio.insecure_channel("localhost:") as channel:
  client = service_pb2_grpc.ServiceStub(channel)
  await client.GetFoo(req)

Any ideas?

shabbyrobe commented 3 years ago

Does the grpc asyncio package do what you're looking for, without types? https://grpc.github.io/grpc/python/grpc_asyncio.html

It's not a part of this stub package yet unfortunately. There was a PR recently that added auto-generated stubs for this (#13) which I had to revert as it caused a lot of problems (#15) I wanted to take a bit of time to understand the impact of including it a little better before I polished it up for inclusion.

I understand if you're a bit busy but if the grpcio asyncio lib is indeed what you are looking for and you do go down that path, would you mind sharing a couple of representative, anonymised, ideally self-contained snippets with me here? That will make it much easier for me to get up and running and also give me some ready-made use cases to try to target.

Thanks heaps for bringing this back up, this is definitely a facet of this library that needs some attention.