Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: Add PFADD command. #1315

Merged
merged 6 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Python: Added ZREMRANGEBYLEX command ([#1306](https://github.com/aws/glide-for-redis/pull/1306))
* Python: Added LINSERT command ([#1304](https://github.com/aws/glide-for-redis/pull/1304))
* Python: Added GEOPOS command ([#1301](https://github.com/aws/glide-for-redis/pull/1301))
* Python: Added PFADD command ([#1315](https://github.com/aws/glide-for-redis/pull/1315))

#### Fixes
* Python: Fix typing error "‘type’ object is not subscriptable" ([#1203](https://github.com/aws/glide-for-redis/pull/1203))
Expand Down
27 changes: 27 additions & 0 deletions python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2355,3 +2355,30 @@ 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.

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]): 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
altered, then returns 1. Otherwise, returns 0.

Examples:
>>> await client.pfadd("hll_1", ["a", "b", "c" ])
1 # A data structure was created or modified
>>> await client.pfadd("hll_2", [])
1 # A new empty data structure was created
"""
return cast(
int,
await self._execute_command(RequestType.PfAdd, [key] + elements),
)
18 changes: 18 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,24 @@ 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.

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]): 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
altered, then returns 1. Otherwise, returns 0.
"""
return self.append_command(RequestType.PfAdd, [key] + elements)


class Transaction(BaseTransaction):
"""
Expand Down
13 changes: 13 additions & 0 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,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):
Expand Down
5 changes: 4 additions & 1 deletion python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,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))
key10 = "{{{}}}:{}".format(keyslot, get_random_string(3)) # list
key10 = "{{{}}}:{}".format(keyslot, get_random_string(3)) # hyper log log
acarbonetto marked this conversation as resolved.
Show resolved Hide resolved

value = datetime.now(timezone.utc).strftime("%m/%d/%Y, %H:%M:%S")
value2 = get_random_string(5)
Expand Down Expand Up @@ -212,6 +212,9 @@ async def transaction_test(
transaction.zremrangebylex(key8, InfBound.NEG_INF, InfBound.POS_INF)
args.append(0)

transaction.pfadd(key10, ["a", "b", "c"])
args.append(1)

transaction.geoadd(
key9,
{
Expand Down
Loading