diff --git a/CHANGELOG.md b/CHANGELOG.md index e361369f0a..ee1e877d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ * Python: Added XREAD command ([#1644](https://github.com/aws/glide-for-redis/pull/1644)) * Python: Added XGROUP CREATE and XGROUP DESTROY commands ([#1646](https://github.com/aws/glide-for-redis/pull/1646)) * Python: Added XGROUP CREATECONSUMER and XGROUP DELCONSUMER commands ([#1658](https://github.com/aws/glide-for-redis/pull/1658)) +* Python: Added LOLWUT command ([#1657](https://github.com/aws/glide-for-redis/pull/1657)) ### Breaking Changes * Node: Update XREAD to return a Map of Map ([#1494](https://github.com/aws/glide-for-redis/pull/1494)) diff --git a/python/python/glide/async_commands/cluster_commands.py b/python/python/glide/async_commands/cluster_commands.py index a30ca943cc..3c35071e18 100644 --- a/python/python/glide/async_commands/cluster_commands.py +++ b/python/python/glide/async_commands/cluster_commands.py @@ -554,3 +554,40 @@ async def copy( bool, await self._execute_command(RequestType.Copy, args), ) + + async def lolwut( + self, + version: Optional[int] = None, + parameters: Optional[List[int]] = None, + route: Optional[Route] = None, + ) -> TClusterResponse[str]: + """ + Displays a piece of generative computer art and the Redis version. + + See https://valkey.io/commands/lolwut for more details. + + Args: + version (Optional[int]): Version of computer art to generate. + parameters (Optional[List[int]]): Additional set of arguments in order to change the output: + For version `5`, those are length of the line, number of squares per row, and number of squares per column. + For version `6`, those are number of columns and number of lines. + 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[str]: A piece of generative computer art along with the current Redis version. + + Examples: + >>> await client.lolwut(6, [40, 20], ALL_NODES); + "Redis ver. 7.2.3" # Indicates the current Redis version + """ + args = [] + if version is not None: + args.extend(["VERSION", str(version)]) + if parameters: + for var in parameters: + args.extend(str(var)) + return cast( + TClusterResponse[str], + await self._execute_command(RequestType.Lolwut, args, route), + ) diff --git a/python/python/glide/async_commands/standalone_commands.py b/python/python/glide/async_commands/standalone_commands.py index 7f006d39dc..a2b8ea4d62 100644 --- a/python/python/glide/async_commands/standalone_commands.py +++ b/python/python/glide/async_commands/standalone_commands.py @@ -503,3 +503,39 @@ async def copy( bool, await self._execute_command(RequestType.Copy, args), ) + + async def lolwut( + self, + version: Optional[int] = None, + parameters: Optional[List[int]] = None, + ) -> str: + """ + Displays a piece of generative computer art and the Redis version. + + See https://valkey.io/commands/lolwut for more details. + + Args: + version (Optional[int]): Version of computer art to generate. + parameters (Optional[List[int]]): Additional set of arguments in order to change the output: + For version `5`, those are length of the line, number of squares per row, and number of squares per column. + For version `6`, those are number of columns and number of lines. + + Returns: + str: A piece of generative computer art along with the current Redis version. + + Examples: + >>> await client.lolwut(6, [40, 20]); + "Redis ver. 7.2.3" # Indicates the current Redis version + >>> await client.lolwut(5, [30, 5, 5]); + "Redis ver. 7.2.3" # Indicates the current Redis version + """ + args = [] + if version is not None: + args.extend(["VERSION", str(version)]) + if parameters: + for var in parameters: + args.extend(str(var)) + return cast( + str, + await self._execute_command(RequestType.Lolwut, args), + ) diff --git a/python/python/glide/async_commands/transaction.py b/python/python/glide/async_commands/transaction.py index 5a3df10be1..1a821d8305 100644 --- a/python/python/glide/async_commands/transaction.py +++ b/python/python/glide/async_commands/transaction.py @@ -3632,6 +3632,33 @@ def getex( args.extend(expiry.get_cmd_args()) return self.append_command(RequestType.GetEx, args) + def lolwut( + self: TTransaction, + version: Optional[int] = None, + parameters: Optional[List[int]] = None, + ) -> TTransaction: + """ + Displays a piece of generative computer art and the Redis version. + + See https://valkey.io/commands/lolwut for more details. + + Args: + version (Optional[int]): Version of computer art to generate. + parameters (Optional[List[int]]): Additional set of arguments in order to change the output: + For version `5`, those are length of the line, number of squares per row, and number of squares per column. + For version `6`, those are number of columns and number of lines. + + Command Response: + str: A piece of generative computer art along with the current Redis version. + """ + args = [] + if version is not None: + args.extend(["VERSION", str(version)]) + if parameters: + for var in parameters: + args.extend(str(var)) + return self.append_command(RequestType.Lolwut, args) + class Transaction(BaseTransaction): """ diff --git a/python/python/tests/test_async_client.py b/python/python/tests/test_async_client.py index dcd919a296..26f54849a6 100644 --- a/python/python/tests/test_async_client.py +++ b/python/python/tests/test_async_client.py @@ -6075,6 +6075,39 @@ async def test_copy_database(self, redis_client: RedisClient): finally: assert await redis_client.select(0) == OK + @pytest.mark.parametrize("cluster_mode", [True, False]) + @pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3]) + async def test_lolwut(self, redis_client: TRedisClient): + result = await redis_client.lolwut() + assert "Redis ver. " in result + result = await redis_client.lolwut(parameters=[]) + assert "Redis ver. " in result + result = await redis_client.lolwut(parameters=[50, 20]) + assert "Redis ver. " in result + result = await redis_client.lolwut(6) + assert "Redis ver. " in result + result = await redis_client.lolwut(5, [30, 4, 4]) + assert "Redis ver. " in result + + if isinstance(redis_client, RedisClusterClient): + # test with multi-node route + result = await redis_client.lolwut(route=AllNodes()) + assert isinstance(result, dict) + for node_result in result.values(): + assert "Redis ver. " in node_result + + result = await redis_client.lolwut(parameters=[10, 20], route=AllNodes()) + assert isinstance(result, dict) + for node_result in result.values(): + assert "Redis ver. " in node_result + + # test with single-node route + result = await redis_client.lolwut(2, route=RandomNode()) + assert "Redis ver. " in node_result + + result = await redis_client.lolwut(2, [10, 20], RandomNode()) + assert "Redis ver. " in node_result + class TestMultiKeyCommandCrossSlot: @pytest.mark.parametrize("cluster_mode", [True]) diff --git a/python/python/tests/test_transaction.py b/python/python/tests/test_transaction.py index 268b776b38..aa7641a301 100644 --- a/python/python/tests/test_transaction.py +++ b/python/python/tests/test_transaction.py @@ -817,3 +817,15 @@ async def test_transaction_lastsave( lastsave_time = response[0] assert isinstance(lastsave_time, int) assert lastsave_time > yesterday_unix_time + + @pytest.mark.parametrize("cluster_mode", [True]) + @pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3]) + async def test_lolwut_transaction(self, redis_client: RedisClusterClient): + transaction = Transaction() + transaction.lolwut().lolwut(5).lolwut(parameters=[1, 2]).lolwut(6, [42]) + results = await redis_client.exec(transaction) + assert results is not None + + for element in results: + assert isinstance(element, str) + assert "Redis ver. " in element