From f98399dff244ad5c9526e9ae89e89f4fb8ab785a Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 1 Aug 2025 13:35:42 +0200 Subject: [PATCH] Python: add api for remove values from key-value store. --- GrpcInterface/GrpcProtos/KeyValueStore.proto | 3 ++ GrpcInterface/Python/rips/project.py | 11 ++++++ .../Python/rips/tests/test_key_value_store.py | 25 +++++++++++- GrpcInterface/RiaGrpcKeyValueStoreService.cpp | 39 +++++++++++++++---- GrpcInterface/RiaGrpcKeyValueStoreService.h | 4 ++ 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/GrpcInterface/GrpcProtos/KeyValueStore.proto b/GrpcInterface/GrpcProtos/KeyValueStore.proto index eb1d161caf..5f7a6ee08c 100644 --- a/GrpcInterface/GrpcProtos/KeyValueStore.proto +++ b/GrpcInterface/GrpcProtos/KeyValueStore.proto @@ -9,6 +9,7 @@ service KeyValueStore { returns (ClientToServerStreamReply) {} rpc GetValue(KeyValueStoreOutputRequest) returns (stream KeyValueStoreOutputChunk) {} + rpc RemoveValue(KeyValueStoreRemoveRequest) returns (Empty) {} } message KeyValueStoreInputChunk { @@ -29,3 +30,5 @@ message KeyValueStoreChunk { repeated float values = 1; } message KeyValueStoreOutputRequest { string name = 1; } message KeyValueStoreOutputChunk { repeated float values = 1; } + +message KeyValueStoreRemoveRequest { string name = 1; } diff --git a/GrpcInterface/Python/rips/project.py b/GrpcInterface/Python/rips/project.py index 2e0a836b65..09a0250f70 100644 --- a/GrpcInterface/Python/rips/project.py +++ b/GrpcInterface/Python/rips/project.py @@ -555,3 +555,14 @@ def key_values(self, key): for value in chunk.values: all_values.append(value) return all_values + + +@add_method(Project) +def remove_key_values(self, key): + """Remove the values for a given key in the key-value store. + + Arguments: + key(str): The key. + """ + request = KeyValueStore_pb2.KeyValueStoreRemoveRequest(name=key) + self.__key_value_store_stub.RemoveValue(request) diff --git a/GrpcInterface/Python/rips/tests/test_key_value_store.py b/GrpcInterface/Python/rips/tests/test_key_value_store.py index b9a397fbd0..de38d00d2b 100644 --- a/GrpcInterface/Python/rips/tests/test_key_value_store.py +++ b/GrpcInterface/Python/rips/tests/test_key_value_store.py @@ -8,7 +8,6 @@ import rips def test_set_and_get_values(rips_instance, initialize_test): project = rips_instance.project - key = "my-key" input_values = [float(x) for x in range(2000)] project.set_key_values(key, input_values) @@ -19,8 +18,30 @@ def test_set_and_get_values(rips_instance, initialize_test): def test_get_non_existing_key(rips_instance, initialize_test): project = rips_instance.project - key = "this-key-does-not-exist" with pytest.raises(rips.RipsError, match="No matching key found."): project.key_values(key) + + +def test_remove_non_existing_key(rips_instance, initialize_test): + project = rips_instance.project + key = "this-key-does-not-exist" + + with pytest.raises(rips.RipsError, match="No matching key found."): + project.remove_key_values(key) + + +def test_set_and_remove_and_get_values(rips_instance, initialize_test): + project = rips_instance.project + key = "my-key" + input_values = [float(x) for x in range(2000)] + project.set_key_values(key, input_values) + + output_values = project.key_values(key) + assert input_values == output_values + + project.remove_key_values(key) + + with pytest.raises(rips.RipsError, match="No matching key found."): + project.key_values(key) diff --git a/GrpcInterface/RiaGrpcKeyValueStoreService.cpp b/GrpcInterface/RiaGrpcKeyValueStoreService.cpp index 382697adb3..a338802078 100644 --- a/GrpcInterface/RiaGrpcKeyValueStoreService.cpp +++ b/GrpcInterface/RiaGrpcKeyValueStoreService.cpp @@ -198,6 +198,9 @@ grpc::Status RiaGrpcKeyValueStoreService::SetValue( grpc::ServerContext* return stateHandler->receiveStreamRequest( request, reply ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- grpc::Status RiaGrpcKeyValueStoreService::GetValue( grpc::ServerContext* context, const rips::KeyValueStoreOutputRequest* request, rips::KeyValueStoreOutputChunk* reply, @@ -206,6 +209,22 @@ grpc::Status RiaGrpcKeyValueStoreService::GetValue( grpc::ServerContext* return stateHandler->assignStreamReply( reply ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +grpc::Status RiaGrpcKeyValueStoreService::RemoveValue( grpc::ServerContext* context, + const rips::KeyValueStoreRemoveRequest* request, + rips::Empty* reply ) +{ + std::string name = request->name(); + + if ( !RiaApplication::instance()->keyValueStore()->exists( name ) ) + return grpc::Status( grpc::NOT_FOUND, "No matching key found." ); + + RiaApplication::instance()->keyValueStore()->remove( name ); + return Status::OK; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -214,14 +233,18 @@ std::vector RiaGrpcKeyValueStoreService::createCallba using Self = RiaGrpcKeyValueStoreService; std::vector callbacks; - callbacks = { - new RiaGrpcClientToServerStreamCallback( this, - &Self::SetValue, - &Self::RequestSetValue, - new RiaKeyValueStoreStateHandler( true ) ) }; + callbacks = { new RiaGrpcClientToServerStreamCallback( this, + &Self::SetValue, + &Self::RequestSetValue, + new RiaKeyValueStoreStateHandler( + true ) ), + new RiaGrpcUnaryCallback( this, + &Self::RemoveValue, + &Self::RequestRemoveValue ) }; + for ( int i = 0; i < NUM_CONCURRENT_CLIENT_TO_SERVER_STREAMS; ++i ) { callbacks.push_back( diff --git a/GrpcInterface/RiaGrpcKeyValueStoreService.h b/GrpcInterface/RiaGrpcKeyValueStoreService.h index 22aa376823..040a19113e 100644 --- a/GrpcInterface/RiaGrpcKeyValueStoreService.h +++ b/GrpcInterface/RiaGrpcKeyValueStoreService.h @@ -43,5 +43,9 @@ public: rips::KeyValueStoreOutputChunk* reply, RiaKeyValueStoreStateHandler* stateHandler ); + grpc::Status RemoveValue( grpc::ServerContext* context, + const rips::KeyValueStoreRemoveRequest* request, + rips::Empty* reply ) override; + std::vector createCallbacks() override; };