From b2e4bf992ea1600973c06aaf7f9ce545f604d184 Mon Sep 17 00:00:00 2001 From: Vladimir Magamedov Date: Sat, 30 May 2020 03:14:26 +0300 Subject: [PATCH] Added server:Stream.user_agent property and corresponding property in the RecvRequest event --- grpclib/events.py | 4 ++++ grpclib/server.py | 7 ++++++- tests/test_server_events.py | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/grpclib/events.py b/grpclib/events.py index 367d378..1f70a4a 100644 --- a/grpclib/events.py +++ b/grpclib/events.py @@ -164,6 +164,7 @@ class RecvRequest(_Event, metaclass=_EventMeta): :param read-only method_name: RPC's method name :param read-only deadline: request's :py:class:`~grpclib.metadata.Deadline` :param read-only content_type: request's content type + :param read-only user_agent: request's user agent """ __payload__ = ('metadata', 'method_func') @@ -172,6 +173,7 @@ class RecvRequest(_Event, metaclass=_EventMeta): method_name: str deadline: Optional[Deadline] content_type: str + user_agent: Optional[str] class SendInitialMetadata(_Event, metaclass=_EventMeta): @@ -205,6 +207,7 @@ class _DispatchServerEvents(_DispatchCommonEvents): method_name: str, deadline: Optional[Deadline], content_type: str, + user_agent: Optional[str], ) -> Tuple[_Metadata, 'IServerMethodFunc']: return await self.__dispatch__(RecvRequest( # type: ignore metadata=metadata, @@ -212,6 +215,7 @@ class _DispatchServerEvents(_DispatchCommonEvents): method_name=method_name, deadline=deadline, content_type=content_type, + user_agent=user_agent, )) @_dispatches(SendInitialMetadata) diff --git a/grpclib/server.py b/grpclib/server.py index 1f4c193..6df047e 100644 --- a/grpclib/server.py +++ b/grpclib/server.py @@ -83,6 +83,7 @@ class Stream(StreamIterator[_RecvType], Generic[_RecvType, _SendType]): status_details_codec: Optional[StatusDetailsCodecBase], dispatch: _DispatchServerEvents, deadline: Optional[Deadline] = None, + user_agent: Optional[str] = None, ): self._stream = stream self._method_name = method_name @@ -97,6 +98,8 @@ class Stream(StreamIterator[_RecvType], Generic[_RecvType, _SendType]): #: Invocation metadata, received with headers from the client. #: Represented as a multi-dict object. self.metadata: Optional[_Metadata] = None + #: Client's user-agent + self.user_agent = user_agent @property def _content_type(self) -> str: @@ -406,12 +409,13 @@ async def request_handler( return metadata = decode_metadata(headers) + user_agent = headers_map.get('user-agent') async with Stream( _stream, method_name, method.cardinality, method.request_type, method.reply_type, codec=codec, status_details_codec=status_details_codec, - dispatch=dispatch, deadline=deadline, + dispatch=dispatch, deadline=deadline, user_agent=user_agent, ) as stream: deadline_wrapper: 'ContextManager[Any]' if deadline is None: @@ -428,6 +432,7 @@ async def request_handler( method_name=method_name, deadline=deadline, content_type=content_type, + user_agent=user_agent, ) await method_func(stream) except GRPCError: diff --git a/tests/test_server_events.py b/tests/test_server_events.py index cd74d90..030e464 100644 --- a/tests/test_server_events.py +++ b/tests/test_server_events.py @@ -59,6 +59,7 @@ async def test_recv_request(): assert event.method_name == '/dummy.DummyService/UnaryUnary' assert event.deadline.time_remaining() > 0 assert event.content_type == 'application/grpc+proto' + assert event.user_agent.startswith('grpc-python-grpclib') @pytest.mark.asyncio