Skip to content

Commit

Permalink
Python: Added EXPIRETIME, PEXPIRETIME commands (valkey-io#1587)
Browse files Browse the repository at this point in the history
  • Loading branch information
shohamazon authored and cyip10 committed Jun 24, 2024
1 parent 5535511 commit 87ef699
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* Python: Added HSTRLEN command ([#1564](https://github.com/aws/glide-for-redis/pull/1564))
* Python: Added MSETNX command ([#1565](https://github.com/aws/glide-for-redis/pull/1565))
* Python: Added MOVE command ([#1566](https://github.com/aws/glide-for-redis/pull/1566))
* Python: Added EXPIRETIME, PEXPIRETIME commands ([#1587](https://github.com/aws/glide-for-redis/pull/1587))
* Python: Added LSET command ([#1584](https://github.com/aws/glide-for-redis/pull/1584))
* Node: Added OBJECT IDLETIME command ([#1567](https://github.com/aws/glide-for-redis/pull/1567))
* Node: Added OBJECT REFCOUNT command ([#1568](https://github.com/aws/glide-for-redis/pull/1568))
Expand Down
55 changes: 55 additions & 0 deletions python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2424,6 +2424,61 @@ async def pexpireat(
)
return cast(bool, await self._execute_command(RequestType.PExpireAt, args))

async def expiretime(self, key: str) -> int:
"""
Returns the absolute Unix timestamp (since January 1, 1970) at which
the given `key` will expire, in seconds.
To get the expiration with millisecond precision, use `pexpiretime`.
See https://valkey.io/commands/expiretime/ for details.
Args:
key (str): The `key` to determine the expiration value of.
Returns:
int: The expiration Unix timestamp in seconds, -2 if `key` does not exist or -1 if `key` exists but has no associated expire.
Examples:
>>> await client.expiretime("my_key")
-2 # 'my_key' doesn't exist.
>>> await client.set("my_key", "value")
>>> await client.expiretime("my_key")
-1 # 'my_key' has no associate expiration.
>>> await client.expire("my_key", 60)
>>> await client.expiretime("my_key")
1718614954
Since: Redis version 7.0.0.
"""
return cast(int, await self._execute_command(RequestType.ExpireTime, [key]))

async def pexpiretime(self, key: str) -> int:
"""
Returns the absolute Unix timestamp (since January 1, 1970) at which
the given `key` will expire, in milliseconds.
See https://valkey.io/commands/pexpiretime/ for details.
Args:
key (str): The `key` to determine the expiration value of.
Returns:
int: The expiration Unix timestamp in milliseconds, -2 if `key` does not exist, or -1 if `key` exists but has no associated expiration.
Examples:
>>> await client.pexpiretime("my_key")
-2 # 'my_key' doesn't exist.
>>> await client.set("my_key", "value")
>>> await client.pexpiretime("my_key")
-1 # 'my_key' has no associate expiration.
>>> await client.expire("my_key", 60)
>>> await client.pexpiretime("my_key")
1718615446670
Since: Redis version 7.0.0.
"""
return cast(int, await self._execute_command(RequestType.PExpireTime, [key]))

async def ttl(self, key: str) -> int:
"""
Returns the remaining time to live of `key` that has a timeout.
Expand Down
35 changes: 35 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,41 @@ def pexpireat(
)
return self.append_command(RequestType.PExpireAt, args)

def expiretime(self: TTransaction, key: str) -> TTransaction:
"""
Returns the absolute Unix timestamp (since January 1, 1970) at which
the given `key` will expire, in seconds.
To get the expiration with millisecond precision, use `pexpiretime`.
See https://valkey.io/commands/expiretime/ for details.
Args:
key (str): The `key` to determine the expiration value of.
Commands response:
int: The expiration Unix timestamp in seconds, -2 if `key` does not exist or -1 if `key` exists but has no associated expire.
Since: Redis version 7.0.0.
"""
return self.append_command(RequestType.ExpireTime, [key])

def pexpiretime(self: TTransaction, key: str) -> TTransaction:
"""
Returns the absolute Unix timestamp (since January 1, 1970) at which
the given `key` will expire, in milliseconds.
See https://valkey.io/commands/pexpiretime/ for details.
Args:
key (str): The `key` to determine the expiration value of.
Commands response:
int: The expiration Unix timestamp in milliseconds, -2 if `key` does not exist, or -1 if `key` exists but has no associated expiration.
Since: Redis version 7.0.0.
"""
return self.append_command(RequestType.PExpireTime, [key])

def ttl(self: TTransaction, key: str) -> TTransaction:
"""
Returns the remaining time to live of `key` that has a timeout.
Expand Down
34 changes: 30 additions & 4 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1982,11 +1982,16 @@ async def test_unlink(self, redis_client: TRedisClient):

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_expire_pexpire_ttl_with_positive_timeout(
async def test_expire_pexpire_ttl_expiretime_pexpiretime_with_positive_timeout(
self, redis_client: TRedisClient
):
key = get_random_string(10)
assert await redis_client.set(key, "foo") == OK
assert await redis_client.ttl(key) == -1

if not await check_if_server_version_lt(redis_client, "7.0.0"):
assert await redis_client.expiretime(key) == -1
assert await redis_client.pexpiretime(key) == -1

assert await redis_client.expire(key, 10) == 1
assert await redis_client.ttl(key) in range(11)
Expand All @@ -2003,6 +2008,8 @@ async def test_expire_pexpire_ttl_with_positive_timeout(
assert await redis_client.expire(key, 15)
else:
assert await redis_client.expire(key, 15, ExpireOptions.HasExistingExpiry)
assert await redis_client.expiretime(key) > int(time.time())
assert await redis_client.pexpiretime(key) > (int(time.time()) * 1000)
assert await redis_client.ttl(key) in range(16)

@pytest.mark.parametrize("cluster_mode", [True, False])
Expand Down Expand Up @@ -2037,31 +2044,47 @@ async def test_expireat_pexpireat_ttl_with_positive_timeout(

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_expire_pexpire_expireat_pexpireat_past_or_negative_timeout(
async def test_expire_pexpire_expireat_pexpireat_expiretime_pexpiretime_past_or_negative_timeout(
self, redis_client: TRedisClient
):
key = get_random_string(10)
assert await redis_client.set(key, "foo") == OK
assert await redis_client.ttl(key) == -1

assert await redis_client.expire(key, -10) == 1
if not await check_if_server_version_lt(redis_client, "7.0.0"):
assert await redis_client.expiretime(key) == -1
assert await redis_client.pexpiretime(key) == -1

assert await redis_client.expire(key, -10) is True
assert await redis_client.ttl(key) == -2
if not await check_if_server_version_lt(redis_client, "7.0.0"):
assert await redis_client.expiretime(key) == -2
assert await redis_client.pexpiretime(key) == -2

assert await redis_client.set(key, "foo") == OK
assert await redis_client.pexpire(key, -10000)
assert await redis_client.ttl(key) == -2
if not await check_if_server_version_lt(redis_client, "7.0.0"):
assert await redis_client.expiretime(key) == -2
assert await redis_client.pexpiretime(key) == -2

assert await redis_client.set(key, "foo") == OK
assert await redis_client.expireat(key, int(time.time()) - 50) == 1
assert await redis_client.ttl(key) == -2
if not await check_if_server_version_lt(redis_client, "7.0.0"):
assert await redis_client.expiretime(key) == -2
assert await redis_client.pexpiretime(key) == -2

assert await redis_client.set(key, "foo") == OK
assert await redis_client.pexpireat(key, int(time.time() * 1000) - 50000)
assert await redis_client.ttl(key) == -2
if not await check_if_server_version_lt(redis_client, "7.0.0"):
assert await redis_client.expiretime(key) == -2
assert await redis_client.pexpiretime(key) == -2

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_expire_pexpire_expireAt_pexpireAt_ttl_non_existing_key(
async def test_expire_pexpire_expireAt_pexpireAt_ttl_expiretime_pexpiretime_non_existing_key(
self, redis_client: TRedisClient
):
key = get_random_string(10)
Expand All @@ -2071,6 +2094,9 @@ async def test_expire_pexpire_expireAt_pexpireAt_ttl_non_existing_key(
assert await redis_client.expireat(key, int(time.time()) + 50) == 0
assert not await redis_client.pexpireat(key, int(time.time() * 1000) + 50000)
assert await redis_client.ttl(key) == -2
if not await check_if_server_version_lt(redis_client, "7.0.0"):
assert await redis_client.expiretime(key) == -2
assert await redis_client.pexpiretime(key) == -2

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
Expand Down
7 changes: 7 additions & 0 deletions python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ async def transaction_test(

transaction.persist(key)
args.append(False)
transaction.ttl(key)
args.append(-1)
if not await check_if_server_version_lt(redis_client, "7.0.0"):
transaction.expiretime(key)
args.append(-1)
transaction.pexpiretime(key)
args.append(-1)

transaction.rename(key, key2)
args.append(OK)
Expand Down

0 comments on commit 87ef699

Please sign in to comment.