redis 7.0.0b3__py3-none-any.whl → 7.0.1__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 +1 -1
- redis/_parsers/base.py +6 -0
- redis/_parsers/helpers.py +64 -6
- redis/asyncio/connection.py +1 -1
- redis/asyncio/multidb/client.py +2 -0
- redis/asyncio/multidb/config.py +2 -2
- redis/asyncio/multidb/healthcheck.py +4 -11
- redis/client.py +27 -24
- redis/cluster.py +6 -0
- redis/commands/core.py +54 -26
- redis/commands/json/commands.py +2 -2
- redis/commands/search/__init__.py +2 -2
- redis/commands/search/aggregation.py +24 -26
- redis/commands/search/commands.py +10 -10
- redis/commands/search/field.py +2 -2
- redis/commands/search/query.py +12 -12
- redis/connection.py +1613 -1263
- redis/exceptions.py +8 -0
- redis/maint_notifications.py +18 -7
- redis/multidb/client.py +2 -0
- redis/multidb/config.py +2 -2
- redis/multidb/healthcheck.py +4 -11
- redis/utils.py +20 -0
- {redis-7.0.0b3.dist-info → redis-7.0.1.dist-info}/METADATA +15 -4
- {redis-7.0.0b3.dist-info → redis-7.0.1.dist-info}/RECORD +27 -27
- {redis-7.0.0b3.dist-info → redis-7.0.1.dist-info}/WHEEL +0 -0
- {redis-7.0.0b3.dist-info → redis-7.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import List, Union
|
|
1
|
+
from typing import List, Optional, Tuple, Union
|
|
2
2
|
|
|
3
3
|
from redis.commands.search.dialect import DEFAULT_DIALECT
|
|
4
4
|
|
|
@@ -27,9 +27,9 @@ class Reducer:
|
|
|
27
27
|
NAME = None
|
|
28
28
|
|
|
29
29
|
def __init__(self, *args: str) -> None:
|
|
30
|
-
self._args = args
|
|
31
|
-
self._field = None
|
|
32
|
-
self._alias = None
|
|
30
|
+
self._args: Tuple[str, ...] = args
|
|
31
|
+
self._field: Optional[str] = None
|
|
32
|
+
self._alias: Optional[str] = None
|
|
33
33
|
|
|
34
34
|
def alias(self, alias: str) -> "Reducer":
|
|
35
35
|
"""
|
|
@@ -49,13 +49,14 @@ class Reducer:
|
|
|
49
49
|
if alias is FIELDNAME:
|
|
50
50
|
if not self._field:
|
|
51
51
|
raise ValueError("Cannot use FIELDNAME alias with no field")
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
else:
|
|
53
|
+
# Chop off initial '@'
|
|
54
|
+
alias = self._field[1:]
|
|
54
55
|
self._alias = alias
|
|
55
56
|
return self
|
|
56
57
|
|
|
57
58
|
@property
|
|
58
|
-
def args(self) ->
|
|
59
|
+
def args(self) -> Tuple[str, ...]:
|
|
59
60
|
return self._args
|
|
60
61
|
|
|
61
62
|
|
|
@@ -64,7 +65,7 @@ class SortDirection:
|
|
|
64
65
|
This special class is used to indicate sort direction.
|
|
65
66
|
"""
|
|
66
67
|
|
|
67
|
-
DIRSTRING = None
|
|
68
|
+
DIRSTRING: Optional[str] = None
|
|
68
69
|
|
|
69
70
|
def __init__(self, field: str) -> None:
|
|
70
71
|
self.field = field
|
|
@@ -104,17 +105,17 @@ class AggregateRequest:
|
|
|
104
105
|
All member methods (except `build_args()`)
|
|
105
106
|
return the object itself, making them useful for chaining.
|
|
106
107
|
"""
|
|
107
|
-
self._query = query
|
|
108
|
-
self._aggregateplan = []
|
|
109
|
-
self._loadfields = []
|
|
110
|
-
self._loadall = False
|
|
111
|
-
self._max = 0
|
|
112
|
-
self._with_schema = False
|
|
113
|
-
self._verbatim = False
|
|
114
|
-
self._cursor = []
|
|
115
|
-
self._dialect = DEFAULT_DIALECT
|
|
116
|
-
self._add_scores = False
|
|
117
|
-
self._scorer = "TFIDF"
|
|
108
|
+
self._query: str = query
|
|
109
|
+
self._aggregateplan: List[str] = []
|
|
110
|
+
self._loadfields: List[str] = []
|
|
111
|
+
self._loadall: bool = False
|
|
112
|
+
self._max: int = 0
|
|
113
|
+
self._with_schema: bool = False
|
|
114
|
+
self._verbatim: bool = False
|
|
115
|
+
self._cursor: List[str] = []
|
|
116
|
+
self._dialect: int = DEFAULT_DIALECT
|
|
117
|
+
self._add_scores: bool = False
|
|
118
|
+
self._scorer: str = "TFIDF"
|
|
118
119
|
|
|
119
120
|
def load(self, *fields: str) -> "AggregateRequest":
|
|
120
121
|
"""
|
|
@@ -133,7 +134,7 @@ class AggregateRequest:
|
|
|
133
134
|
return self
|
|
134
135
|
|
|
135
136
|
def group_by(
|
|
136
|
-
self, fields: List[str], *reducers:
|
|
137
|
+
self, fields: Union[str, List[str]], *reducers: Reducer
|
|
137
138
|
) -> "AggregateRequest":
|
|
138
139
|
"""
|
|
139
140
|
Specify by which fields to group the aggregation.
|
|
@@ -147,7 +148,6 @@ class AggregateRequest:
|
|
|
147
148
|
`aggregation` module.
|
|
148
149
|
"""
|
|
149
150
|
fields = [fields] if isinstance(fields, str) else fields
|
|
150
|
-
reducers = [reducers] if isinstance(reducers, Reducer) else reducers
|
|
151
151
|
|
|
152
152
|
ret = ["GROUPBY", str(len(fields)), *fields]
|
|
153
153
|
for reducer in reducers:
|
|
@@ -251,12 +251,10 @@ class AggregateRequest:
|
|
|
251
251
|
.sort_by(Desc("@paid"), max=10)
|
|
252
252
|
```
|
|
253
253
|
"""
|
|
254
|
-
if isinstance(fields, (str, SortDirection)):
|
|
255
|
-
fields = [fields]
|
|
256
254
|
|
|
257
255
|
fields_args = []
|
|
258
256
|
for f in fields:
|
|
259
|
-
if isinstance(f,
|
|
257
|
+
if isinstance(f, (Asc, Desc)):
|
|
260
258
|
fields_args += [f.field, f.DIRSTRING]
|
|
261
259
|
else:
|
|
262
260
|
fields_args += [f]
|
|
@@ -356,7 +354,7 @@ class AggregateRequest:
|
|
|
356
354
|
ret.extend(self._loadfields)
|
|
357
355
|
|
|
358
356
|
if self._dialect:
|
|
359
|
-
ret.extend(["DIALECT", self._dialect])
|
|
357
|
+
ret.extend(["DIALECT", str(self._dialect)])
|
|
360
358
|
|
|
361
359
|
ret.extend(self._aggregateplan)
|
|
362
360
|
|
|
@@ -393,7 +391,7 @@ class AggregateResult:
|
|
|
393
391
|
self.cursor = cursor
|
|
394
392
|
self.schema = schema
|
|
395
393
|
|
|
396
|
-
def __repr__(self) ->
|
|
394
|
+
def __repr__(self) -> str:
|
|
397
395
|
cid = self.cursor.cid if self.cursor else -1
|
|
398
396
|
return (
|
|
399
397
|
f"<{self.__class__.__name__} at 0x{id(self):x} "
|
|
@@ -221,7 +221,7 @@ class SearchCommands:
|
|
|
221
221
|
|
|
222
222
|
return self.execute_command(*args)
|
|
223
223
|
|
|
224
|
-
def alter_schema_add(self, fields: List[
|
|
224
|
+
def alter_schema_add(self, fields: Union[Field, List[Field]]):
|
|
225
225
|
"""
|
|
226
226
|
Alter the existing search index by adding new fields. The index
|
|
227
227
|
must already exist.
|
|
@@ -336,11 +336,11 @@ class SearchCommands:
|
|
|
336
336
|
doc_id: str,
|
|
337
337
|
nosave: bool = False,
|
|
338
338
|
score: float = 1.0,
|
|
339
|
-
payload: bool = None,
|
|
339
|
+
payload: Optional[bool] = None,
|
|
340
340
|
replace: bool = False,
|
|
341
341
|
partial: bool = False,
|
|
342
342
|
language: Optional[str] = None,
|
|
343
|
-
no_create:
|
|
343
|
+
no_create: bool = False,
|
|
344
344
|
**fields: List[str],
|
|
345
345
|
):
|
|
346
346
|
"""
|
|
@@ -464,7 +464,7 @@ class SearchCommands:
|
|
|
464
464
|
return self._parse_results(INFO_CMD, res)
|
|
465
465
|
|
|
466
466
|
def get_params_args(
|
|
467
|
-
self, query_params:
|
|
467
|
+
self, query_params: Optional[Dict[str, Union[str, int, float, bytes]]]
|
|
468
468
|
):
|
|
469
469
|
if query_params is None:
|
|
470
470
|
return []
|
|
@@ -478,7 +478,7 @@ class SearchCommands:
|
|
|
478
478
|
return args
|
|
479
479
|
|
|
480
480
|
def _mk_query_args(
|
|
481
|
-
self, query, query_params:
|
|
481
|
+
self, query, query_params: Optional[Dict[str, Union[str, int, float, bytes]]]
|
|
482
482
|
):
|
|
483
483
|
args = [self.index_name]
|
|
484
484
|
|
|
@@ -528,7 +528,7 @@ class SearchCommands:
|
|
|
528
528
|
def explain(
|
|
529
529
|
self,
|
|
530
530
|
query: Union[str, Query],
|
|
531
|
-
query_params: Dict[str, Union[str, int, float]] = None,
|
|
531
|
+
query_params: Optional[Dict[str, Union[str, int, float, bytes]]] = None,
|
|
532
532
|
):
|
|
533
533
|
"""Returns the execution plan for a complex query.
|
|
534
534
|
|
|
@@ -543,7 +543,7 @@ class SearchCommands:
|
|
|
543
543
|
def aggregate(
|
|
544
544
|
self,
|
|
545
545
|
query: Union[AggregateRequest, Cursor],
|
|
546
|
-
query_params: Dict[str, Union[str, int, float]] = None,
|
|
546
|
+
query_params: Optional[Dict[str, Union[str, int, float, bytes]]] = None,
|
|
547
547
|
):
|
|
548
548
|
"""
|
|
549
549
|
Issue an aggregation query.
|
|
@@ -598,7 +598,7 @@ class SearchCommands:
|
|
|
598
598
|
self,
|
|
599
599
|
query: Union[Query, AggregateRequest],
|
|
600
600
|
limited: bool = False,
|
|
601
|
-
query_params: Optional[Dict[str, Union[str, int, float]]] = None,
|
|
601
|
+
query_params: Optional[Dict[str, Union[str, int, float, bytes]]] = None,
|
|
602
602
|
):
|
|
603
603
|
"""
|
|
604
604
|
Performs a search or aggregate command and collects performance
|
|
@@ -936,7 +936,7 @@ class AsyncSearchCommands(SearchCommands):
|
|
|
936
936
|
async def search(
|
|
937
937
|
self,
|
|
938
938
|
query: Union[str, Query],
|
|
939
|
-
query_params: Dict[str, Union[str, int, float]] = None,
|
|
939
|
+
query_params: Optional[Dict[str, Union[str, int, float, bytes]]] = None,
|
|
940
940
|
):
|
|
941
941
|
"""
|
|
942
942
|
Search the index for a given query, and return a result of documents
|
|
@@ -968,7 +968,7 @@ class AsyncSearchCommands(SearchCommands):
|
|
|
968
968
|
async def aggregate(
|
|
969
969
|
self,
|
|
970
970
|
query: Union[AggregateResult, Cursor],
|
|
971
|
-
query_params: Dict[str, Union[str, int, float]] = None,
|
|
971
|
+
query_params: Optional[Dict[str, Union[str, int, float, bytes]]] = None,
|
|
972
972
|
):
|
|
973
973
|
"""
|
|
974
974
|
Issue an aggregation query.
|
redis/commands/search/field.py
CHANGED
|
@@ -52,14 +52,14 @@ class Field:
|
|
|
52
52
|
self.args_suffix = list()
|
|
53
53
|
self.as_name = as_name
|
|
54
54
|
|
|
55
|
-
if sortable:
|
|
56
|
-
self.args_suffix.append(Field.SORTABLE)
|
|
57
55
|
if no_index:
|
|
58
56
|
self.args_suffix.append(Field.NOINDEX)
|
|
59
57
|
if index_missing:
|
|
60
58
|
self.args_suffix.append(Field.INDEX_MISSING)
|
|
61
59
|
if index_empty:
|
|
62
60
|
self.args_suffix.append(Field.INDEX_EMPTY)
|
|
61
|
+
if sortable:
|
|
62
|
+
self.args_suffix.append(Field.SORTABLE)
|
|
63
63
|
|
|
64
64
|
if no_index and not sortable:
|
|
65
65
|
raise ValueError("Non-Sortable non-Indexable fields are ignored")
|
redis/commands/search/query.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import List, Optional, Union
|
|
1
|
+
from typing import List, Optional, Tuple, Union
|
|
2
2
|
|
|
3
3
|
from redis.commands.search.dialect import DEFAULT_DIALECT
|
|
4
4
|
|
|
@@ -31,7 +31,7 @@ class Query:
|
|
|
31
31
|
self._with_scores: bool = False
|
|
32
32
|
self._scorer: Optional[str] = None
|
|
33
33
|
self._filters: List = list()
|
|
34
|
-
self._ids: Optional[
|
|
34
|
+
self._ids: Optional[Tuple[str, ...]] = None
|
|
35
35
|
self._slop: int = -1
|
|
36
36
|
self._timeout: Optional[float] = None
|
|
37
37
|
self._in_order: bool = False
|
|
@@ -81,7 +81,7 @@ class Query:
|
|
|
81
81
|
self._return_fields += ("AS", as_field)
|
|
82
82
|
return self
|
|
83
83
|
|
|
84
|
-
def _mk_field_list(self, fields: List[str]) -> List:
|
|
84
|
+
def _mk_field_list(self, fields: Optional[Union[List[str], str]]) -> List:
|
|
85
85
|
if not fields:
|
|
86
86
|
return []
|
|
87
87
|
return [fields] if isinstance(fields, str) else list(fields)
|
|
@@ -126,7 +126,7 @@ class Query:
|
|
|
126
126
|
|
|
127
127
|
def highlight(
|
|
128
128
|
self, fields: Optional[List[str]] = None, tags: Optional[List[str]] = None
|
|
129
|
-
) ->
|
|
129
|
+
) -> "Query":
|
|
130
130
|
"""
|
|
131
131
|
Apply specified markup to matched term(s) within the returned field(s).
|
|
132
132
|
|
|
@@ -187,16 +187,16 @@ class Query:
|
|
|
187
187
|
self._scorer = scorer
|
|
188
188
|
return self
|
|
189
189
|
|
|
190
|
-
def get_args(self) -> List[str]:
|
|
190
|
+
def get_args(self) -> List[Union[str, int, float]]:
|
|
191
191
|
"""Format the redis arguments for this query and return them."""
|
|
192
|
-
args = [self._query_string]
|
|
192
|
+
args: List[Union[str, int, float]] = [self._query_string]
|
|
193
193
|
args += self._get_args_tags()
|
|
194
194
|
args += self._summarize_fields + self._highlight_fields
|
|
195
195
|
args += ["LIMIT", self._offset, self._num]
|
|
196
196
|
return args
|
|
197
197
|
|
|
198
|
-
def _get_args_tags(self) -> List[str]:
|
|
199
|
-
args = []
|
|
198
|
+
def _get_args_tags(self) -> List[Union[str, int, float]]:
|
|
199
|
+
args: List[Union[str, int, float]] = []
|
|
200
200
|
if self._no_content:
|
|
201
201
|
args.append("NOCONTENT")
|
|
202
202
|
if self._fields:
|
|
@@ -288,14 +288,14 @@ class Query:
|
|
|
288
288
|
self._with_scores = True
|
|
289
289
|
return self
|
|
290
290
|
|
|
291
|
-
def limit_fields(self, *fields:
|
|
291
|
+
def limit_fields(self, *fields: str) -> "Query":
|
|
292
292
|
"""
|
|
293
293
|
Limit the search to specific TEXT fields only.
|
|
294
294
|
|
|
295
|
-
- **fields**:
|
|
295
|
+
- **fields**: Each element should be a string, case sensitive field name
|
|
296
296
|
from the defined schema.
|
|
297
297
|
"""
|
|
298
|
-
self._fields = fields
|
|
298
|
+
self._fields = list(fields)
|
|
299
299
|
return self
|
|
300
300
|
|
|
301
301
|
def add_filter(self, flt: "Filter") -> "Query":
|
|
@@ -340,7 +340,7 @@ class Query:
|
|
|
340
340
|
|
|
341
341
|
|
|
342
342
|
class Filter:
|
|
343
|
-
def __init__(self, keyword: str, field: str, *args:
|
|
343
|
+
def __init__(self, keyword: str, field: str, *args: Union[str, float]) -> None:
|
|
344
344
|
self.args = [keyword, field] + list(args)
|
|
345
345
|
|
|
346
346
|
|