diff options
| author | Vamsi Atluri <vamc19@gmail.com> | 2016-12-11 23:54:54 +0530 |
|---|---|---|
| committer | Roey Prat <roey.prat@redislabs.com> | 2020-07-01 17:03:18 +0300 |
| commit | 2eef463380570aab5a32b2355a1323dee4613294 (patch) | |
| tree | 532f6f182fd29836842d672a3f0769b498cf1804 | |
| parent | 67c2fca8bb2208d57f74ad34da52c0ca2d9e29dc (diff) | |
| download | redis-py-2eef463380570aab5a32b2355a1323dee4613294.tar.gz | |
Support for loading, unloading and listing Redis Modules
| -rwxr-xr-x | redis/client.py | 32 | ||||
| -rwxr-xr-x | redis/connection.py | 13 | ||||
| -rw-r--r-- | redis/exceptions.py | 4 |
3 files changed, 49 insertions, 0 deletions
diff --git a/redis/client.py b/redis/client.py index 9de90fb..09b320b 100755 --- a/redis/client.py +++ b/redis/client.py @@ -22,6 +22,7 @@ from redis.exceptions import ( ResponseError, TimeoutError, WatchError, + ModuleError ) SYM_EMPTY = b'' @@ -516,6 +517,12 @@ def parse_acl_getuser(response, **options): return data +def parse_module_result(response): + if isinstance(response, ModuleError): + raise response + return True + + class Redis(object): """ Implementation of the Redis protocol. @@ -656,6 +663,9 @@ class Redis(object): 'XPENDING': parse_xpending, 'ZADD': parse_zadd, 'ZSCAN': parse_zscan, + 'MODULE LOAD': parse_module_result, + 'MODULE UNLOAD': parse_module_result, + 'MODULE LIST': lambda r: [pairs_to_dict(l) for l in r] } ) @@ -3306,6 +3316,28 @@ class Redis(object): return self.execute_command(command, *pieces, **kwargs) + # MODULE COMMANDS + def module_load(self, path): + """ + Loads the module from ``path``. + Raises ``ModuleError`` if a module is not found at ``path``. + """ + return self.execute_command('MODULE LOAD', path) + + def module_unload(self, name): + """ + Unloads the module ``name``. + Raises ``ModuleError`` if ``name`` is not in loaded modules. + """ + return self.execute_command('MODULE UNLOAD', name) + + def module_list(self): + """ + Returns a list of dictionaries containing the name and version of + all loaded modules. + """ + return self.execute_command('MODULE LIST') + StrictRedis = Redis diff --git a/redis/connection.py b/redis/connection.py index e3c9b66..6f1f765 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -29,6 +29,7 @@ from redis.exceptions import ( RedisError, ResponseError, TimeoutError, + ModuleError ) from redis.utils import HIREDIS_AVAILABLE @@ -90,6 +91,14 @@ SYM_EMPTY = b'' SERVER_CLOSED_CONNECTION_ERROR = "Connection closed by server." SENTINEL = object() +MODULE_LOAD_ERROR = 'Error loading the extension. ' \ + 'Please check the server logs.' +NO_SUCH_MODULE_ERROR = 'Error unloading module: no such module with that name' +MODULE_UNLOAD_NOT_POSSIBLE_ERROR = 'Error unloading module: operation not ' \ + 'possible.' +MODULE_EXPORTS_DATA_TYPES_ERROR = "Error unloading module: the module " \ + "exports one or more module-side data " \ + "types, can't unload" class Encoder(object): @@ -146,6 +155,10 @@ class BaseParser(object): # in uppercase 'wrong number of arguments for \'AUTH\' command': AuthenticationWrongNumberOfArgsError, + MODULE_LOAD_ERROR: ModuleError, + MODULE_EXPORTS_DATA_TYPES_ERROR: ModuleError, + NO_SUCH_MODULE_ERROR: ModuleError, + MODULE_UNLOAD_NOT_POSSIBLE_ERROR: ModuleError }, 'EXECABORT': ExecAbortError, 'LOADING': BusyLoadingError, diff --git a/redis/exceptions.py b/redis/exceptions.py index 760af66..245b333 100644 --- a/redis/exceptions.py +++ b/redis/exceptions.py @@ -57,6 +57,10 @@ class NoPermissionError(ResponseError): pass +class ModuleError(RedisError): + pass + + class LockError(RedisError, ValueError): "Errors acquiring or releasing a lock" # NOTE: For backwards compatability, this class derives from ValueError. |
