python-redis封装实例
# -*- coding: utf-8 -*-
# !/usr/bin/env python3
# @Author: eddyhhu
# @Time: 2023-01-30
# @Document: RedisCliet Base Class.
import functools
import logging
import time
import traceback
from redis import StrictRedis
from redis.exceptions import ConnectionError
from typing import (
Union,
)
LOG = logging.getLogger()
REDIS_MAX_RETRY_TIMES = 3
REDIS_WAIT_TIME = 1
def retry(max_retry_times=1, wait_time=0.1):
def _(func):
@functools.wraps(func)
def wrap_func(*l, **kwargs):
for i in range(max_retry_times):
try:
return func(*l, **kwargs)
except ConnectionError as conn_error:
LOG.error(f"redis conn error:{conn_error}")
LOG.error(traceback.format_exc())
if i == (max_retry_times - 1):
raise Exception(
f"redis client command `{func.__name__}` error!")
except Exception as e:
LOG.error(f"redis unknown error:{e}")
LOG.error(traceback.format_exc())
if i == (max_retry_times - 1):
raise Exception(
f"redis client command `{func.__name__}` error!")
time.sleep(wait_time)
return wrap_func
return _
class RedisClient(object):
"""If the method you want to use is not defined, it is recommended to implement this method and call it yourself."""
def __init__(self, config) -> None:
self._conn = None
self.config = config
def execute(self, cmd, *vargs):
"""The entrypoint to execute the command"""
self.create()
try:
if hasattr(self, '_%s' % cmd):
return getattr(self, '_%s' % cmd)(*vargs)
else:
return getattr(self._conn, cmd)(*vargs)
except Exception:
self.destroy()
raise
def create(self):
"""create redis connection"""
if self._conn is None:
self._conn = StrictRedis(**self.config)
def destroy(self):
"""destory redis connection"""
self._conn = None
def decode(self, data: bytes):
"""bytes --> str"""
if data is None:
return None
return str(data, encoding='utf-8')
def decode_dict(self, data: dict):
"""Dict[bytes] --> Dict[str]"""
if data is None:
return None
return {k.decode('utf-8'): v.decode('utf-8') for k, v in data.items()}
def decode_iterable(self, data: Union[list, set, tuple]):
"""
List[bytes] --> List[str]
Tuple[bytes] --> Tuple[str]
Set[bytes] --> Set[str]
"""
if data is None:
return None
if isinstance(data, list):
return list(map(self.decode, data))
elif isinstance(data, set):
return set(map(self.decode, data))
elif isinstance(data, tuple):
return tuple(map(self.decode, data))
else:
return list(map(self.decode, data))
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _set(self, name, value):
return self._conn.set(name, value)
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _get(self, name):
return self.decode(self._conn.get(name))
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _setnx(self, name, value):
return self._conn.setnx(name, value)
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _lpush(self, name, *values):
return self._conn.lpush(name, *values)
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _lrange(self, name, start, end):
return self.decode_iterable(self._conn.lrange(name, start, end))
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _incr(self, name, amount=1):
return self._conn.incr(name, amount)
_incrby = _incr
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _hgetall(self, name):
return self.decode_dict(self._conn.hgetall(name))
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _sadd(self, name, *values):
return self._conn.sadd(name, *values)
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _sismember(self, name, value):
return self._conn.sismember(name, value)
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _smembers(self, name):
return self.decode_iterable(self._conn.smembers(name))
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _srem(self, name, *values):
return self._conn.srem(name, *values)
@retry(max_retry_times=REDIS_MAX_RETRY_TIMES, wait_time=REDIS_WAIT_TIME)
def _delete(self, *names):
return self._conn.delete(*names)
if __name__ == "__main__":
config = {
"host": "127.0.0.1",
"port": 6379,
"db": 0,
}
redis_cli = RedisClient(config)
print(redis_cli.execute("set", "key1", "val1"))
print(redis_cli.execute("get", "key1"))
print(redis_cli.execute("lpush", "alist", "1"))
print(redis_cli.execute("lrange", "alist", 0, -1))
print(redis_cli.execute("setnx", "key41", "val4"))
print(redis_cli.execute("incr", "key333"))
print(redis_cli.execute("incrby", "key444"))
print(redis_cli.execute("hgetall", "myhash"))
print(redis_cli.execute("sismember", "set", 1))
print(redis_cli.execute("delete", "key1"))
print(redis_cli.execute("srem", "set", 1))
print(redis_cli.execute("sismember", "set", 1))
print(redis_cli.execute("sadd", "set", 6))
print(redis_cli.execute("sismember", "set", 6))
print(redis_cli.execute("smembers", "set"))
print("test undefined method...")
print(f'rpush: {redis_cli.execute("rpush", "alist", 10)}')