Skip to content

redis timeseries support #1652

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions redis/commands/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,17 @@ def nativestr(x):
def delist(x):
"""Given a list of binaries, return the stringified version."""
return [nativestr(obj) for obj in x]


def parse_to_list(response):
"""Optimistally parse the response to a list.
"""
res = []
for item in response:
try:
res.append(int(item))
except ValueError:
res.append(nativestr(item))
except TypeError:
res.append(None)
return res
4 changes: 0 additions & 4 deletions redis/commands/json/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
# from typing import Optional
from json import JSONDecoder, JSONEncoder

# # from redis.client import Redis

from .helpers import bulk_of_jsons
from ..helpers import nativestr, delist
from .commands import JSONCommands
# from ..feature import AbstractFeature


class JSON(JSONCommands):
Expand Down
16 changes: 15 additions & 1 deletion redis/commands/redismodules.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,22 @@ def ft(self, index_name="idx"):
try:
modversion = self.loaded_modules['search']
except IndexError:
raise ModuleError("rejson is not a loaded in the redis instance.")
raise ModuleError("search is not a loaded in the redis instance.")

from .search import Search
s = Search(client=self, version=modversion, index_name=index_name)
return s

def ts(self, index_name="idx"):
"""Access the timeseries namespace, providing support for
redis timeseries data.
"""
try:
modversion = self.loaded_modules['timeseries']
except IndexError:
raise ModuleError("timeseries is not a loaded in "
"the redis instance.")

from .timeseries import TimeSeries
s = TimeSeries(client=self, version=modversion, index_name=index_name)
return s
61 changes: 61 additions & 0 deletions redis/commands/timeseries/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from redis.client import bool_ok

from .utils import (
parse_range,
parse_get,
parse_m_range,
parse_m_get,
)
from .info import TSInfo
from ..helpers import parse_to_list
from .commands import (
ALTER_CMD,
CREATE_CMD,
CREATERULE_CMD,
DELETERULE_CMD,
DEL_CMD,
GET_CMD,
INFO_CMD,
MGET_CMD,
MRANGE_CMD,
MREVRANGE_CMD,
QUERYINDEX_CMD,
RANGE_CMD,
REVRANGE_CMD,
TimeSeriesCommands,
)


class TimeSeries(TimeSeriesCommands):
"""
This class subclasses redis-py's `Redis` and implements RedisTimeSeries's
commands (prefixed with "ts").
The client allows to interact with RedisTimeSeries and use all of it's
functionality.
"""

def __init__(self, client=None, version=None, **kwargs):
"""Create a new RedisTimeSeries client."""
# Set the module commands' callbacks
MODULE_CALLBACKS = {
CREATE_CMD: bool_ok,
ALTER_CMD: bool_ok,
CREATERULE_CMD: bool_ok,
DEL_CMD: int,
DELETERULE_CMD: bool_ok,
RANGE_CMD: parse_range,
REVRANGE_CMD: parse_range,
MRANGE_CMD: parse_m_range,
MREVRANGE_CMD: parse_m_range,
GET_CMD: parse_get,
MGET_CMD: parse_m_get,
INFO_CMD: TSInfo,
QUERYINDEX_CMD: parse_to_list,
}

self.client = client
self.execute_command = client.execute_command
self.MODULE_VERSION = version

for k in MODULE_CALLBACKS:
self.client.set_response_callback(k, MODULE_CALLBACKS[k])
Loading