From e30a94643cd5201429398ace9fbf3d9e9e7b9e0d Mon Sep 17 00:00:00 2001 From: Shoham Elias <116083498+shohamazon@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:19:20 +0200 Subject: [PATCH] Python: adds TIME command (#1147) --- CHANGELOG.md | 2 +- .../glide/async_commands/cluster_commands.py | 30 ++++++++++++++++++- .../async_commands/standalone_commands.py | 20 +++++++++++++ python/python/tests/test_async_client.py | 12 ++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 716d373c31..42da0b406b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ * Node: Added ZREMRANGEBYRANK command ([#924](https://github.com/aws/glide-for-redis/pull/924)) * Node: Added Xadd, Xtrim commands. ([#1057](https://github.com/aws/glide-for-redis/pull/1057)) * Python: Added json module and JSON.SET JSON.GET commands ([#1056](https://github.com/aws/glide-for-redis/pull/1056)) -* Node: Added Time command. ([#1114](https://github.com/aws/glide-for-redis/pull/1114)) +* Python, Node: Added Time command ([#1147](https://github.com/aws/glide-for-redis/pull/1147)), ([#1114](https://github.com/aws/glide-for-redis/pull/1114)) * Python, Node: Added LINDEX command ([#1058](https://github.com/aws/glide-for-redis/pull/1058), [#999](https://github.com/aws/glide-for-redis/pull/999)) * Python: Added ZRANK command ([#1065](https://github.com/aws/glide-for-redis/pull/1065)) * Core: Enabled Cluster Mode periodic checks by default ([#1089](https://github.com/aws/glide-for-redis/pull/1089)) diff --git a/python/python/glide/async_commands/cluster_commands.py b/python/python/glide/async_commands/cluster_commands.py index 295fb57114..24531c6028 100644 --- a/python/python/glide/async_commands/cluster_commands.py +++ b/python/python/glide/async_commands/cluster_commands.py @@ -252,7 +252,7 @@ async def client_getname( >>> await client.client_getname() 'Connection Name' >>> await client.client_getname(AllNodes()) - {'addr': 'Connection Name'', 'addr2': 'Connection Name', 'addr3': 'Connection Name'} + {'addr': 'Connection Name', 'addr2': 'Connection Name', 'addr3': 'Connection Name'} """ return cast( TClusterResponse[Optional[str]], @@ -277,3 +277,31 @@ async def dbsize(self, route: Optional[Route] = None) -> int: 10 # Indicates there are 10 keys in the cluster. """ return cast(int, await self._execute_command(RequestType.DBSize, [], route)) + + async def time(self, route: Optional[Route] = None) -> TClusterResponse[List[str]]: + """ + Returns the server time. + + See https://redis.io/commands/time/ for more details. + + Args: + route (Optional[Route]): The command will be routed to a random node, unless `route` is provided, + in which case the client will route the command to the nodes defined by `route`. + + Returns: + TClusterResponse[Optional[str]]: The current server time as a two items `array`: + A Unix timestamp and the amount of microseconds already elapsed in the current second. + The returned `array` is in a [Unix timestamp, Microseconds already elapsed] format. + When specifying a route other than a single node, response will be: + {Address (str) : response (List[str]) , ... } with type of Dict[str, List[str]]. + + Examples: + >>> await client.time() + ['1710925775', '913580'] + >>> await client.client_getname(AllNodes()) + {'addr': ['1710925775', '913580'], 'addr2': ['1710925775', '913580'], 'addr3': ['1710925775', '913580']} + """ + return cast( + TClusterResponse[List[str]], + await self._execute_command(RequestType.Time, [], route), + ) diff --git a/python/python/glide/async_commands/standalone_commands.py b/python/python/glide/async_commands/standalone_commands.py index 57dd88522e..5839ddf887 100644 --- a/python/python/glide/async_commands/standalone_commands.py +++ b/python/python/glide/async_commands/standalone_commands.py @@ -206,3 +206,23 @@ async def dbsize(self) -> int: 10 # Indicates there are 10 keys in the current database. """ return cast(int, await self._execute_command(RequestType.DBSize, [])) + + async def time(self) -> List[str]: + """ + Returns the server time. + + See https://redis.io/commands/time/ for more details. + + Returns: + List[str]: The current server time as a two items `array`: + A Unix timestamp and the amount of microseconds already elapsed in the current second. + The returned `array` is in a [Unix timestamp, Microseconds already elapsed] format. + + Examples: + >>> await client.time() + ['1710925775', '913580'] + """ + return cast( + List[str], + await self._execute_command(RequestType.Time, []), + ) diff --git a/python/python/tests/test_async_client.py b/python/python/tests/test_async_client.py index faa6769c50..761ca7ccc9 100644 --- a/python/python/tests/test_async_client.py +++ b/python/python/tests/test_async_client.py @@ -1580,6 +1580,18 @@ async def test_dbsize(self, redis_client: TRedisClient): assert await redis_client.select(1) == OK assert await redis_client.dbsize() == 0 + @pytest.mark.parametrize("cluster_mode", [True, False]) + @pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3]) + async def test_time(self, redis_client: TRedisClient): + current_time = int(time.time()) - 1 + result = await redis_client.time() + assert len(result) == 2 + assert isinstance(result, list) + assert isinstance(result[0], str) + assert isinstance(result[1], str) + assert int(result[0]) > current_time + assert 0 < int(result[1]) < 1000000 + class TestCommandsUnitTests: def test_expiry_cmd_args(self):