From 8dcb13d14ec366a69421a43dd4b8a0041ee6fdb0 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Fri, 19 Apr 2024 10:33:36 -0700 Subject: [PATCH 1/4] Python: Add `PFADD` command. (#229) * Add `PFADD` command. Signed-off-by: Yury-Fridlyand * BLACK I HATE YOU Signed-off-by: Yury-Fridlyand * PR comments. Signed-off-by: Yury-Fridlyand * Update CHANGELOG.md Signed-off-by: Yury-Fridlyand Co-authored-by: Aaron <69273634+aaron-congo@users.noreply.github.com> --------- Signed-off-by: Yury-Fridlyand Co-authored-by: Aaron <69273634+aaron-congo@users.noreply.github.com> --- CHANGELOG.md | 1 + python/python/glide/async_commands/core.py | 29 +++++++++++++++++++ .../glide/async_commands/transaction.py | 20 +++++++++++++ python/python/tests/test_async_client.py | 13 +++++++++ python/python/tests/test_transaction.py | 5 ++++ 5 files changed, 68 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ed4e0b68e..6512dcf7de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Node: Added ZRANGE command ([#1115](https://github.com/aws/glide-for-redis/pull/1115)) * Python: Added RENAME command ([#1252](https://github.com/aws/glide-for-redis/pull/1252)) * Python: Added APPEND command ([#1152](https://github.com/aws/glide-for-redis/pull/1152)) +* Python: Added PFADD command (TODO PR #) #### Fixes * Python: Fix typing error "‘type’ object is not subscriptable" ([#1203](https://github.com/aws/glide-for-redis/pull/1203)) diff --git a/python/python/glide/async_commands/core.py b/python/python/glide/async_commands/core.py index 581948347e..cc48856798 100644 --- a/python/python/glide/async_commands/core.py +++ b/python/python/glide/async_commands/core.py @@ -2041,3 +2041,32 @@ async def invoke_script( ["foo", "bar"] """ return await self._execute_script(script.get_hash(), keys, args) + + async def pfadd(self, key: str, elements: List[str]) -> int: + """ + Adds all elements to the HyperLogLog data structure stored at the specified `key`. + Creates a new structure if the `key` does not exist. + + When no `elements` are provided, and `key` exists and is a HyperLogLog, then no operation is performed. + If `key` does not exist, then the HyperLogLog structure is created. + + See https://redis.io/commands/pfadd/ for more details. + + Args: + key (str): The `key` of the HyperLogLog data structure to add elements into. + elements (List[str]): An list of members to add to the HyperLogLog stored at `key`. + + Returns: + int: If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is + altered, then returns `1`. Otherwise, returns `0`. + + Examples: + >>> client.pfadd("hll_1", ["a", "b", "c" ]) + 1 # A data structure was created or modified + >>> client.pfadd("hll_2", []) + 1 # A new empty data structure was created + """ + return cast( + int, + await self._execute_command(RequestType.PfAdd, [key] + elements), + ) diff --git a/python/python/glide/async_commands/transaction.py b/python/python/glide/async_commands/transaction.py index adc979ec79..788f3b35a4 100644 --- a/python/python/glide/async_commands/transaction.py +++ b/python/python/glide/async_commands/transaction.py @@ -1551,6 +1551,26 @@ def dbsize(self: TTransaction) -> TTransaction: """ return self.append_command(RequestType.DBSize, []) + def pfadd(self: TTransaction, key: str, elements: List[str]) -> TTransaction: + """ + Adds all elements to the HyperLogLog data structure stored at the specified `key`. + Creates a new structure if the `key` does not exist. + + When no `elements` are provided, and `key` exists and is a HyperLogLog, then no operation is performed. + If `key` does not exist, then the HyperLogLog structure is created. + + See https://redis.io/commands/pfadd/ for more details. + + Args: + key (str): The `key` of the HyperLogLog data structure to add elements into. + elements (List[str]): An list of members to add to the HyperLogLog stored at `key`. + + Commands response: + int: If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is + altered, then returns `1`. Otherwise, returns `0`. + """ + return self.append_command(RequestType.PfAdd, [key] + elements) + class Transaction(BaseTransaction): """ diff --git a/python/python/tests/test_async_client.py b/python/python/tests/test_async_client.py index ea4ec3ff95..bafd1c5521 100644 --- a/python/python/tests/test_async_client.py +++ b/python/python/tests/test_async_client.py @@ -1741,6 +1741,19 @@ async def test_append(self, redis_client: TRedisClient): assert await redis_client.append(key, value) == 10 assert await redis_client.get(key) == value * 2 + @pytest.mark.parametrize("cluster_mode", [True, False]) + @pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3]) + async def test_pfadd(self, redis_client: TRedisClient): + key = get_random_string(10) + assert await redis_client.pfadd(key, []) == 1 + assert await redis_client.pfadd(key, ["one", "two"]) == 1 + assert await redis_client.pfadd(key, ["two"]) == 0 + assert await redis_client.pfadd(key, []) == 0 + + assert await redis_client.set("foo", "value") == OK + with pytest.raises(RequestError): + await redis_client.pfadd("foo", []) + class TestCommandsUnitTests: def test_expiry_cmd_args(self): diff --git a/python/python/tests/test_transaction.py b/python/python/tests/test_transaction.py index 0fab703f50..26d520be14 100644 --- a/python/python/tests/test_transaction.py +++ b/python/python/tests/test_transaction.py @@ -32,6 +32,7 @@ async def transaction_test( key7 = "{{{}}}:{}".format(keyslot, get_random_string(3)) key8 = "{{{}}}:{}".format(keyslot, get_random_string(3)) key9 = "{{{}}}:{}".format(keyslot, get_random_string(3)) + key11 = "{{{}}}:{}".format(keyslot, get_random_string(3)) # hyper log log value = datetime.now(timezone.utc).strftime("%m/%d/%Y, %H:%M:%S") value2 = get_random_string(5) @@ -198,6 +199,10 @@ async def transaction_test( args.append({"four": 4}) transaction.zremrangebyscore(key8, InfBound.NEG_INF, InfBound.POS_INF) args.append(1) + + transaction.pfadd(key11, ["a", "b", "c"]) + args.append(1) + return args From 7bfa2cba0ae5eabe23b18077b5c7c60d02ad9b47 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Mon, 22 Apr 2024 19:56:28 -0700 Subject: [PATCH 2/4] Apply suggestions from code review Signed-off-by: Yury-Fridlyand Co-authored-by: Shoham Elias <116083498+shohamazon@users.noreply.github.com> --- python/python/glide/async_commands/core.py | 10 +++++----- python/python/glide/async_commands/transaction.py | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/python/glide/async_commands/core.py b/python/python/glide/async_commands/core.py index c0b9ed16fb..0f79c0b532 100644 --- a/python/python/glide/async_commands/core.py +++ b/python/python/glide/async_commands/core.py @@ -2268,23 +2268,23 @@ async def pfadd(self, key: str, elements: List[str]) -> int: Adds all elements to the HyperLogLog data structure stored at the specified `key`. Creates a new structure if the `key` does not exist. - When no `elements` are provided, and `key` exists and is a HyperLogLog, then no operation is performed. + When no elements are provided, and `key` exists and is a HyperLogLog, then no operation is performed. If `key` does not exist, then the HyperLogLog structure is created. See https://redis.io/commands/pfadd/ for more details. Args: - key (str): The `key` of the HyperLogLog data structure to add elements into. + key (str): The key of the HyperLogLog data structure to add elements into. elements (List[str]): An list of members to add to the HyperLogLog stored at `key`. Returns: int: If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is - altered, then returns `1`. Otherwise, returns `0`. + altered, then returns 1. Otherwise, returns 0. Examples: - >>> client.pfadd("hll_1", ["a", "b", "c" ]) + >>> await client.pfadd("hll_1", ["a", "b", "c" ]) 1 # A data structure was created or modified - >>> client.pfadd("hll_2", []) + >>> await client.pfadd("hll_2", []) 1 # A new empty data structure was created """ return cast( diff --git a/python/python/glide/async_commands/transaction.py b/python/python/glide/async_commands/transaction.py index 2b685ddccf..d5694925fc 100644 --- a/python/python/glide/async_commands/transaction.py +++ b/python/python/glide/async_commands/transaction.py @@ -1715,18 +1715,18 @@ def pfadd(self: TTransaction, key: str, elements: List[str]) -> TTransaction: Adds all elements to the HyperLogLog data structure stored at the specified `key`. Creates a new structure if the `key` does not exist. - When no `elements` are provided, and `key` exists and is a HyperLogLog, then no operation is performed. + When no elements are provided, and `key` exists and is a HyperLogLog, then no operation is performed. If `key` does not exist, then the HyperLogLog structure is created. See https://redis.io/commands/pfadd/ for more details. Args: - key (str): The `key` of the HyperLogLog data structure to add elements into. + key (str): The key of the HyperLogLog data structure to add elements into. elements (List[str]): An list of members to add to the HyperLogLog stored at `key`. Commands response: int: If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is - altered, then returns `1`. Otherwise, returns `0`. + altered, then returns 1. Otherwise, returns 0. """ return self.append_command(RequestType.PfAdd, [key] + elements) From 78af3d8ea209cfb063e65fd7dec7b7e2cf7f4271 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Tue, 23 Apr 2024 17:48:22 -0700 Subject: [PATCH 3/4] PR comments. Signed-off-by: Yury-Fridlyand --- python/python/glide/async_commands/core.py | 2 +- python/python/glide/async_commands/transaction.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/python/glide/async_commands/core.py b/python/python/glide/async_commands/core.py index 0f79c0b532..76adf4dec7 100644 --- a/python/python/glide/async_commands/core.py +++ b/python/python/glide/async_commands/core.py @@ -2275,7 +2275,7 @@ async def pfadd(self, key: str, elements: List[str]) -> int: Args: key (str): The key of the HyperLogLog data structure to add elements into. - elements (List[str]): An list of members to add to the HyperLogLog stored at `key`. + elements (List[str]): A list of members to add to the HyperLogLog stored at `key`. Returns: int: If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is diff --git a/python/python/glide/async_commands/transaction.py b/python/python/glide/async_commands/transaction.py index d5694925fc..832bf5398f 100644 --- a/python/python/glide/async_commands/transaction.py +++ b/python/python/glide/async_commands/transaction.py @@ -1722,7 +1722,7 @@ def pfadd(self: TTransaction, key: str, elements: List[str]) -> TTransaction: Args: key (str): The key of the HyperLogLog data structure to add elements into. - elements (List[str]): An list of members to add to the HyperLogLog stored at `key`. + elements (List[str]): A list of members to add to the HyperLogLog stored at `key`. Commands response: int: If the HyperLogLog is newly created, or if the HyperLogLog approximated cardinality is From eec360a5dcc39bc13766b19654990d3fa0e27aa0 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Tue, 23 Apr 2024 17:57:52 -0700 Subject: [PATCH 4/4] PR comments. Signed-off-by: Yury-Fridlyand --- python/python/glide/async_commands/core.py | 2 -- python/python/glide/async_commands/transaction.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/python/python/glide/async_commands/core.py b/python/python/glide/async_commands/core.py index 76adf4dec7..456944d4bb 100644 --- a/python/python/glide/async_commands/core.py +++ b/python/python/glide/async_commands/core.py @@ -2267,9 +2267,7 @@ async def pfadd(self, key: str, elements: List[str]) -> int: """ Adds all elements to the HyperLogLog data structure stored at the specified `key`. Creates a new structure if the `key` does not exist. - When no elements are provided, and `key` exists and is a HyperLogLog, then no operation is performed. - If `key` does not exist, then the HyperLogLog structure is created. See https://redis.io/commands/pfadd/ for more details. diff --git a/python/python/glide/async_commands/transaction.py b/python/python/glide/async_commands/transaction.py index 832bf5398f..7b27757446 100644 --- a/python/python/glide/async_commands/transaction.py +++ b/python/python/glide/async_commands/transaction.py @@ -1714,9 +1714,7 @@ def pfadd(self: TTransaction, key: str, elements: List[str]) -> TTransaction: """ Adds all elements to the HyperLogLog data structure stored at the specified `key`. Creates a new structure if the `key` does not exist. - When no elements are provided, and `key` exists and is a HyperLogLog, then no operation is performed. - If `key` does not exist, then the HyperLogLog structure is created. See https://redis.io/commands/pfadd/ for more details.