redis 5.3.0b5__py3-none-any.whl → 6.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- redis/__init__.py +2 -11
- redis/_parsers/base.py +14 -2
- redis/_parsers/resp3.py +2 -2
- redis/asyncio/client.py +102 -82
- redis/asyncio/cluster.py +147 -102
- redis/asyncio/connection.py +77 -24
- redis/asyncio/lock.py +26 -5
- redis/asyncio/retry.py +12 -0
- redis/asyncio/sentinel.py +11 -1
- redis/asyncio/utils.py +1 -1
- redis/auth/token.py +6 -2
- redis/backoff.py +15 -0
- redis/client.py +106 -98
- redis/cluster.py +208 -79
- redis/commands/cluster.py +1 -11
- redis/commands/core.py +219 -207
- redis/commands/helpers.py +19 -76
- redis/commands/json/__init__.py +1 -1
- redis/commands/redismodules.py +5 -17
- redis/commands/search/aggregation.py +3 -1
- redis/commands/search/commands.py +43 -16
- redis/commands/search/dialect.py +3 -0
- redis/commands/search/profile_information.py +14 -0
- redis/commands/search/query.py +5 -1
- redis/commands/timeseries/__init__.py +1 -1
- redis/commands/vectorset/__init__.py +46 -0
- redis/commands/vectorset/commands.py +367 -0
- redis/commands/vectorset/utils.py +94 -0
- redis/connection.py +78 -29
- redis/exceptions.py +4 -1
- redis/lock.py +24 -4
- redis/ocsp.py +2 -1
- redis/retry.py +12 -0
- redis/sentinel.py +3 -1
- redis/utils.py +114 -1
- {redis-5.3.0b5.dist-info → redis-6.0.0.dist-info}/METADATA +57 -23
- redis-6.0.0.dist-info/RECORD +78 -0
- {redis-5.3.0b5.dist-info → redis-6.0.0.dist-info}/WHEEL +1 -2
- redis/commands/graph/__init__.py +0 -263
- redis/commands/graph/commands.py +0 -313
- redis/commands/graph/edge.py +0 -91
- redis/commands/graph/exceptions.py +0 -3
- redis/commands/graph/execution_plan.py +0 -211
- redis/commands/graph/node.py +0 -88
- redis/commands/graph/path.py +0 -78
- redis/commands/graph/query_result.py +0 -588
- redis-5.3.0b5.dist-info/RECORD +0 -82
- redis-5.3.0b5.dist-info/top_level.txt +0 -1
- /redis/commands/search/{indexDefinition.py → index_definition.py} +0 -0
- {redis-5.3.0b5.dist-info → redis-6.0.0.dist-info/licenses}/LICENSE +0 -0
redis/commands/helpers.py
CHANGED
|
@@ -43,19 +43,32 @@ def parse_to_list(response):
|
|
|
43
43
|
"""Optimistically parse the response to a list."""
|
|
44
44
|
res = []
|
|
45
45
|
|
|
46
|
+
special_values = {"infinity", "nan", "-infinity"}
|
|
47
|
+
|
|
46
48
|
if response is None:
|
|
47
49
|
return res
|
|
48
50
|
|
|
49
51
|
for item in response:
|
|
52
|
+
if item is None:
|
|
53
|
+
res.append(None)
|
|
54
|
+
continue
|
|
50
55
|
try:
|
|
51
|
-
|
|
52
|
-
except ValueError:
|
|
53
|
-
try:
|
|
54
|
-
res.append(float(item))
|
|
55
|
-
except ValueError:
|
|
56
|
-
res.append(nativestr(item))
|
|
56
|
+
item_str = nativestr(item)
|
|
57
57
|
except TypeError:
|
|
58
58
|
res.append(None)
|
|
59
|
+
continue
|
|
60
|
+
|
|
61
|
+
if isinstance(item_str, str) and item_str.lower() in special_values:
|
|
62
|
+
res.append(item_str) # Keep as string
|
|
63
|
+
else:
|
|
64
|
+
try:
|
|
65
|
+
res.append(int(item))
|
|
66
|
+
except ValueError:
|
|
67
|
+
try:
|
|
68
|
+
res.append(float(item))
|
|
69
|
+
except ValueError:
|
|
70
|
+
res.append(item_str)
|
|
71
|
+
|
|
59
72
|
return res
|
|
60
73
|
|
|
61
74
|
|
|
@@ -79,29 +92,6 @@ def parse_list_to_dict(response):
|
|
|
79
92
|
return res
|
|
80
93
|
|
|
81
94
|
|
|
82
|
-
def parse_to_dict(response):
|
|
83
|
-
if response is None:
|
|
84
|
-
return {}
|
|
85
|
-
|
|
86
|
-
res = {}
|
|
87
|
-
for det in response:
|
|
88
|
-
if not isinstance(det, list) or not det:
|
|
89
|
-
continue
|
|
90
|
-
if len(det) == 1:
|
|
91
|
-
res[det[0]] = True
|
|
92
|
-
elif isinstance(det[1], list):
|
|
93
|
-
res[det[0]] = parse_list_to_dict(det[1])
|
|
94
|
-
else:
|
|
95
|
-
try: # try to set the attribute. may be provided without value
|
|
96
|
-
try: # try to convert the value to float
|
|
97
|
-
res[det[0]] = float(det[1])
|
|
98
|
-
except (TypeError, ValueError):
|
|
99
|
-
res[det[0]] = det[1]
|
|
100
|
-
except IndexError:
|
|
101
|
-
pass
|
|
102
|
-
return res
|
|
103
|
-
|
|
104
|
-
|
|
105
95
|
def random_string(length=10):
|
|
106
96
|
"""
|
|
107
97
|
Returns a random N character long string.
|
|
@@ -111,26 +101,6 @@ def random_string(length=10):
|
|
|
111
101
|
)
|
|
112
102
|
|
|
113
103
|
|
|
114
|
-
def quote_string(v):
|
|
115
|
-
"""
|
|
116
|
-
RedisGraph strings must be quoted,
|
|
117
|
-
quote_string wraps given v with quotes incase
|
|
118
|
-
v is a string.
|
|
119
|
-
"""
|
|
120
|
-
|
|
121
|
-
if isinstance(v, bytes):
|
|
122
|
-
v = v.decode()
|
|
123
|
-
elif not isinstance(v, str):
|
|
124
|
-
return v
|
|
125
|
-
if len(v) == 0:
|
|
126
|
-
return '""'
|
|
127
|
-
|
|
128
|
-
v = v.replace("\\", "\\\\")
|
|
129
|
-
v = v.replace('"', '\\"')
|
|
130
|
-
|
|
131
|
-
return f'"{v}"'
|
|
132
|
-
|
|
133
|
-
|
|
134
104
|
def decode_dict_keys(obj):
|
|
135
105
|
"""Decode the keys of the given dictionary with utf-8."""
|
|
136
106
|
newobj = copy.copy(obj)
|
|
@@ -141,33 +111,6 @@ def decode_dict_keys(obj):
|
|
|
141
111
|
return newobj
|
|
142
112
|
|
|
143
113
|
|
|
144
|
-
def stringify_param_value(value):
|
|
145
|
-
"""
|
|
146
|
-
Turn a parameter value into a string suitable for the params header of
|
|
147
|
-
a Cypher command.
|
|
148
|
-
You may pass any value that would be accepted by `json.dumps()`.
|
|
149
|
-
|
|
150
|
-
Ways in which output differs from that of `str()`:
|
|
151
|
-
* Strings are quoted.
|
|
152
|
-
* None --> "null".
|
|
153
|
-
* In dictionaries, keys are _not_ quoted.
|
|
154
|
-
|
|
155
|
-
:param value: The parameter value to be turned into a string.
|
|
156
|
-
:return: string
|
|
157
|
-
"""
|
|
158
|
-
|
|
159
|
-
if isinstance(value, str):
|
|
160
|
-
return quote_string(value)
|
|
161
|
-
elif value is None:
|
|
162
|
-
return "null"
|
|
163
|
-
elif isinstance(value, (list, tuple)):
|
|
164
|
-
return f'[{",".join(map(stringify_param_value, value))}]'
|
|
165
|
-
elif isinstance(value, dict):
|
|
166
|
-
return f'{{{",".join(f"{k}:{stringify_param_value(v)}" for k, v in value.items())}}}' # noqa
|
|
167
|
-
else:
|
|
168
|
-
return str(value)
|
|
169
|
-
|
|
170
|
-
|
|
171
114
|
def get_protocol_version(client):
|
|
172
115
|
if isinstance(client, redis.Redis) or isinstance(client, redis.asyncio.Redis):
|
|
173
116
|
return client.connection_pool.connection_kwargs.get("protocol")
|
redis/commands/json/__init__.py
CHANGED
|
@@ -120,7 +120,7 @@ class JSON(JSONCommands):
|
|
|
120
120
|
startup_nodes=self.client.nodes_manager.startup_nodes,
|
|
121
121
|
result_callbacks=self.client.result_callbacks,
|
|
122
122
|
cluster_response_callbacks=self.client.cluster_response_callbacks,
|
|
123
|
-
cluster_error_retry_attempts=self.client.
|
|
123
|
+
cluster_error_retry_attempts=self.client.retry.get_retries(),
|
|
124
124
|
read_from_replicas=self.client.read_from_replicas,
|
|
125
125
|
reinitialize_steps=self.client.reinitialize_steps,
|
|
126
126
|
lock=self.client._lock,
|
redis/commands/redismodules.py
CHANGED
|
@@ -72,15 +72,13 @@ class RedisModuleCommands:
|
|
|
72
72
|
tdigest = TDigestBloom(client=self)
|
|
73
73
|
return tdigest
|
|
74
74
|
|
|
75
|
-
def
|
|
76
|
-
"""Access the
|
|
77
|
-
redis graph data.
|
|
78
|
-
"""
|
|
75
|
+
def vset(self):
|
|
76
|
+
"""Access the VectorSet commands namespace."""
|
|
79
77
|
|
|
80
|
-
from .
|
|
78
|
+
from .vectorset import VectorSet
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
return
|
|
80
|
+
vset = VectorSet(client=self)
|
|
81
|
+
return vset
|
|
84
82
|
|
|
85
83
|
|
|
86
84
|
class AsyncRedisModuleCommands(RedisModuleCommands):
|
|
@@ -91,13 +89,3 @@ class AsyncRedisModuleCommands(RedisModuleCommands):
|
|
|
91
89
|
|
|
92
90
|
s = AsyncSearch(client=self, index_name=index_name)
|
|
93
91
|
return s
|
|
94
|
-
|
|
95
|
-
def graph(self, index_name="idx"):
|
|
96
|
-
"""Access the graph namespace, providing support for
|
|
97
|
-
redis graph data.
|
|
98
|
-
"""
|
|
99
|
-
|
|
100
|
-
from .graph import AsyncGraph
|
|
101
|
-
|
|
102
|
-
g = AsyncGraph(client=self, name=index_name)
|
|
103
|
-
return g
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import List, Union
|
|
2
2
|
|
|
3
|
+
from redis.commands.search.dialect import DEFAULT_DIALECT
|
|
4
|
+
|
|
3
5
|
FIELDNAME = object()
|
|
4
6
|
|
|
5
7
|
|
|
@@ -110,7 +112,7 @@ class AggregateRequest:
|
|
|
110
112
|
self._with_schema = False
|
|
111
113
|
self._verbatim = False
|
|
112
114
|
self._cursor = []
|
|
113
|
-
self._dialect =
|
|
115
|
+
self._dialect = DEFAULT_DIALECT
|
|
114
116
|
self._add_scores = False
|
|
115
117
|
self._scorer = "TFIDF"
|
|
116
118
|
|
|
@@ -5,12 +5,13 @@ from typing import Dict, List, Optional, Union
|
|
|
5
5
|
from redis.client import NEVER_DECODE, Pipeline
|
|
6
6
|
from redis.utils import deprecated_function
|
|
7
7
|
|
|
8
|
-
from ..helpers import get_protocol_version
|
|
8
|
+
from ..helpers import get_protocol_version
|
|
9
9
|
from ._util import to_string
|
|
10
10
|
from .aggregation import AggregateRequest, AggregateResult, Cursor
|
|
11
11
|
from .document import Document
|
|
12
12
|
from .field import Field
|
|
13
|
-
from .
|
|
13
|
+
from .index_definition import IndexDefinition
|
|
14
|
+
from .profile_information import ProfileInformation
|
|
14
15
|
from .query import Query
|
|
15
16
|
from .result import Result
|
|
16
17
|
from .suggestion import SuggestionParser
|
|
@@ -22,7 +23,6 @@ ALTER_CMD = "FT.ALTER"
|
|
|
22
23
|
SEARCH_CMD = "FT.SEARCH"
|
|
23
24
|
ADD_CMD = "FT.ADD"
|
|
24
25
|
ADDHASH_CMD = "FT.ADDHASH"
|
|
25
|
-
DROP_CMD = "FT.DROP"
|
|
26
26
|
DROPINDEX_CMD = "FT.DROPINDEX"
|
|
27
27
|
EXPLAIN_CMD = "FT.EXPLAIN"
|
|
28
28
|
EXPLAINCLI_CMD = "FT.EXPLAINCLI"
|
|
@@ -34,7 +34,6 @@ SPELLCHECK_CMD = "FT.SPELLCHECK"
|
|
|
34
34
|
DICT_ADD_CMD = "FT.DICTADD"
|
|
35
35
|
DICT_DEL_CMD = "FT.DICTDEL"
|
|
36
36
|
DICT_DUMP_CMD = "FT.DICTDUMP"
|
|
37
|
-
GET_CMD = "FT.GET"
|
|
38
37
|
MGET_CMD = "FT.MGET"
|
|
39
38
|
CONFIG_CMD = "FT.CONFIG"
|
|
40
39
|
TAGVALS_CMD = "FT.TAGVALS"
|
|
@@ -67,7 +66,7 @@ class SearchCommands:
|
|
|
67
66
|
|
|
68
67
|
def _parse_results(self, cmd, res, **kwargs):
|
|
69
68
|
if get_protocol_version(self.client) in ["3", 3]:
|
|
70
|
-
return res
|
|
69
|
+
return ProfileInformation(res) if cmd == "FT.PROFILE" else res
|
|
71
70
|
else:
|
|
72
71
|
return self._RESP2_MODULE_CALLBACKS[cmd](res, **kwargs)
|
|
73
72
|
|
|
@@ -101,7 +100,7 @@ class SearchCommands:
|
|
|
101
100
|
with_scores=query._with_scores,
|
|
102
101
|
)
|
|
103
102
|
|
|
104
|
-
return result,
|
|
103
|
+
return result, ProfileInformation(res[1])
|
|
105
104
|
|
|
106
105
|
def _parse_spellcheck(self, res, **kwargs):
|
|
107
106
|
corrections = {}
|
|
@@ -254,8 +253,18 @@ class SearchCommands:
|
|
|
254
253
|
|
|
255
254
|
For more information see `FT.DROPINDEX <https://redis.io/commands/ft.dropindex>`_.
|
|
256
255
|
""" # noqa
|
|
257
|
-
|
|
258
|
-
|
|
256
|
+
args = [DROPINDEX_CMD, self.index_name]
|
|
257
|
+
|
|
258
|
+
delete_str = (
|
|
259
|
+
"DD"
|
|
260
|
+
if isinstance(delete_documents, bool) and delete_documents is True
|
|
261
|
+
else ""
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
if delete_str:
|
|
265
|
+
args.append(delete_str)
|
|
266
|
+
|
|
267
|
+
return self.execute_command(*args)
|
|
259
268
|
|
|
260
269
|
def _add_document(
|
|
261
270
|
self,
|
|
@@ -395,6 +404,7 @@ class SearchCommands:
|
|
|
395
404
|
doc_id, conn=None, score=score, language=language, replace=replace
|
|
396
405
|
)
|
|
397
406
|
|
|
407
|
+
@deprecated_function(version="2.0.0", reason="deprecated since redisearch 2.0")
|
|
398
408
|
def delete_document(self, doc_id, conn=None, delete_actual_document=False):
|
|
399
409
|
"""
|
|
400
410
|
Delete a document from index
|
|
@@ -429,6 +439,7 @@ class SearchCommands:
|
|
|
429
439
|
|
|
430
440
|
return Document(id=id, **fields)
|
|
431
441
|
|
|
442
|
+
@deprecated_function(version="2.0.0", reason="deprecated since redisearch 2.0")
|
|
432
443
|
def get(self, *ids):
|
|
433
444
|
"""
|
|
434
445
|
Returns the full contents of multiple documents.
|
|
@@ -499,7 +510,7 @@ class SearchCommands:
|
|
|
499
510
|
For more information see `FT.SEARCH <https://redis.io/commands/ft.search>`_.
|
|
500
511
|
""" # noqa
|
|
501
512
|
args, query = self._mk_query_args(query, query_params=query_params)
|
|
502
|
-
st = time.
|
|
513
|
+
st = time.monotonic()
|
|
503
514
|
|
|
504
515
|
options = {}
|
|
505
516
|
if get_protocol_version(self.client) not in ["3", 3]:
|
|
@@ -511,7 +522,7 @@ class SearchCommands:
|
|
|
511
522
|
return res
|
|
512
523
|
|
|
513
524
|
return self._parse_results(
|
|
514
|
-
SEARCH_CMD, res, query=query, duration=(time.
|
|
525
|
+
SEARCH_CMD, res, query=query, duration=(time.monotonic() - st) * 1000.0
|
|
515
526
|
)
|
|
516
527
|
|
|
517
528
|
def explain(
|
|
@@ -585,7 +596,7 @@ class SearchCommands:
|
|
|
585
596
|
|
|
586
597
|
def profile(
|
|
587
598
|
self,
|
|
588
|
-
query: Union[
|
|
599
|
+
query: Union[Query, AggregateRequest],
|
|
589
600
|
limited: bool = False,
|
|
590
601
|
query_params: Optional[Dict[str, Union[str, int, float]]] = None,
|
|
591
602
|
):
|
|
@@ -595,13 +606,13 @@ class SearchCommands:
|
|
|
595
606
|
|
|
596
607
|
### Parameters
|
|
597
608
|
|
|
598
|
-
**query**: This can be either an `AggregateRequest
|
|
609
|
+
**query**: This can be either an `AggregateRequest` or `Query`.
|
|
599
610
|
**limited**: If set to True, removes details of reader iterator.
|
|
600
611
|
**query_params**: Define one or more value parameters.
|
|
601
612
|
Each parameter has a name and a value.
|
|
602
613
|
|
|
603
614
|
"""
|
|
604
|
-
st = time.
|
|
615
|
+
st = time.monotonic()
|
|
605
616
|
cmd = [PROFILE_CMD, self.index_name, ""]
|
|
606
617
|
if limited:
|
|
607
618
|
cmd.append("LIMITED")
|
|
@@ -620,7 +631,7 @@ class SearchCommands:
|
|
|
620
631
|
res = self.execute_command(*cmd)
|
|
621
632
|
|
|
622
633
|
return self._parse_results(
|
|
623
|
-
PROFILE_CMD, res, query=query, duration=(time.
|
|
634
|
+
PROFILE_CMD, res, query=query, duration=(time.monotonic() - st) * 1000.0
|
|
624
635
|
)
|
|
625
636
|
|
|
626
637
|
def spellcheck(self, query, distance=None, include=None, exclude=None):
|
|
@@ -691,6 +702,10 @@ class SearchCommands:
|
|
|
691
702
|
cmd = [DICT_DUMP_CMD, name]
|
|
692
703
|
return self.execute_command(*cmd)
|
|
693
704
|
|
|
705
|
+
@deprecated_function(
|
|
706
|
+
version="8.0.0",
|
|
707
|
+
reason="deprecated since Redis 8.0, call config_set from core module instead",
|
|
708
|
+
)
|
|
694
709
|
def config_set(self, option: str, value: str) -> bool:
|
|
695
710
|
"""Set runtime configuration option.
|
|
696
711
|
|
|
@@ -705,6 +720,10 @@ class SearchCommands:
|
|
|
705
720
|
raw = self.execute_command(*cmd)
|
|
706
721
|
return raw == "OK"
|
|
707
722
|
|
|
723
|
+
@deprecated_function(
|
|
724
|
+
version="8.0.0",
|
|
725
|
+
reason="deprecated since Redis 8.0, call config_get from core module instead",
|
|
726
|
+
)
|
|
708
727
|
def config_get(self, option: str) -> str:
|
|
709
728
|
"""Get runtime configuration option value.
|
|
710
729
|
|
|
@@ -931,7 +950,7 @@ class AsyncSearchCommands(SearchCommands):
|
|
|
931
950
|
For more information see `FT.SEARCH <https://redis.io/commands/ft.search>`_.
|
|
932
951
|
""" # noqa
|
|
933
952
|
args, query = self._mk_query_args(query, query_params=query_params)
|
|
934
|
-
st = time.
|
|
953
|
+
st = time.monotonic()
|
|
935
954
|
|
|
936
955
|
options = {}
|
|
937
956
|
if get_protocol_version(self.client) not in ["3", 3]:
|
|
@@ -943,7 +962,7 @@ class AsyncSearchCommands(SearchCommands):
|
|
|
943
962
|
return res
|
|
944
963
|
|
|
945
964
|
return self._parse_results(
|
|
946
|
-
SEARCH_CMD, res, query=query, duration=(time.
|
|
965
|
+
SEARCH_CMD, res, query=query, duration=(time.monotonic() - st) * 1000.0
|
|
947
966
|
)
|
|
948
967
|
|
|
949
968
|
async def aggregate(
|
|
@@ -1006,6 +1025,10 @@ class AsyncSearchCommands(SearchCommands):
|
|
|
1006
1025
|
|
|
1007
1026
|
return self._parse_results(SPELLCHECK_CMD, res)
|
|
1008
1027
|
|
|
1028
|
+
@deprecated_function(
|
|
1029
|
+
version="8.0.0",
|
|
1030
|
+
reason="deprecated since Redis 8.0, call config_set from core module instead",
|
|
1031
|
+
)
|
|
1009
1032
|
async def config_set(self, option: str, value: str) -> bool:
|
|
1010
1033
|
"""Set runtime configuration option.
|
|
1011
1034
|
|
|
@@ -1020,6 +1043,10 @@ class AsyncSearchCommands(SearchCommands):
|
|
|
1020
1043
|
raw = await self.execute_command(*cmd)
|
|
1021
1044
|
return raw == "OK"
|
|
1022
1045
|
|
|
1046
|
+
@deprecated_function(
|
|
1047
|
+
version="8.0.0",
|
|
1048
|
+
reason="deprecated since Redis 8.0, call config_get from core module instead",
|
|
1049
|
+
)
|
|
1023
1050
|
async def config_get(self, option: str) -> str:
|
|
1024
1051
|
"""Get runtime configuration option value.
|
|
1025
1052
|
|
redis/commands/search/query.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import List, Optional, Union
|
|
2
2
|
|
|
3
|
+
from redis.commands.search.dialect import DEFAULT_DIALECT
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
class Query:
|
|
5
7
|
"""
|
|
@@ -40,7 +42,7 @@ class Query:
|
|
|
40
42
|
self._highlight_fields: List = []
|
|
41
43
|
self._language: Optional[str] = None
|
|
42
44
|
self._expander: Optional[str] = None
|
|
43
|
-
self._dialect:
|
|
45
|
+
self._dialect: int = DEFAULT_DIALECT
|
|
44
46
|
|
|
45
47
|
def query_string(self) -> str:
|
|
46
48
|
"""Return the query string of this query only."""
|
|
@@ -177,6 +179,8 @@ class Query:
|
|
|
177
179
|
Use a different scoring function to evaluate document relevance.
|
|
178
180
|
Default is `TFIDF`.
|
|
179
181
|
|
|
182
|
+
Since Redis 8.0 default was changed to BM25STD.
|
|
183
|
+
|
|
180
184
|
:param scorer: The scoring function to use
|
|
181
185
|
(e.g. `TFIDF.DOCNORM` or `BM25`)
|
|
182
186
|
"""
|
|
@@ -84,7 +84,7 @@ class TimeSeries(TimeSeriesCommands):
|
|
|
84
84
|
startup_nodes=self.client.nodes_manager.startup_nodes,
|
|
85
85
|
result_callbacks=self.client.result_callbacks,
|
|
86
86
|
cluster_response_callbacks=self.client.cluster_response_callbacks,
|
|
87
|
-
cluster_error_retry_attempts=self.client.
|
|
87
|
+
cluster_error_retry_attempts=self.client.retry.get_retries(),
|
|
88
88
|
read_from_replicas=self.client.read_from_replicas,
|
|
89
89
|
reinitialize_steps=self.client.reinitialize_steps,
|
|
90
90
|
lock=self.client._lock,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from redis._parsers.helpers import pairs_to_dict
|
|
4
|
+
from redis.commands.vectorset.utils import (
|
|
5
|
+
parse_vemb_result,
|
|
6
|
+
parse_vlinks_result,
|
|
7
|
+
parse_vsim_result,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from ..helpers import get_protocol_version
|
|
11
|
+
from .commands import (
|
|
12
|
+
VEMB_CMD,
|
|
13
|
+
VGETATTR_CMD,
|
|
14
|
+
VINFO_CMD,
|
|
15
|
+
VLINKS_CMD,
|
|
16
|
+
VSIM_CMD,
|
|
17
|
+
VectorSetCommands,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class VectorSet(VectorSetCommands):
|
|
22
|
+
def __init__(self, client, **kwargs):
|
|
23
|
+
"""Create a new VectorSet client."""
|
|
24
|
+
# Set the module commands' callbacks
|
|
25
|
+
self._MODULE_CALLBACKS = {
|
|
26
|
+
VEMB_CMD: parse_vemb_result,
|
|
27
|
+
VGETATTR_CMD: lambda r: r and json.loads(r) or None,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
self._RESP2_MODULE_CALLBACKS = {
|
|
31
|
+
VINFO_CMD: lambda r: r and pairs_to_dict(r) or None,
|
|
32
|
+
VSIM_CMD: parse_vsim_result,
|
|
33
|
+
VLINKS_CMD: parse_vlinks_result,
|
|
34
|
+
}
|
|
35
|
+
self._RESP3_MODULE_CALLBACKS = {}
|
|
36
|
+
|
|
37
|
+
self.client = client
|
|
38
|
+
self.execute_command = client.execute_command
|
|
39
|
+
|
|
40
|
+
if get_protocol_version(self.client) in ["3", 3]:
|
|
41
|
+
self._MODULE_CALLBACKS.update(self._RESP3_MODULE_CALLBACKS)
|
|
42
|
+
else:
|
|
43
|
+
self._MODULE_CALLBACKS.update(self._RESP2_MODULE_CALLBACKS)
|
|
44
|
+
|
|
45
|
+
for k, v in self._MODULE_CALLBACKS.items():
|
|
46
|
+
self.client.set_response_callback(k, v)
|