예제 #1
0
    def test_transaction_then_get_states(self):
        dapr = DaprClient(f'localhost:{self.server_port}')

        key = str(uuid.uuid4())
        value = str(uuid.uuid4())
        another_key = str(uuid.uuid4())
        another_value = str(uuid.uuid4())

        dapr.execute_transaction(
            store_name="statestore",
            operations=[
                TransactionalStateOperation(key=key, data=value),
                TransactionalStateOperation(key=another_key,
                                            data=another_value),
            ],
            transactional_metadata={"metakey": "metavalue"})

        resp = dapr.get_states(store_name="statestore",
                               keys=[key, another_key])
        self.assertEqual(resp.items[0].key, key)
        self.assertEqual(resp.items[0].data, to_bytes(value))
        self.assertEqual(resp.items[1].key, another_key)
        self.assertEqual(resp.items[1].data, to_bytes(another_value))

        resp = dapr.get_states(store_name="statestore",
                               keys=[key, another_key],
                               states_metadata={"upper": "1"})
        self.assertEqual(resp.items[0].key, key)
        self.assertEqual(resp.items[0].data, to_bytes(value.upper()))
        self.assertEqual(resp.items[1].key, another_key)
        self.assertEqual(resp.items[1].data, to_bytes(another_value.upper()))
예제 #2
0
    def test_get_save_delete_state(self):
        dapr = DaprClient(f'localhost:{self.server_port}')
        key = "key_1"
        value = "value_1"
        options = StateOptions(
            consistency=Consistency.eventual,
            concurrency=Concurrency.first_write,
        )
        dapr.save_state(store_name="statestore",
                        key=key,
                        value=value,
                        options=options,
                        state_metadata={"capitalize": "1"})

        resp = dapr.get_state(store_name="statestore", key=key)
        self.assertEqual(resp.data, to_bytes(value.capitalize()))

        resp = dapr.get_state(store_name="statestore",
                              key=key,
                              state_metadata={"upper": "1"})
        self.assertEqual(resp.data, to_bytes(value.upper()))

        resp = dapr.get_state(store_name="statestore", key="NotValidKey")
        self.assertEqual(resp.data, b'')

        dapr.delete_state(store_name="statestore", key=key)
        resp = dapr.get_state(store_name="statestore", key=key)
        self.assertEqual(resp.data, b'')

        with self.assertRaises(Exception) as context:
            dapr.delete_state(store_name="statestore",
                              key=key,
                              state_metadata={"must_delete": "1"})
        print(context.exception)
        self.assertTrue('delete failed' in str(context.exception))
예제 #3
0
    def test_save_then_get_states(self):
        dapr = DaprClient(f'localhost:{self.server_port}')

        key = str(uuid.uuid4())
        value = str(uuid.uuid4())
        another_key = str(uuid.uuid4())
        another_value = str(uuid.uuid4())

        dapr.save_states(store_name="statestore",
                         states=[
                             StateItem(key=key,
                                       value=value,
                                       metadata={"capitalize": "1"}),
                             StateItem(key=another_key,
                                       value=another_value,
                                       etag="1"),
                         ],
                         metadata=(("metakey", "metavalue"), ))

        resp = dapr.get_states(store_name="statestore",
                               keys=[key, another_key])
        self.assertEqual(resp.items[0].key, key)
        self.assertEqual(resp.items[0].data, to_bytes(value.capitalize()))
        self.assertEqual(resp.items[1].key, another_key)
        self.assertEqual(resp.items[1].data, to_bytes(another_value))

        resp = dapr.get_states(store_name="statestore",
                               keys=[key, another_key],
                               states_metadata={"upper": "1"})
        self.assertEqual(resp.items[0].key, key)
        self.assertEqual(resp.items[0].etag, "fake_etag")
        self.assertEqual(resp.items[0].data, to_bytes(value.upper()))
        self.assertEqual(resp.items[1].key, another_key)
        self.assertEqual(resp.items[1].etag, "fake_etag")
        self.assertEqual(resp.items[1].data, to_bytes(another_value.upper()))
예제 #4
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())
예제 #5
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())
예제 #6
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())
예제 #7
0
파일: client.py 프로젝트: dapr/python-sdk
    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())
예제 #8
0
 def GetState(self, request, context):
     key = request.key
     if key not in self.store:
         return empty_pb2.Empty()
     else:
         data, etag = self.store[key]
         if request.metadata["upper"]:
             data = to_bytes(data.decode("utf-8").upper())
         return api_v1.GetStateResponse(data=data, etag=etag)
예제 #9
0
 def set_data(self, val: Union[str, bytes, GrpcAny, GrpcMessage, None]) -> None:
     """Sets data to request data."""
     if val is None:
         self._data = GrpcAny()
     elif isinstance(val, (bytes, str)):
         self._data = GrpcAny(value=to_bytes(val))
     elif isinstance(val, (GrpcAny, GrpcMessage)):
         self.pack(val)
     else:
         raise ValueError(f'invalid data type {type(val)}')
예제 #10
0
 def GetBulkState(self, request, context):
     items = []
     for key in request.keys:
         req = api_v1.GetStateRequest(store_name=request.store_name, key=key)
         res = self.GetState(req, context)
         data = res.data
         etag = res.etag
         if request.metadata["upper"]:
             data = to_bytes(data.decode("utf-8").upper())
         items.append(api_v1.BulkStateItem(key=key, etag=etag, data=data))
     return api_v1.GetBulkStateResponse(items=items)
예제 #11
0
    def SaveState(self, request, context):
        headers = ()
        trailers = ()
        for state in request.states:
            data = state.value
            if state.metadata["capitalize"]:
                data = to_bytes(data.decode("utf-8").capitalize())
            self.store[state.key] = data

        context.send_initial_metadata(headers)
        context.set_trailing_metadata(trailers)
        return empty_pb2.Empty()
예제 #12
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())
예제 #13
0
    def test_get_save_state_etag_none(self):
        dapr = DaprGrpcClient(f'localhost:{self.server_port}')

        value = 'test'
        no_etag_key = 'no_etag'
        empty_etag_key = 'empty_etag'
        dapr.save_state(
            store_name="statestore",
            key=no_etag_key,
            value=value,
        )

        dapr.save_state(store_name="statestore",
                        key=empty_etag_key,
                        value=value,
                        etag="")

        resp = dapr.get_state(store_name="statestore", key=no_etag_key)
        self.assertEqual(resp.data, to_bytes(value))
        self.assertEqual(resp.etag, "ETAG_WAS_NONE")

        resp = dapr.get_state(store_name="statestore", key=empty_etag_key)
        self.assertEqual(resp.data, to_bytes(value))
        self.assertEqual(resp.etag, "")
예제 #14
0
    def SaveState(self, request, context):
        headers = ()
        trailers = ()
        for state in request.states:
            data = state.value
            if state.metadata["capitalize"]:
                data = to_bytes(data.decode("utf-8").capitalize())
            if state.HasField('etag'):
                self.store[state.key] = (data, state.etag.value)
            else:
                self.store[state.key] = (data, 'ETAG_WAS_NONE')

        context.send_initial_metadata(headers)
        context.set_trailing_metadata(trailers)
        return empty_pb2.Empty()
예제 #15
0
    def test_get_save_delete_state(self):
        dapr = DaprClient(f'localhost:{self.server_port}')
        key = "key_1"
        value = "value_1"
        options = StateOptions(
            consistency=Consistency.eventual,
            concurrency=Concurrency.first_write,
        )
        dapr.save_state(store_name="statestore",
                        key=key,
                        value=value,
                        options=options)
        resp = dapr.get_state(store_name="statestore", key=key)

        self.assertEqual(resp.data, to_bytes(value))

        resp = dapr.get_state(store_name="statestore", key="NotValidKey")
        self.assertEqual(resp.data, b'')

        dapr.delete_state(store_name="statestore", key=key)
        resp = dapr.get_state(store_name="statestore", key=key)
        self.assertEqual(resp.data, b'')
예제 #16
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())
예제 #17
0
 def data(self, val: Union[str, bytes]) -> None:
     """Sets str or bytes type data to request data."""
     self._data = to_bytes(val)