def test_invoke_method_proto_data(self):
        self.server.set_response(b"\x0a\x04resp")
        self.server.reply_header('Content-Type', 'application/x-protobuf')

        req = common_v1.StateItem(key='test')
        resp = self.client.invoke_method(self.app_id,
                                         self.method_name,
                                         http_verb='PUT',
                                         data=req)

        self.assertEqual(b"\x0a\x04test", self.server.get_request_body())
        # unpack to new protobuf object
        new_resp = common_v1.StateItem()
        resp.unpack(new_resp)
        self.assertEqual('resp', new_resp.key)
Beispiel #2
0
    def save_state(
        self,
        store_name: str,
        key: str,
        value: Union[bytes, str],
        etag: Optional[str] = None,
        options: Optional[StateOptions] = None,
        metadata: Optional[MetadataTuple] = ()
    ) -> DaprResponse:
        """Saves key-value pairs to a statestore

        This saves a value to the statestore with a given key and state store name.
        Options for request can be passed with the options field and custom
        metadata can be passed with metadata field.

        The example saves states to a statestore:
            from dapr import DaprClient
            with DaprClient() as d:
                resp = d.save_state(
                    store_name='state_store'
                    states=[{'key': 'key1', 'value': 'value1'}],
                    etag='etag',
                    metadata=(
                        ('header1', 'value1')
                    ),
                )

        Args:
            store_name (str): the state store name to save to
            key (str): the key to be saved
            value (bytes or str): the value to be saved
            etag (str, optional): the etag to save with
            options (StateOptions, optional): custom options
                for concurrency and consistency
            metadata (tuple, optional): custom metadata

        Returns:
            :class:`DaprResponse` gRPC metadata returned from callee
        """
        if not isinstance(value, (bytes, str)):
            raise ValueError(f'invalid type for data {type(value)}')

        req_value = value

        if len(store_name) == 0 or len(store_name.strip()) == 0:
            raise ValueError("State store name cannot be empty")

        if options is None:
            state_options = None
        else:
            state_options = options.get_proto()

        state = common_v1.StateItem(key=key,
                                    value=to_bytes(req_value),
                                    etag=etag,
                                    options=state_options)

        req = api_v1.SaveStateRequest(store_name=store_name, states=[state])
        response, call = self._stub.SaveState.with_call(req, metadata=metadata)
        return DaprResponse(headers=call.initial_metadata())
Beispiel #3
0
    def execute_state_transaction(
        self,
        store_name: str,
        operations: Sequence[TransactionalStateOperation],
        transactional_metadata: Optional[Dict[str, str]] = dict(),
        metadata: Optional[MetadataTuple] = ()
    ) -> DaprResponse:
        """Saves or deletes key-value pairs to a statestore as a transaction

        This saves or deletes key-values to the statestore as part of a single transaction,
        transaction_metadata is used for the transaction operation, while metadata is used
        for the GRPC call.

        The example saves states to a statestore:
            from dapr import DaprClient
            with DaprClient() as d:
                resp = d.execute_state_transaction(
                    store_name='state_store',
                    operations=[
                        TransactionalStateOperation(key=key, data=value),
                        TransactionalStateOperation(key=another_key, data=another_value),
                        TransactionalStateOperation(
                            operation_type=TransactionOperationType.delete,
                            key=key_to_delete),
                    ],
                    transactional_metadata={"header1": "value1"},
                    metadata=(
                        ('header1', 'value1')
                    ),
                )

        Args:
            store_name (str): the state store name to save to
            operations (Sequence[TransactionalStateOperation]): the transaction operations
            transactional_metadata (Dict[str, str], optional): custom metadata for transaction
            metadata (tuple, optional): custom grpc metadata

        Returns:
            :class:`DaprResponse` gRPC metadata returned from callee
        """
        if not store_name or len(store_name) == 0 or len(
                store_name.strip()) == 0:
            raise ValueError("State store name cannot be empty")
        req_ops = [
            api_v1.TransactionalStateOperation(
                operationType=o.operation_type.value,
                request=common_v1.StateItem(key=o.key,
                                            value=to_bytes(o.data),
                                            etag=o.etag)) for o in operations
        ]

        req = api_v1.ExecuteStateTransactionRequest(
            storeName=store_name,
            operations=req_ops,
            metadata=transactional_metadata)
        _, call = self._stub.ExecuteStateTransaction.with_call(
            req, metadata=metadata)
        return DaprResponse(headers=call.initial_metadata())
Beispiel #4
0
    def save_bulk_state(
        self,
        store_name: str,
        states: List[StateItem],
        metadata: Optional[MetadataTuple] = ()
    ) -> DaprResponse:
        """Saves state items to a statestore

        This saves a given state item into the statestore specified by store_name.

        The example saves states to a statestore:
            from dapr import DaprClient
            with DaprClient() as d:
                resp = d.save_bulk_state(
                    store_name='state_store',
                    states=[StateItem(key='key1', value='value1'),
                        StateItem(key='key2', value='value2', etag='etag'),],
                )

        Args:
            store_name (str): the state store name to save to
            states (List[StateItem]): list of states to save
            metadata (tuple, optional): gRPC custom metadata

        Returns:
            :class:`DaprResponse` gRPC metadata returned from callee

        Raises:
            ValueError: states is empty
            ValueError: store_name is empty
        """
        if metadata is not None:
            warn(
                'metadata argument is deprecated. Dapr already intercepts API token headers '
                'and this is not needed.',
                DeprecationWarning,
                stacklevel=2)

        if not states or len(states) == 0:
            raise ValueError("States to be saved cannot be empty")

        if not store_name or len(store_name) == 0 or len(
                store_name.strip()) == 0:
            raise ValueError("State store name cannot be empty")

        req_states = [
            common_v1.StateItem(
                key=i.key,
                value=to_bytes(i.value),
                etag=common_v1.Etag(
                    value=i.etag) if i.etag is not None else None,
                options=i.options,
                metadata=i.metadata) for i in states
        ]

        req = api_v1.SaveStateRequest(store_name=store_name, states=req_states)
        _, call = self._stub.SaveState.with_call(req, metadata=metadata)
        return DaprResponse(headers=call.initial_metadata())
    def test_invoke_method_protobuf_response_case_insensitive(self):
        self.server.set_response(b"\x0a\x04resp")
        self.server.reply_header('Content-Type',
                                 'apPlicaTion/x-protobuf; gzip')

        req = common_v1.StateItem(key='test')
        resp = self.client.invoke_method(self.app_id,
                                         self.method_name,
                                         http_verb='PUT',
                                         data=req,
                                         metadata=(('header1', 'value1'),
                                                   ('header2', 'value2')))

        self.assertEqual(b"\x0a\x04test", self.server.get_request_body())
        # unpack to new protobuf object
        new_resp = common_v1.StateItem()
        resp.unpack(new_resp)
        self.assertEqual('resp', new_resp.key)
Beispiel #6
0
    def execute_state_transaction(
            self,
            store_name: str,
            operations: Sequence[TransactionalStateOperation],
            transactional_metadata: Optional[Dict[str, str]] = dict(),
            metadata: Optional[MetadataTuple] = None) -> DaprResponse:
        """Saves or deletes key-value pairs to a statestore as a transaction

        This saves or deletes key-values to the statestore as part of a single transaction,
        transaction_metadata is used for the transaction operation, while metadata is used
        for the GRPC call.

        The example saves states to a statestore:
            from dapr import DaprClient
            with DaprClient() as d:
                resp = d.execute_state_transaction(
                    store_name='state_store',
                    operations=[
                        TransactionalStateOperation(key=key, data=value),
                        TransactionalStateOperation(key=another_key, data=another_value),
                        TransactionalStateOperation(
                            operation_type=TransactionOperationType.delete,
                            key=key_to_delete),
                    ],
                    transactional_metadata={"header1": "value1"},
                )

        Args:
            store_name (str): the state store name to save to
            operations (Sequence[TransactionalStateOperation]): the transaction operations
            transactional_metadata (Dict[str, str], optional): Dapr metadata for transaction
            metadata (tuple, optional, DEPRECATED): gRPC custom metadata

        Returns:
            :class:`DaprResponse` gRPC metadata returned from callee
        """
        if metadata is not None:
            warn('metadata argument is deprecated. Dapr already intercepts API token headers '
                 'and this is not needed.', DeprecationWarning, stacklevel=2)

        if not store_name or len(store_name) == 0 or len(store_name.strip()) == 0:
            raise ValueError("State store name cannot be empty")
        req_ops = [api_v1.TransactionalStateOperation(
            operationType=o.operation_type.value,
            request=common_v1.StateItem(
                key=o.key,
                value=to_bytes(o.data),
                etag=common_v1.Etag(value=o.etag) if o.etag is not None else None))
            for o in operations]

        req = api_v1.ExecuteStateTransactionRequest(
            storeName=store_name,
            operations=req_ops,
            metadata=transactional_metadata)
        _, call = self._stub.ExecuteStateTransaction.with_call(req, metadata=metadata)
        return DaprResponse(
            headers=call.initial_metadata())
Beispiel #7
0
    def test_on_invoke_return_proto(self):
        def method_cb(request: InvokeMethodRequest):
            return common_v1.StateItem(key='fake_key')

        resp = self._on_invoke('method_proto', method_cb)

        state = common_v1.StateItem()
        resp.data.Unpack(state)

        self.assertEqual('fake_key', state.key)
Beispiel #8
0
    def test_invoke_service_proto_data(self):
        dapr = DaprClient(f'localhost:{self.server_port}')
        req = common_v1.StateItem(key='test')
        resp = dapr.invoke_service(
            id='targetId',
            method='proto',
            data=req,
            metadata=(
                ('key1', 'value1'),
                ('key2', 'value2'),
            ),
        )

        self.assertEqual(3, len(resp.headers))
        self.assertEqual(['value1'], resp.headers['hkey1'])
        self.assertTrue(resp.is_proto())

        # unpack to new protobuf object
        new_resp = common_v1.StateItem()
        resp.unpack(new_resp)
        self.assertEqual('test', new_resp.key)
Beispiel #9
0
    def save_bulk_state(
        self,
        store_name: str,
        states: List[StateItem],
        metadata: Optional[MetadataTuple] = ()
    ) -> DaprResponse:
        """Saves state items to a statestore

        This saves a given state item into the statestore specified by store_name.

        The example saves states to a statestore:
            from dapr import DaprClient
            with DaprClient() as d:
                resp = d.save_bulk_state(
                    store_name='state_store'
                    states=[StateItem(key='key1', value='value1'),
                        StateItem(key='key2', value='value2', etag='etag'),],
                    metadata=(
                        ('header1', 'value1')
                    ),
                )

        Args:
            store_name (str): the state store name to save to
            states (List[StateItem]): list of states to save
            metadata (tuple, optional): custom metadata

        Returns:
            :class:`DaprResponse` gRPC metadata returned from callee

        Raises:
            ValueError: states is empty
            ValueError: store_name is empty
        """
        if not states or len(states) == 0:
            raise ValueError("States to be saved cannot be empty")

        if not store_name or len(store_name) == 0 or len(
                store_name.strip()) == 0:
            raise ValueError("State store name cannot be empty")

        req_states = [
            common_v1.StateItem(key=i.key,
                                value=to_bytes(i.value),
                                etag=i.etag,
                                options=i.options,
                                metadata=i.metadata) for i in states
        ]

        req = api_v1.SaveStateRequest(store_name=store_name, states=req_states)
        _, call = self._stub.SaveState.with_call(req, metadata=metadata)
        return DaprResponse(headers=call.initial_metadata())
    def test_invoke_method_with_api_token(self):
        self.server.set_response(b"FOO")
        settings.DAPR_API_TOKEN = 'c29saSBkZW8gZ2xvcmlhCg=='

        req = common_v1.StateItem(key='test')
        resp = self.client.invoke_method(
            self.app_id,
            self.method_name,
            http_verb='PUT',
            data=req,
        )

        request_headers = self.server.get_request_headers()

        self.assertEqual('c29saSBkZW8gZ2xvcmlhCg==',
                         request_headers['dapr-api-token'])
        self.assertEqual(b'FOO', resp.data)
    def test_invoke_method_metadata(self):
        self.server.set_response(b"FOO")

        req = common_v1.StateItem(key='test')
        resp = self.client.invoke_method(self.app_id,
                                         self.method_name,
                                         http_verb='PUT',
                                         data=req,
                                         metadata=(('header1', 'value1'),
                                                   ('header2', 'value2')))

        request_headers = self.server.get_request_headers()

        self.assertEqual(b'FOO', resp.data)

        self.assertEqual('value1', request_headers['header1'])
        self.assertEqual('value2', request_headers['header2'])
    def test_invoke_method_with_tracer(self):
        tracer = Tracer(sampler=samplers.AlwaysOnSampler(),
                        exporter=print_exporter.PrintExporter())

        self.client = DaprClient(headers_callback=lambda: tracer.propagator.
                                 to_headers(tracer.span_context))
        self.server.set_response(b"FOO")

        with tracer.span(name="test"):
            req = common_v1.StateItem(key='test')
            resp = self.client.invoke_method(
                self.app_id,
                self.method_name,
                http_verb='PUT',
                data=req,
            )

        request_headers = self.server.get_request_headers()

        self.assertIn('Traceparent', request_headers)
        self.assertEqual(b'FOO', resp.data)
Beispiel #13
0
 def method_cb(request: InvokeMethodRequest):
     return common_v1.StateItem(key='fake_key')
Beispiel #14
0
    def save_state(
        self,
        store_name: str,
        key: str,
        value: Union[bytes, str],
        etag: Optional[str] = None,
        options: Optional[StateOptions] = None,
        state_metadata: Optional[Dict[str, str]] = dict(),
        metadata: Optional[MetadataTuple] = ()
    ) -> DaprResponse:
        """Saves key-value pairs to a statestore

        This saves a value to the statestore with a given key and state store name.
        Options for request can be passed with the options field and custom
        metadata can be passed with metadata field.

        The example saves states to a statestore:
            from dapr import DaprClient
            with DaprClient() as d:
                resp = d.save_state(
                    store_name='state_store',
                    key='key1',
                    value='value1',
                    etag='etag',
                    state_metadata={"metakey": "metavalue"},
                )

        Args:
            store_name (str): the state store name to save to
            key (str): the key to be saved
            value (bytes or str): the value to be saved
            etag (str, optional): the etag to save with
            options (StateOptions, optional): custom options
                for concurrency and consistency
            state_metadata (Dict[str, str], optional): Dapr metadata for state request
            metadata (tuple, optional, DEPRECATED): gRPC custom metadata

        Returns:
            :class:`DaprResponse` gRPC metadata returned from callee

        Raises:
            ValueError: value is not bytes or str
            ValueError: store_name is empty
        """
        if metadata is not None:
            warn(
                'metadata argument is deprecated. Dapr already intercepts API token headers '
                'and this is not needed.',
                DeprecationWarning,
                stacklevel=2)

        if not isinstance(value, (bytes, str)):
            raise ValueError(f'invalid type for data {type(value)}')

        req_value = value

        if not store_name or len(store_name) == 0 or len(
                store_name.strip()) == 0:
            raise ValueError("State store name cannot be empty")

        if options is None:
            state_options = None
        else:
            state_options = options.get_proto()

        state = common_v1.StateItem(
            key=key,
            value=to_bytes(req_value),
            etag=common_v1.Etag(value=etag) if etag is not None else None,
            options=state_options,
            metadata=state_metadata)

        req = api_v1.SaveStateRequest(store_name=store_name, states=[state])
        _, call = self._stub.SaveState.with_call(req, metadata=metadata)
        return DaprResponse(headers=call.initial_metadata())
Beispiel #15
0
import os

from dapr.proto import api_v1, api_service_v1, common_v1
from google.protobuf.any_pb2 import Any

# Get port from environment variable.
port = os.getenv('DAPR_GRPC_PORT', '50001')
daprUri = 'localhost:' + port
channel = grpc.insecure_channel(daprUri)

client = api_service_v1.DaprStub(channel)
client.PublishEvent(api_v1.PublishEventRequest(topic='sith', data='lala'.encode('utf-8')))
print('Published!')

key = 'mykey'
storeName = 'statestore'
req = common_v1.StateItem(key=key, value='my state'.encode('utf-8'))
state = api_v1.SaveStateRequest(store_name=storeName, states=[req])

client.SaveState(state)
print('Saved!')

resp = client.GetState(api_v1.GetStateRequest(store_name=storeName, key=key))
print('Got!')
print(resp)

resp = client.DeleteState(api_v1.DeleteStateRequest(store_name=storeName, key=key))
print('Deleted!')

channel.close()