I'm trying to use the aio API in Python, and having a lot of issues when it 
comes to typing my stubs. I think the Python codegen needs to generate 
separate async stubs and servicers that have different type signatures 
(either in this project or in mypy-protobuf), thoughts?

Here's why:

mypy-protobuf attempts to generate typing stubs, but these only apply to 
the sync API, leaving aio usage incorrectly typed. So I tried to fix 
mypy-protobuf to support the aio API, and ran into a lot of issues. I'd go 
so far as to say it's impossible to type aio stubs, here's why (C and R are 
placeholders):

class FooServicer:
    def DoFoo(self, request: DoFooRequest, context: C) -> R: ...

class SyncFooServicer(FooServicer):
    def DoFoo(self, request: DoFooRequest, context: grpc.ServicerContext) 
-> DoFooResponse: ...

class AsyncFooServicer(FooServicer):
    async def DoFoo(self, request: DoFooRequest, context: 
grpc.aio.ServicerContext) -> DoFooResponse: ...

So R needs to support both DoFooResponse (in the sync case) and 
Awaitable[DoFooResponse] (in the async case). A Union could work, but we 
also need C to be either grpc.ServicerContext or grpc.aio.ServicerContext 
depending on whether the function is async or not, and I don't think this 
is possible to express in Python. This is before we even get to streaming 
requests, where the type of the request itself changes (Iterator vs 
AsyncIterator).

Effectively, the type of DoFoo in FooServicer is:
Union[
    Callable[[Self, DoFooRequest, grpc.ServicerContext], DoFooResponse],
    Callable[[Self, DoFooRequest, grpc.aio.ServicerContext], 
Awaitable[DoFooResponse]
]

But this doesn't appear to work correctly with Python type checkers.

I imagine the same thing happens with stubs too, but I haven't worked out 
how yet.

In addition to all this, we have the fact that sync Servicers can be used 
with sync Servers and aio Servers (that have a thread pool), but async 
Servicers can only be used with aio Servers.

Given the difference between the sync and async APIs, I believe the right 
approach is to generate separate stubs and servicers for the sync vs async 
case. Then, the sync API can generally stick to only the sync stubs and 
servicers, while the aio API can use both (given the compatibility).

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/aa3edfee-89ee-4810-b61c-2efe06fd1723n%40googlegroups.com.

Reply via email to