def _do_unary_response(self, rpc_method, start_response, context, headers, resp): if resp: message_data = protocol.wrap_message( False, False, rpc_method.response_serializer(resp)) else: message_data = b"" if context._trailing_metadata: trailers = protocol.encode_headers(context._trailing_metadata) trailer_message = protocol.pack_trailers(trailers) trailer_data = protocol.wrap_message(True, False, trailer_message) else: trailer_data = b"" content_length = len(message_data) + len(trailer_data) headers.append(("content-length", str(content_length))) headers.append(("grpc-status", str(context.code.value[0]))) if context.details: headers.append(("grpc-message", quote(context.details))) if context._initial_metadata: headers.extend(protocol.encode_headers(context._initial_metadata)) start_response(_grpc_status_to_wsgi_status(context.code), headers) yield message_data yield trailer_data
def _do_streaming_response(self, rpc_method, start_response, context, headers, resp): try: first_message = next(resp) except grpc.RpcError: pass if context._initial_metadata: headers.extend(protocol.encode_headers(context._initial_metadata)) start_response(_grpc_status_to_wsgi_status(context.code), headers) yield protocol.wrap_message( False, False, rpc_method.response_serializer(first_message)) try: for message in resp: yield protocol.wrap_message( False, False, rpc_method.response_serializer(message)) except grpc.RpcError: pass trailers = [("grpc-status", str(context.code.value[0]))] if context.details: trailers.append(("grpc-message", quote(context.details))) if context._trailing_metadata: trailers.extend(protocol.encode_headers( context._trailing_metadata)) trailer_message = protocol.pack_trailers(trailers) yield protocol.wrap_message(True, False, trailer_message)
async def _do_unary_response(self, rpc_method, receive, send, context, headers, coroutine): message = await coroutine status = protocol.grpc_status_to_http_status(context.code) headers.append((b"grpc-status", str(context.code.value[0]).encode())) if context.details: headers.append((b"grpc-message", quote(context.details))) if context._initial_metadata: headers.extend(context._initial_metadata) if message is not None: message_data = protocol.wrap_message( False, False, rpc_method.response_serializer(message)) else: message_data = b"" if context._trailing_metadata: trailers = context._trailing_metadata trailer_message = protocol.pack_trailers(trailers) trailer_data = protocol.wrap_message(True, False, trailer_message) else: trailer_data = b"" content_length = len(message_data) + len(trailer_data) headers.append((b"content-length", str(content_length).encode())) await send({ "type": "http.response.start", "status": status, "headers": headers }) await send({ "type": "http.response.body", "body": message_data, "more_body": True }) await send({ "type": "http.response.body", "body": trailer_data, "more_body": False })
async def _get_response(self): if self._response is None: timeout = aiohttp.ClientTimeout(total=self._timeout) self._response = await self._session.post( self._url, data=protocol.wrap_message( False, False, self._serializer(self._request) ), headers=dict(self._metadata), timeout=timeout, ) protocol.raise_for_status(self._response.headers) return self._response
def test_unwrapping_stream(): buffer = io.BytesIO() messages = [ b"Tyger Tyger, burning bright,", b"In the forests of the night;", b"What immortal hand or eye,", b"Could frame thy fearful symmetry?", ] for message in messages: buffer.write(protocol.wrap_message(False, False, message)) buffer.seek(0) resp_messages = [] for _, _, resp in protocol.unwrap_message_stream(buffer): resp_messages.append(resp) assert resp_messages == messages
def __call__(self): self._response = self._session.request( "POST", self._url, body=protocol.wrap_message(False, False, self._serializer(self._request)), headers=dict(self._metadata), timeout=self._timeout, ) buffer = io.BytesIO(self._response.data) messages = protocol.unwrap_message_stream(buffer) try: trailers, _, message = next(messages) except StopIteration: protocol.raise_for_status(self._response.headers) return if trailers: self._trailers = protocol.unpack_trailers(message) else: result = self._deserializer(message) try: trailers, _, message = next(messages) except StopIteration: pass else: if trailers: self._trailers = protocol.unpack_trailers(message) else: raise ValueError( "UnaryUnary should only return a single message") protocol.raise_for_status(self._response.headers, self._trailers) return result
def __iter__(self): self._response = self._session.request( "POST", self._url, body=protocol.wrap_message(False, False, self._serializer(self._request)), headers=dict(self._metadata), timeout=self._timeout, preload_content=False, ) self._response.auto_close = False stream = io.BufferedReader(self._response, buffer_size=16384) for trailers, _, message in protocol.unwrap_message_stream(stream): if trailers: self._trailers = protocol.unpack_trailers(message) break else: yield self._deserializer(message) self._response.release_conn() protocol.raise_for_status(self._response.headers, self._trailers)
async def test_unwrapping_asgi(): messages = [ b"Tyger Tyger, burning bright,", b"In the forests of the night;", b"What immortal hand or eye,", b"Could frame thy fearful symmetry?", ] buffer = [ protocol.wrap_message(False, False, message) for message in messages ] async def receive(): return { "type": "http.request", "body": buffer.pop(0), "more_body": bool(buffer), } resp_messages = [] async for _, _, resp in protocol.unwrap_message_asgi(receive): resp_messages.append(resp) assert resp_messages == messages
def test_wrapping(): data = b"foobar" wrapped = protocol.wrap_message(False, False, data) assert protocol.unwrap_message(wrapped) == (False, False, data)
async def _do_streaming_response(self, rpc_method, receive, send, context, headers, coroutine): message = await anext(coroutine) status = protocol.grpc_status_to_http_status(context.code) body = protocol.wrap_message(False, False, rpc_method.response_serializer(message)) if context._initial_metadata: headers.extend(context._initial_metadata) await send({ "type": "http.response.start", "status": status, "headers": headers }) await send({ "type": "http.response.body", "body": body, "more_body": True }) async for message in coroutine: body = protocol.wrap_message( False, False, rpc_method.response_serializer(message)) send_task = asyncio.create_task( send({ "type": "http.response.body", "body": body, "more_body": True })) recv_task = asyncio.create_task(receive()) done, pending = await asyncio.wait( {send_task, recv_task}, return_when=asyncio.FIRST_COMPLETED) if recv_task in done: send_task.cancel() result = recv_task.result() if result["type"] == "http.disconnect": break else: recv_task.cancel() trailers = [("grpc-status", str(context.code.value[0]))] if context.details: trailers.append(("grpc-message", quote(context.details))) if context._trailing_metadata: trailers.extend(context._trailing_metadata) trailer_message = protocol.pack_trailers(trailers) body = protocol.wrap_message(True, False, trailer_message) await send({ "type": "http.response.body", "body": body, "more_body": False })