danielgtaylor / python-betterproto

Clean, modern, Python 3.6+ code generator & library for Protobuf 3 and async gRPC
MIT License
1.51k stars 214 forks source link

Expose request metadata in the generated ```ServiceBase``` #240

Open bettdouglas opened 3 years ago

bettdouglas commented 3 years ago
service Echo {
  rpc Echo(EchoRequest) returns (EchoResponse);
  // rpc EchoStream(EchoRequest) returns (stream EchoStreamResponse);
}

The generated servicer code generates the code but does not expose the request metadata as a parameter.

class EchoService(EchoBase):
    async def echo(self, value: str, extra_times: int) -> "EchoResponse":
        return value

    async def echo_stream(
        self, value: str, extra_times: int
    ) -> AsyncIterator["EchoStreamResponse"]:
        for _ in range(extra_times):
            yield value

The request metadata is really important since it works like headers in rest-api requests, so this is where a client could add authentication tokens, and also where other metadata could be injected by interceptors for instance.

iamnoah commented 3 years ago

I have a PR for this: #234 Feedback welcome.

bettdouglas commented 3 years ago

@iamnoah I've trying generating the echo service, using the example above gives this error

python -m grpc_tools.protoc -I . --python_betterproto_out=lib echo.proto

gives this exception

--python_betterproto_out: protoc-gen-python_betterproto: Plugin failed with status code 1.

I am on python 3.8 and environment variables are

betterproto @ git+https://github.com/hack-edu/python-betterproto.git@02e41afd09f0050a10fea764b15279b82cdd6e6b
grpcio==1.37.1
grpcio-tools==1.37.1
grpclib==0.4.1
h2==4.0.0
hpack==4.0.0
hyperframe==6.0.1
multidict==5.1.0
protobuf==3.17.0
python-dateutil==2.8.1
six==1.16.0

which i installed via pip install git+https://github.com/hack-edu/python-betterproto.git

iamnoah commented 3 years ago

@bettdouglas try pip install git+https://github.com/hack-edu/python-betterproto.git@with-stream-hooks black jinja2

My PR is from a branch, it looks like you installed master, which is unchanged.

Also, installing the plugin from the repo doesn't pickup the compiler dependencies:

> protoc-gen-python_betterproto
Unable to import `black` from betterproto plugin! Please ensure that you've installed betterproto as `pip install "betterproto[compiler]"` so that compiler dependencies are included.

Which is why I added black and jinja2.

jbkoh commented 2 years ago

Are there any other suggestions on this issue? I forked betterproto and did something similar to @iamnoah's solution, but if there is a better practice suggested by the community, I'd love to learn about it.

Thanks all!

parhawm commented 9 months ago

I guess I should switch back to grpclib

jbkoh commented 9 months ago

I guess I should switch back to grpclib

@parhawm This solution works great: https://github.com/danielgtaylor/python-betterproto/pull/234#issuecomment-1089905019

gurland commented 5 months ago

This feature is essential, I agree!

No progress for it since 2021?

greemo commented 5 months ago

Also would like to see support for the missing metadata on the messages used in server base.

Using this solution ATM: https://github.com/danielgtaylor/python-betterproto/pull/234#issuecomment-1089905019