get metadata from server

763 views
Skip to first unread message

soun...@gmail.com

unread,
Apr 1, 2016, 3:01:58 AM4/1/16
to grpc.io
hi guys

I know how to pass metadata from client to server, could I return metadata from server to client?

Thanks

Craig Tiller

unread,
Apr 1, 2016, 9:57:17 AM4/1/16
to soun...@gmail.com, grpc.io

You certainly can! Which language are you working in?


--
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+u...@googlegroups.com.
To post to this group, send email to grp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/abea5ca0-06ba-4edf-be4f-195432a42c6a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

soun...@gmail.com

unread,
Apr 1, 2016, 10:35:52 AM4/1/16
to grpc.io, soun...@gmail.com
I'm using Python, I really need this.

Thanks.

在 2016年4月1日星期五 UTC+8下午9:57:17,Craig Tiller写道:

Nathaniel Manista

unread,
Apr 1, 2016, 5:39:52 PM4/1/16
to Guo Jing, grpc.io
On Fri, Apr 1, 2016 at 7:35 AM, <soun...@gmail.com> wrote:
I'm using Python, I really need this.

在 2016年4月1日星期五 UTC+8下午9:57:17,Craig Tiller写道:

You certainly can! Which language are you working in?


On Fri, Apr 1, 2016, 12:01 AM <soun...@gmail.com> wrote:
I know how to pass metadata from client to server, could I return metadata from server to client?

On the context object that is passed to your service-side application code, do you see an "initial_metadata" method (for sending metadata before any response messages) and a "terminal_metadata" method (for sending metadata after all response messages)?
-Nathaniel

soun...@gmail.com

unread,
Apr 1, 2016, 9:17:15 PM4/1/16
to grpc.io, soun...@gmail.com
hi

Thanks for the reply.

I looked into the code but did not see how to use this ServicerContext object. Looks like it's a server call (because it's a server option)?

I need a response with metadata because I need to do something like Etag in HTTP1, and don't want to add this to Protobuf file. If I could pass the metadata which like HTTP header from server to client. I could design a simple cache between server and client.

A gRPC response is a  google protobuf message, I don't know where to get the metadata.

gRPC support OAuth, looks like it could do that, but with no document and sample.

Thanks, I really need this one to make code clean.

在 2016年4月2日星期六 UTC+8上午5:39:52,Nathaniel Manista写道:

soun...@gmail.com

unread,
Apr 1, 2016, 9:30:10 PM4/1/16
to grpc.io, soun...@gmail.com
And Im grep ServicerContext in the code, I found MethodImplementation.

In MethodImplementation comments is:

The implementation of the method as a callable value that takes a request value and a ServicerContext object and returns a response value.

It seems receive request and context and return response, return value did not include a context object.


在 2016年4月2日星期六 UTC+8上午5:39:52,Nathaniel Manista写道:
On Fri, Apr 1, 2016 at 7:35 AM, <soun...@gmail.com> wrote:

weiyu...@gmail.com

unread,
Apr 4, 2016, 2:26:06 AM4/4/16
to grpc.io, soun...@gmail.com
Same issue on my side, seeking for a way on python client side to extract the metadata...

Nathaniel Manista

unread,
Apr 4, 2016, 11:07:09 AM4/4/16
to Guo Jing, weiyu...@gmail.com, grpc.io
On Fri, Apr 1, 2016 at 6:30 PM, <soun...@gmail.com> wrote:
And Im grep ServicerContext in the code, I found MethodImplementation.

In MethodImplementation comments is:

The implementation of the method as a callable value that takes a request value and a ServicerContext object and returns a response value.

It seems receive request and context and return response, return value did not include a context object.

To retrieve on the client metadata sent from the server you need a Call object. When you make a blocking RPC that just returns a single message (a "response-unary" RPC), the way to get a Call object for the RPC is to pass the "with_call=True" parameter when invoking the RPC. When making an RPC that does not block (either because RPC invocation returns a Future for a single message or because it returns an iterator of response messages), the Future or iterator that is returned is also the Call object. Once you have a Call object for your RPC, the metadata sent from the server is available at its initial_metadata and terminal_metadata methods.
-Nathaniel

soun...@gmail.com

unread,
Apr 4, 2016, 12:25:35 PM4/4/16
to grpc.io, soun...@gmail.com, weiyu...@gmail.com
hi

Thank you, This really help. and sorry, I miss that comments in codes.

Now I could use `response, call = stub.SomeMethod(with_call=True)`. ok, at this moment, this is easy to understand.

But I'm still don't know how to send from server (I know how to receive now). maybe testpb2.SomeServerResponse(a=1, b=2, metadata=mt)? (this is not working). I looked _UnaryUnaryMultiCallable but got nothing in __call__ function. (a rendezvous object?)

I dig into the _invoke function, and found end.operate, looks like end is channel object. then start batch and go to grpc c core. I just don't know where to go. (It may be like this? c code get the http2 frame and give data to a callback, I can't find where).

Thanks and sorry for poor English.

在 2016年4月4日星期一 UTC+8下午11:07:09,Nathaniel Manista写道:

Nathaniel Manista

unread,
Apr 4, 2016, 1:02:54 PM4/4/16
to Guo Jing, grpc.io
On Mon, Apr 4, 2016 at 9:25 AM, <soun...@gmail.com> wrote:
But I'm still don't know how to send from server

Would you mind sharing the text of one of your server-side methods?
-Nathaniel

soun...@gmail.com

unread,
Apr 4, 2016, 9:30:21 PM4/4/16
to grpc.io, soun...@gmail.com
hi this is my code. Thank you very much for helping me.

server protobuf

message Empty {
}

message TouchResponse {
    StatusCode status_code = 1;
    string hostname        = 2;
}

service JediService {
    rpc Touch(Empty) returns (TouchResponse);
}

server impl

class JediServiceImpl(jedi_pb2.BetaJediServiceServicer):

    def touch(self, request, context):
        # just return hostname
        hostname = platform.node()
        return common_pb2.TouchResponse(status_code=common_pb2.OK,
                                        hostname=hostname)

run server

def run():
    r = dsnparse.parse(GRPC_DSN)
    host = r.host
    port = r.port
    pool = ThreadPoolExecutor(max_workers=GRPC_POOL_MAX_WORKER)
    server = jedi_pb2.beta_create_JediService_server(
        JediServiceImpl(), pool=pool, pool_size=GRPC_POOL_SIZE,
        default_timeout=30, maximum_timeout=60)
    server.add_insecure_port('%s:%s' % (host, port))
    print 'server starting at %s:%s ...' % (host, port)
    server.start()

client method

request = common_pb2.Empty()
response, call = self.stub.Touch(request, _TIMEOUT_SECONDS, metadata=metadata, with_call=True)
# I can receive here
# but no where to send from server
for i in call.initial_metadata():
    print i
for i in call.terminal_metadata():
    print i
return response

在 2016年4月5日星期二 UTC+8上午1:02:54,Nathaniel Manista写道:

Nathaniel Manista

unread,
Apr 5, 2016, 12:02:22 AM4/5/16
to Guo Jing, grpc.io
On Mon, Apr 4, 2016 at 6:30 PM, <soun...@gmail.com> wrote:
server impl

class JediServiceImpl(jedi_pb2.BetaJediServiceServicer):

    def touch(self, request, context):

This is the most important part right here - the gRPC Python library has passed from itself to your code a "context" object. Presumably it wants your code to feel free to use it, but your code isn't yet making use of it. Why not?

        # just return hostname
        hostname = platform.node()
        return common_pb2.TouchResponse(status_code=common_pb2.OK,
                                        hostname=hostname)

-Nathaniel

soun...@gmail.com

unread,
Apr 5, 2016, 12:24:23 AM4/5/16
to grpc.io, soun...@gmail.com
oh man! Thank you! I got it!

PS: There is no document of gRPC, so I'm confuse about it. Read code is really hard for fresh guy (include python code and c core), I know Ticket, Call, Channel, CompletionQueue, TcpListener, Event, ChannelFilter, ChannelStack etc., but no big map. Anyway, thanks all, this is really awesome framework.

I learned a lot in this discussion. Thanks. and really sorry for poor English. :)

best wishes.

在 2016年4月5日星期二 UTC+8下午12:02:22,Nathaniel Manista写道:
Reply all
Reply to author
Forward
0 new messages