Skip to content

Commit

Permalink
Python: add OBJECT FREQ command (valkey-io#1472)
Browse files Browse the repository at this point in the history
Python: add OBJECT FREQ command (#311)
  • Loading branch information
aaron-congo authored and cyip10 committed Jun 24, 2024
1 parent 54901a3 commit 503aab3
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#### Changes
* Python: Added OBJECT ENCODING command ([#1471](https://github.com/aws/glide-for-redis/pull/1471))
* Python: Added OBJECT FREQ command ([#1472](https://github.com/aws/glide-for-redis/pull/1472))

## 0.4.0 (2024-05-26)

Expand Down
22 changes: 22 additions & 0 deletions python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3544,3 +3544,25 @@ async def object_encoding(self, key: str) -> Optional[str]:
Optional[str],
await self._execute_command(RequestType.ObjectEncoding, [key]),
)

async def object_freq(self, key: str) -> int:
"""
Returns the logarithmic access frequency counter of a Redis object stored at `key`.
See https://valkey.io/commands/object-freq for more details.
Args:
key (str): The key of the object to get the logarithmic access frequency counter of.
Returns:
int: If `key` exists, returns the logarithmic access frequency counter of the object stored at `key` as an
integer. Otherwise, returns None.
Examples:
>>> await client.object_freq("my_hash")
2 # The logarithmic access frequency counter of "my_hash" has a value of 2.
"""
return cast(
int,
await self._execute_command(RequestType.ObjectFreq, [key]),
)
15 changes: 15 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -2475,6 +2475,21 @@ def object_encoding(self: TTransaction, key: str) -> TTransaction:
"""
return self.append_command(RequestType.ObjectEncoding, [key])

def object_freq(self: TTransaction, key: str) -> TTransaction:
"""
Returns the logarithmic access frequency counter of a Redis object stored at `key`.
See https://valkey.io/commands/object-freq for more details.
Args:
key (str): The key of the object to get the logarithmic access frequency counter of.
Command response:
int: If `key` exists, returns the logarithmic access frequency counter of the object stored at `key` as an
integer. Otherwise, returns None.
"""
return self.append_command(RequestType.ObjectFreq, [key])


class Transaction(BaseTransaction):
"""
Expand Down
20 changes: 20 additions & 0 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3393,6 +3393,26 @@ async def test_object_encoding(self, redis_client: TRedisClient):
assert await redis_client.xadd(stream_key, [("field", "value")]) is not None
assert await redis_client.object_encoding(stream_key) == "stream"

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_object_freq(self, redis_client: TRedisClient):
key = get_random_string(10)
non_existing_key = get_random_string(10)
maxmemory_policy_key = "maxmemory-policy"
config = await redis_client.config_get([maxmemory_policy_key])
maxmemory_policy = cast(str, config.get(maxmemory_policy_key))

try:
assert (
await redis_client.config_set({maxmemory_policy_key: "allkeys-lfu"})
== OK
)
assert await redis_client.object_freq(non_existing_key) is None
assert await redis_client.set(key, "") == OK
assert await redis_client.object_freq(key) >= 0
finally:
await redis_client.config_set({maxmemory_policy_key: maxmemory_policy})


class TestMultiKeyCommandCrossSlot:
@pytest.mark.parametrize("cluster_mode", [True])
Expand Down
29 changes: 28 additions & 1 deletion python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0

from datetime import datetime, timezone
from typing import List, Union
from typing import List, Union, cast

import pytest
from glide import RequestError
Expand Down Expand Up @@ -501,3 +501,30 @@ async def test_transaction_chaining_calls(self, redis_client: TRedisClient):
transaction.set(key, "value").get(key).delete([key])

assert await redis_client.exec(transaction) == [OK, "value", 1]

# object_freq is not tested in transaction_test as it requires that we set and later restore the max memory policy
@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_transaction_object_freq(
self, redis_client: TRedisClient, cluster_mode: bool
):
string_key = get_random_string(10)
maxmemory_policy_key = "maxmemory-policy"
config = await redis_client.config_get([maxmemory_policy_key])
maxmemory_policy = cast(str, config.get(maxmemory_policy_key))

try:
transaction = ClusterTransaction() if cluster_mode else Transaction()
transaction.config_set({maxmemory_policy_key: "allkeys-lfu"})
transaction.set(string_key, "foo")
transaction.object_freq(string_key)

response = await redis_client.exec(transaction)
assert response is not None
assert len(response) == 3
assert response[0] == OK
assert response[1] == OK
frequency = cast(int, response[2])
assert frequency >= 0
finally:
await redis_client.config_set({maxmemory_policy_key: maxmemory_policy})

0 comments on commit 503aab3

Please sign in to comment.