updated Redis
This commit is contained in:
parent
c4013943a1
commit
6d77c34252
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/wag-managment-api-service-version-4" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/wag-managment-api-service-version-4" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import List, Dict, Optional
|
from typing import List, Dict, Optional
|
||||||
|
|
||||||
|
|
||||||
class EmailSendModel(BaseModel):
|
class EmailSendModel(BaseModel):
|
||||||
subject: str
|
subject: str
|
||||||
html: str = ""
|
html: str = ""
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,12 @@ class WagRedis:
|
||||||
REDIS_PASSWORD: str = "commercial_redis_password"
|
REDIS_PASSWORD: str = "commercial_redis_password"
|
||||||
REDIS_PORT: int = 11222
|
REDIS_PORT: int = 11222
|
||||||
REDIS_DB: int = 0
|
REDIS_DB: int = 0
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def as_dict(cls):
|
||||||
|
return dict(
|
||||||
|
host=WagRedis.REDIS_HOST,
|
||||||
|
password=WagRedis.REDIS_PASSWORD,
|
||||||
|
port=WagRedis.REDIS_PORT,
|
||||||
|
db=WagRedis.REDIS_DB,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
class HostConfig:
|
class HostConfig:
|
||||||
MAIN_HOST = "10.10.2.36" # http://10.10.2.36
|
MAIN_HOST = "10.10.2.36" # http://10.10.2.36
|
||||||
EMAIL_HOST = "10.10.2.34" # http://10.10.2.34
|
EMAIL_HOST = "10.10.2.34" # http://10.10.2.34
|
||||||
|
|
||||||
|
|
||||||
|
class MainConfig:
|
||||||
|
DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss Z"
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@ email_sender = EmailSender(**EmailConfig.as_dict())
|
||||||
class EmailService:
|
class EmailService:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def send_email(
|
def send_email(cls, params: EmailSendModel) -> bool:
|
||||||
cls,
|
|
||||||
params : EmailSendModel
|
|
||||||
) -> bool:
|
|
||||||
if not EmailConfig.EMAIL_SEND:
|
if not EmailConfig.EMAIL_SEND:
|
||||||
print("Email sending is disabled", params)
|
print("Email sending is disabled", params)
|
||||||
return False
|
return False
|
||||||
|
|
|
||||||
|
|
@ -1,102 +1,33 @@
|
||||||
import json
|
|
||||||
import arrow
|
import arrow
|
||||||
from typing import (
|
|
||||||
Any,
|
|
||||||
Optional,
|
|
||||||
List,
|
|
||||||
Dict,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
from typing import Optional, List, Dict, Union
|
||||||
|
|
||||||
|
from AllConfigs.main import MainConfig
|
||||||
from ApiServiceRedis.Redis.conn import redis_cli
|
from ApiServiceRedis.Redis.conn import redis_cli
|
||||||
|
from ApiServiceRedis.Redis.Models.base import RedisRow
|
||||||
from ApiServiceRedis.Redis.Models.response import RedisResponse
|
from ApiServiceRedis.Redis.Models.response import RedisResponse
|
||||||
|
|
||||||
|
|
||||||
class RedisRow:
|
|
||||||
|
|
||||||
key: str | bytes
|
|
||||||
value: Any
|
|
||||||
delimiter: str = "*"
|
|
||||||
expires_at: Optional[str] = None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def merge(cls, set_values: list[str | bytes]):
|
|
||||||
for key, set_value in enumerate(set_values):
|
|
||||||
set_value = str(set_value) if isinstance(set_value, bytes) else set_value
|
|
||||||
cls.key += f"{set_value}" if key == len(set_values) - 1 else f"{set_value}{cls.delimiter}"
|
|
||||||
cls.key = cls.key.encode()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def regex(cls, list_keys: list[str | bytes]):
|
|
||||||
search_regex = ""
|
|
||||||
for key, list_key in enumerate(list_keys):
|
|
||||||
list_key = list_key.decode() if isinstance(list_key, bytes) else str(list_key)
|
|
||||||
if key == 0 and list_key:
|
|
||||||
search_regex += f"{list_key}{cls.delimiter}*"
|
|
||||||
elif key == len(list_keys) - 1 and list_key:
|
|
||||||
search_regex += f"*{cls.delimiter}{list_key}"
|
|
||||||
else:
|
|
||||||
if list_key:
|
|
||||||
search_regex += f"*{cls.delimiter}{list_key}{cls.delimiter}*"
|
|
||||||
return search_regex
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def parse(cls):
|
|
||||||
return cls.key.split(cls.delimiter) if cls.key else []
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def feed(cls, value: Any):
|
|
||||||
cls.value = json.dumps(value)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def modify(cls, add_dict):
|
|
||||||
value = cls.data or {}
|
|
||||||
cls.feed({**value, **add_dict})
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def remove(cls, key):
|
|
||||||
value = cls.data or {}
|
|
||||||
value.pop(key)
|
|
||||||
cls.feed(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def keys(self):
|
|
||||||
return self.key if isinstance(self.key, str) else self.key.decode()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def redis_key(self):
|
|
||||||
return self.key if isinstance(self.key, bytes) else self.key.encode()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def data(self):
|
|
||||||
return json.loads(self.value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def as_dict(self):
|
|
||||||
return {
|
|
||||||
"keys": self.keys,
|
|
||||||
"value": self.data,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class RedisActions:
|
class RedisActions:
|
||||||
|
"""Class for handling Redis operations with JSON data."""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_expiry_time(cls, expiry_kwargs: dict) -> int:
|
def get_expiry_time(cls, expiry_kwargs: Dict[str, int]) -> int:
|
||||||
expiry_time = 0
|
"""Calculate expiry time in seconds from kwargs."""
|
||||||
if "days" in expiry_kwargs:
|
time_multipliers = {"days": 86400, "hours": 3600, "minutes": 60, "seconds": 1}
|
||||||
expiry_time += int(expiry_kwargs["days"]) * 24 * 60 * 60
|
return sum(
|
||||||
if "hours" in expiry_kwargs:
|
int(expiry_kwargs.get(unit, 0)) * multiplier
|
||||||
expiry_time += int(expiry_kwargs["hours"]) * 60 * 60
|
for unit, multiplier in time_multipliers.items()
|
||||||
if "minutes" in expiry_kwargs:
|
)
|
||||||
expiry_time += int(expiry_kwargs["minutes"]) * 60
|
|
||||||
if "seconds" in expiry_kwargs:
|
|
||||||
expiry_time += int(expiry_kwargs["seconds"])
|
|
||||||
return expiry_time
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_json(
|
def set_json(
|
||||||
cls, list_keys: list[str | bytes], value: Optional[dict | list], expires: Optional[dict] = None
|
cls,
|
||||||
):
|
list_keys: List[Union[str, bytes]],
|
||||||
|
value: Optional[Union[Dict, List]],
|
||||||
|
expires: Optional[Dict[str, int]] = None,
|
||||||
|
) -> RedisResponse:
|
||||||
|
"""Set JSON value in Redis with optional expiry."""
|
||||||
redis_row = RedisRow()
|
redis_row = RedisRow()
|
||||||
redis_row.merge(set_values=list_keys)
|
redis_row.merge(set_values=list_keys)
|
||||||
redis_row.feed(value)
|
redis_row.feed(value)
|
||||||
|
|
@ -108,9 +39,15 @@ class RedisActions:
|
||||||
time=expiry_time,
|
time=expiry_time,
|
||||||
value=redis_row.value,
|
value=redis_row.value,
|
||||||
)
|
)
|
||||||
redis_row.expires_at = arrow.now().shift(seconds=expiry_time).format("YYYY-MM-DD HH:mm:ss")
|
redis_row.expires_at = (
|
||||||
|
arrow.now()
|
||||||
|
.shift(seconds=expiry_time)
|
||||||
|
.format(MainConfig.DATETIME_FORMAT)
|
||||||
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
redis_cli.set(name=redis_row.redis_key, value=redis_row.value)
|
redis_cli.set(name=redis_row.redis_key, value=redis_row.value)
|
||||||
|
|
||||||
return RedisResponse(
|
return RedisResponse(
|
||||||
status=True,
|
status=True,
|
||||||
message="Value is set successfully.",
|
message="Value is set successfully.",
|
||||||
|
|
@ -124,21 +61,31 @@ class RedisActions:
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_json(cls, list_keys: list[str | bytes]):
|
def resolve_expires_at(cls, redis_row: RedisRow) -> str:
|
||||||
|
"""Resolve expiry time for Redis key."""
|
||||||
|
expiry_time = redis_cli.ttl(redis_row.redis_key)
|
||||||
|
if expiry_time == -1:
|
||||||
|
return "Key has no expiry time."
|
||||||
|
return arrow.now().shift(seconds=expiry_time).format(MainConfig.DATETIME_FORMAT)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_json(cls, list_keys: List[Union[str, bytes]]) -> RedisResponse:
|
||||||
|
"""Get JSON values from Redis using pattern matching."""
|
||||||
try:
|
try:
|
||||||
redis_row = RedisRow()
|
list_of_rows = []
|
||||||
json_get = redis_cli.get(redis_row.regex(list_keys=list_keys))
|
regex = RedisRow.regex(list_keys=list_keys)
|
||||||
redis_row.key = json_get
|
json_get = redis_cli.scan_iter(match=regex)
|
||||||
if not json_get:
|
|
||||||
return RedisResponse(
|
for row in list(json_get):
|
||||||
status=False,
|
redis_row = RedisRow()
|
||||||
message="Value is not get successfully.",
|
redis_row.set_key(key=row)
|
||||||
error="Value is not found in the redis.",
|
redis_row.expires_at = cls.resolve_expires_at(redis_row=redis_row)
|
||||||
)
|
redis_row.feed(redis_cli.get(redis_row.redis_key))
|
||||||
|
list_of_rows.append(redis_row)
|
||||||
return RedisResponse(
|
return RedisResponse(
|
||||||
status=True,
|
status=True,
|
||||||
message="Value is get successfully.",
|
message="Value is get successfully.",
|
||||||
data=json.loads(json_get),
|
data=list_of_rows,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return RedisResponse(
|
return RedisResponse(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
import json
|
||||||
|
from typing import Union, Dict, List, Optional, Any
|
||||||
|
|
||||||
|
|
||||||
|
class RedisRow:
|
||||||
|
"""Class for handling Redis key-value operations with structured data."""
|
||||||
|
|
||||||
|
key: Union[str, bytes]
|
||||||
|
value: Any
|
||||||
|
delimiter: str = ":"
|
||||||
|
expires_at: Optional[str] = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def merge(cls, set_values: List[Union[str, bytes]]) -> None:
|
||||||
|
"""Merge list of values into a single delimited key."""
|
||||||
|
cls.key = ""
|
||||||
|
for key, set_value in enumerate(set_values):
|
||||||
|
set_value = (
|
||||||
|
set_value.decode() if isinstance(set_value, bytes) else str(set_value)
|
||||||
|
)
|
||||||
|
cls.key += (
|
||||||
|
f"{set_value}"
|
||||||
|
if key == len(set_values) - 1
|
||||||
|
else f"{set_value}{cls.delimiter}"
|
||||||
|
)
|
||||||
|
cls.key = cls.key.encode()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def regex(cls, list_keys: List[Union[str, bytes]]) -> str:
|
||||||
|
"""Generate Redis search pattern from list of keys."""
|
||||||
|
search_regex = ""
|
||||||
|
for key, list_key in enumerate(list_keys):
|
||||||
|
if not list_key:
|
||||||
|
continue
|
||||||
|
|
||||||
|
list_key = (
|
||||||
|
list_key.decode() if isinstance(list_key, bytes) else str(list_key)
|
||||||
|
)
|
||||||
|
if key == 0:
|
||||||
|
search_regex += f"{list_key}{cls.delimiter}*"
|
||||||
|
elif key == len(list_keys) - 1:
|
||||||
|
search_regex += f"*{cls.delimiter}{list_key}"
|
||||||
|
else:
|
||||||
|
search_regex += f"*{cls.delimiter}{list_key}{cls.delimiter}*"
|
||||||
|
return search_regex
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse(cls) -> List[str]:
|
||||||
|
"""Parse the key into its component parts."""
|
||||||
|
return cls.key.split(cls.delimiter) if cls.key else []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def feed(cls, value: Union[bytes, Dict, List]) -> None:
|
||||||
|
"""Convert and store value in JSON format."""
|
||||||
|
if isinstance(value, (dict, list)):
|
||||||
|
cls.value = json.dumps(value)
|
||||||
|
else:
|
||||||
|
cls.value = json.dumps(json.loads(value.decode()))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def modify(cls, add_dict: Dict) -> None:
|
||||||
|
"""Modify existing data by merging with new dictionary."""
|
||||||
|
value = cls.data or {}
|
||||||
|
cls.feed({**value, **add_dict})
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def remove(cls, key: str) -> None:
|
||||||
|
"""Remove a key from the stored dictionary."""
|
||||||
|
value = cls.data or {}
|
||||||
|
value.pop(key)
|
||||||
|
cls.feed(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def keys(self) -> str:
|
||||||
|
"""Get key as string."""
|
||||||
|
return self.key.decode() if isinstance(self.key, bytes) else self.key
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_key(cls, key: Union[str, bytes]) -> None:
|
||||||
|
"""Set key ensuring bytes format."""
|
||||||
|
cls.key = key if isinstance(key, bytes) else key.encode()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def redis_key(self) -> bytes:
|
||||||
|
"""Get key in bytes format for Redis operations."""
|
||||||
|
return self.key if isinstance(self.key, bytes) else self.key.encode()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data(self) -> Union[Dict, List]:
|
||||||
|
"""Get stored value as Python object."""
|
||||||
|
return json.loads(self.value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def as_dict(self) -> Dict:
|
||||||
|
"""Get row data as dictionary."""
|
||||||
|
return {
|
||||||
|
"keys": self.keys,
|
||||||
|
"value": self.data,
|
||||||
|
}
|
||||||
|
|
@ -1,19 +1,21 @@
|
||||||
from typing import Union, Dict, List
|
from typing import Union, Dict, List, Optional, Any
|
||||||
from ApiServiceRedis.Redis.Actions.actions import RedisRow
|
from ApiServiceRedis.Redis.Models.base import RedisRow
|
||||||
|
|
||||||
|
|
||||||
class RedisResponse:
|
class RedisResponse:
|
||||||
|
"""Base class for Redis response handling."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
status: bool,
|
status: bool,
|
||||||
message: str,
|
message: str,
|
||||||
data: RedisRow = None,
|
data: Any = None,
|
||||||
error: str = None,
|
error: Optional[str] = None,
|
||||||
):
|
):
|
||||||
self.status = status
|
self.status = status
|
||||||
self.message = message
|
self.message = message
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
self.data_type = "dict"
|
self.data_type = "dict"
|
||||||
elif isinstance(data, list):
|
elif isinstance(data, list):
|
||||||
|
|
@ -22,7 +24,7 @@ class RedisResponse:
|
||||||
self.data_type = None
|
self.data_type = None
|
||||||
self.error = error
|
self.error = error
|
||||||
|
|
||||||
def as_dict(self):
|
def as_dict(self) -> Dict:
|
||||||
return {
|
return {
|
||||||
"status": self.status,
|
"status": self.status,
|
||||||
"message": self.message,
|
"message": self.message,
|
||||||
|
|
@ -30,3 +32,13 @@ class RedisResponse:
|
||||||
"dataType": self.data_type,
|
"dataType": self.data_type,
|
||||||
"error": self.error,
|
"error": self.error,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def all(self) -> Union[Optional[List[RedisRow]]]:
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def first(self) -> Union[RedisRow, None]:
|
||||||
|
if self.data:
|
||||||
|
return self.data[0]
|
||||||
|
return None
|
||||||
|
|
|
||||||
|
|
@ -22,4 +22,4 @@ class AccessToken(BaseModel):
|
||||||
# "accessToken": "token",
|
# "accessToken": "token",
|
||||||
# "userUUID": "uuid"
|
# "userUUID": "uuid"
|
||||||
# })
|
# })
|
||||||
# access_token_obj.to_list()
|
# access_token_obj.to_list()
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,11 @@
|
||||||
from redis import Redis
|
from redis import Redis
|
||||||
from api_configs import WagRedis
|
from AllConfigs.Redis.configs import WagRedis
|
||||||
|
|
||||||
|
|
||||||
class RedisConn:
|
class RedisConn:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.redis = Redis(
|
self.redis = Redis(**WagRedis.as_dict())
|
||||||
host=WagRedis.REDIS_HOST,
|
|
||||||
password=WagRedis.REDIS_PASSWORD,
|
|
||||||
port=WagRedis.REDIS_PORT,
|
|
||||||
db=WagRedis.REDIS_DB,
|
|
||||||
)
|
|
||||||
if not self.check_connection():
|
if not self.check_connection():
|
||||||
raise Exception("Connection error")
|
raise Exception("Connection error")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,40 @@
|
||||||
|
import secrets
|
||||||
|
import uuid
|
||||||
|
|
||||||
from ApiServiceRedis.Redis.Actions.actions import RedisActions
|
from ApiServiceRedis.Redis.Actions.actions import RedisActions
|
||||||
from ApiServiceRedis.Redis.Models.row import AccessToken
|
from ApiServiceRedis.Redis.Models.row import AccessToken
|
||||||
|
|
||||||
|
first_user = AccessToken(
|
||||||
redis_cli_actions = RedisActions()
|
accessToken=secrets.token_urlsafe(90),
|
||||||
|
userUUID=uuid.uuid4().__str__(),
|
||||||
access_object = AccessToken(
|
|
||||||
accessToken="token",
|
|
||||||
userUUID="uuid"
|
|
||||||
)
|
)
|
||||||
|
second_user = AccessToken(
|
||||||
|
accessToken=secrets.token_urlsafe(90),
|
||||||
|
userUUID=uuid.uuid4().__str__(),
|
||||||
|
)
|
||||||
|
|
||||||
|
json_data = lambda uu_id, access: {
|
||||||
|
"uu_id": uu_id,
|
||||||
|
"access_token": access,
|
||||||
|
"user_type": 1,
|
||||||
|
"selected_company": None,
|
||||||
|
"selected_occupant": None,
|
||||||
|
"reachable_event_list_id": [],
|
||||||
|
}
|
||||||
|
set_response_first_json = json_data(first_user.userUUID, first_user.accessToken)
|
||||||
|
set_response_second_json = json_data(second_user.userUUID, second_user.accessToken)
|
||||||
|
set_response_first = RedisActions.set_json(
|
||||||
|
list_keys=first_user.to_list(),
|
||||||
|
value=set_response_first_json,
|
||||||
|
expires={"seconds": 140},
|
||||||
|
)
|
||||||
|
|
||||||
|
set_response_second = RedisActions.set_json(
|
||||||
|
list_keys=second_user.to_list(),
|
||||||
|
value=set_response_second_json,
|
||||||
|
expires={"seconds": 190},
|
||||||
|
)
|
||||||
|
|
||||||
|
search_keys = [None, set_response_first_json["uu_id"]]
|
||||||
|
get_response = RedisActions.get_json(list_keys=search_keys)
|
||||||
|
print("get_response", [data.expires_at for data in get_response.all])
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import secrets
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from ApiServiceRedis.Redis.Actions.actions import RedisActions
|
||||||
|
from ApiServiceRedis.Redis.Models.row import AccessToken
|
||||||
|
|
||||||
|
first_user = AccessToken(
|
||||||
|
accessToken=secrets.token_urlsafe(90),
|
||||||
|
userUUID=uuid.uuid4().__str__(),
|
||||||
|
)
|
||||||
|
second_user = AccessToken(
|
||||||
|
accessToken=secrets.token_urlsafe(90),
|
||||||
|
userUUID=uuid.uuid4().__str__(),
|
||||||
|
)
|
||||||
|
|
||||||
|
json_data = lambda uu_id, access: {
|
||||||
|
"uu_id": uu_id,
|
||||||
|
"access_token": access,
|
||||||
|
"user_type": 1,
|
||||||
|
"selected_company": None,
|
||||||
|
"selected_occupant": None,
|
||||||
|
"reachable_event_list_id": [],
|
||||||
|
}
|
||||||
|
set_response_first_json = json_data(first_user.userUUID, first_user.accessToken)
|
||||||
|
set_response_second_json = json_data(second_user.userUUID, second_user.accessToken)
|
||||||
|
set_response_first = RedisActions.set_json(
|
||||||
|
list_keys=first_user.to_list(),
|
||||||
|
value=set_response_first_json,
|
||||||
|
expires={"seconds": 140},
|
||||||
|
)
|
||||||
|
|
||||||
|
set_response_second = RedisActions.set_json(
|
||||||
|
list_keys=second_user.to_list(),
|
||||||
|
value=set_response_second_json,
|
||||||
|
expires={"seconds": 190},
|
||||||
|
)
|
||||||
|
|
||||||
|
search_keys = [None, set_response_first_json["uu_id"]]
|
||||||
|
get_response = RedisActions.get_json(list_keys=search_keys)
|
||||||
|
print("get_response", [data.expires_at for data in get_response.all])
|
||||||
Loading…
Reference in New Issue