def test_data(self): test_data = GrpcAny(value=b'hello dapr') resp = InvokeServiceResponse(data=test_data, content_type='application/json') self.assertEqual(b'hello dapr', resp.data) self.assertEqual('hello dapr', resp.text()) self.assertEqual('application/json', resp.content_type)
def OnInvoke(self, request, context): """Invokes service method with InvokeRequest.""" if request.method not in self._invoke_method_map: context.set_code(grpc.StatusCode.UNIMPLEMENTED) # type: ignore raise NotImplementedError( f'{request.method} method not implemented!') req = InvokeServiceRequest(request.data, request.content_type) req.metadata = context.invocation_metadata() resp = self._invoke_method_map[request.method](req) if not resp: return common_v1.InvokeResponse() resp_data = InvokeServiceResponse() if isinstance(resp, (bytes, str)): resp_data.set_data(resp) resp_data.content_type = DEFAULT_JSON_CONTENT_TYPE elif isinstance(resp, GrpcMessage): resp_data.set_data(resp) elif isinstance(resp, InvokeServiceResponse): resp_data = resp else: context.set_code(grpc.StatusCode.OUT_OF_RANGE) context.set_details(f'{type(resp)} is the invalid return type.') raise NotImplementedError( f'{request.method} method not implemented!') if len(resp_data.get_headers()) > 0: context.send_initial_metadata(resp_data.get_headers()) return common_v1.InvokeResponse(data=resp_data.proto, content_type=resp_data.content_type)
def test_unpack(self): # arrange fake_req = common_v1.InvokeRequest(method="test") # act resp = InvokeServiceResponse(data=fake_req) resp_proto = common_v1.InvokeRequest() resp.unpack(resp_proto) # assert self.assertEqual("test", resp_proto.method)
def test_proto(self): fake_req = common_v1.InvokeRequest(method="test") resp = InvokeServiceResponse(data=fake_req) self.assertIsNotNone(resp.proto)
def test_is_proto_for_protobuf(self): fake_req = common_v1.InvokeRequest(method="test") test_data = GrpcAny() test_data.Pack(fake_req) resp = InvokeServiceResponse(data=test_data) self.assertTrue(resp.is_proto())
def test_is_proto_for_non_protobuf(self): test_data = GrpcAny(value=b'hello dapr') resp = InvokeServiceResponse(data=test_data, content_type='application/json') self.assertFalse(resp.is_proto())
def test_non_protobuf_message(self): with self.assertRaises(ValueError): resp = InvokeServiceResponse(data=123) self.assertIsNone(resp, 'This should not be reached.')
def test_proto(self): fake_req = common_v1.InvokeRequest(method="test") test_data = GrpcAny() test_data.Pack(fake_req) resp = InvokeServiceResponse(data=test_data) self.assertIsNotNone(resp.data)
def invoke_service( self, id: str, method: str, data: Union[bytes, str, GrpcMessage], content_type: Optional[str] = None, metadata: Optional[MetadataTuple] = None, http_verb: Optional[str] = None, http_querystring: Optional[MetadataTuple] = None ) -> InvokeServiceResponse: """Invokes the target service to call method. This can invoke the specified target service to call method with bytes array data or custom protocol buffer message. If your callee application uses http appcallback, http_verb and http_querystring must be specified. Otherwise, Dapr runtime will return error. The example calls `callee` service with bytes data, which implements grpc appcallback: from dapr.clients import DaprClient with DaprClient() as d: resp = d.invoke_service( id='callee', method='method', data=b'message', content_type='text/plain', metadata=( ('header1', 'value1') ), ) # resp.content includes the content in bytes. # resp.content_type specifies the content type of resp.content. # Thus, resp.content can be deserialized properly. When sending custom protocol buffer message object, it doesn't requires content_type: from dapr.clients import DaprClient req_data = dapr_example_v1.CustomRequestMessage(data='custom') with DaprClient() as d: resp = d.invoke_service( id='callee', method='method', data=req_data, metadata=( ('header1', 'value1') ), ) # Create protocol buffer object resp_data = dapr_example_v1.CustomResponseMessage() # Deserialize to resp_data resp.unpack(resp_data) The example calls `callee` service which implements http appcallback: from dapr.clients import DaprClient with DaprClient() as d: resp = d.invoke_service( id='callee', method='method', data=b'message', content_type='text/plain', metadata=( ('header1', 'value1') ), http_verb='POST', http_querystring=( ('key1', 'value1') ), ) # resp.content includes the content in bytes. # resp.content_type specifies the content type of resp.content. # Thus, resp.content can be deserialized properly. Args: id (str): the callee app id method (str): the method name which is called data (bytes or :obj:`google.protobuf.message.Message`): bytes or Message for data which will send to id metadata (tuple, optional): custom metadata http_verb (str, optional): http method verb to call HTTP callee application http_querystring (tuple, optional): the tuple to represent query string Returns: :class:`InvokeServiceResponse` object returned from callee """ req_data = InvokeServiceRequest(data, content_type) http_ext = None if http_verb: http_ext = self._get_http_extension(http_verb, http_querystring) req = api_v1.InvokeServiceRequest( id=id, message=common_v1.InvokeRequest(method=method, data=req_data.proto, content_type=req_data.content_type, http_extension=http_ext)) response, call = self._stub.InvokeService.with_call(req, metadata=metadata) resp_data = InvokeServiceResponse(response.data, response.content_type) resp_data.headers = call.initial_metadata() # type: ignore return resp_data
def method_cb(request: InvokeServiceRequest): return InvokeServiceResponse( data='fake_data', content_type='text/plain', )