valkey-glide 2.2.0rc1__cp312-cp312-macosx_10_7_x86_64.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.
Files changed (40) hide show
  1. glide/__init__.py +388 -0
  2. glide/async_commands/__init__.py +5 -0
  3. glide/async_commands/cluster_commands.py +1476 -0
  4. glide/async_commands/core.py +7818 -0
  5. glide/async_commands/ft.py +465 -0
  6. glide/async_commands/glide_json.py +1269 -0
  7. glide/async_commands/standalone_commands.py +1001 -0
  8. glide/glide.cpython-312-darwin.so +0 -0
  9. glide/glide.pyi +61 -0
  10. glide/glide_client.py +821 -0
  11. glide/logger.py +97 -0
  12. glide/opentelemetry.py +185 -0
  13. glide/py.typed +0 -0
  14. glide_shared/__init__.py +330 -0
  15. glide_shared/commands/__init__.py +0 -0
  16. glide_shared/commands/batch.py +5997 -0
  17. glide_shared/commands/batch_options.py +261 -0
  18. glide_shared/commands/bitmap.py +320 -0
  19. glide_shared/commands/command_args.py +103 -0
  20. glide_shared/commands/core_options.py +407 -0
  21. glide_shared/commands/server_modules/ft_options/ft_aggregate_options.py +300 -0
  22. glide_shared/commands/server_modules/ft_options/ft_constants.py +84 -0
  23. glide_shared/commands/server_modules/ft_options/ft_create_options.py +423 -0
  24. glide_shared/commands/server_modules/ft_options/ft_profile_options.py +113 -0
  25. glide_shared/commands/server_modules/ft_options/ft_search_options.py +139 -0
  26. glide_shared/commands/server_modules/json_batch.py +820 -0
  27. glide_shared/commands/server_modules/json_options.py +93 -0
  28. glide_shared/commands/sorted_set.py +412 -0
  29. glide_shared/commands/stream.py +449 -0
  30. glide_shared/config.py +975 -0
  31. glide_shared/constants.py +124 -0
  32. glide_shared/exceptions.py +88 -0
  33. glide_shared/protobuf/command_request_pb2.py +56 -0
  34. glide_shared/protobuf/connection_request_pb2.py +56 -0
  35. glide_shared/protobuf/response_pb2.py +32 -0
  36. glide_shared/protobuf_codec.py +110 -0
  37. glide_shared/routes.py +161 -0
  38. valkey_glide-2.2.0rc1.dist-info/METADATA +210 -0
  39. valkey_glide-2.2.0rc1.dist-info/RECORD +40 -0
  40. valkey_glide-2.2.0rc1.dist-info/WHEEL +4 -0
@@ -0,0 +1,407 @@
1
+ # Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
2
+ from dataclasses import dataclass
3
+ from datetime import datetime, timedelta
4
+ from enum import Enum
5
+ from typing import List, Optional, Type, Union, get_args
6
+
7
+ from glide_shared.commands.command_args import Limit, OrderBy
8
+ from glide_shared.constants import TEncodable
9
+
10
+
11
+ @dataclass
12
+ class PubSubMsg:
13
+ """
14
+ Describes the incoming pubsub message
15
+
16
+ Attributes:
17
+ message (TEncodable): Incoming message.
18
+ channel (TEncodable): Name of an channel that triggered the message.
19
+ pattern (Optional[TEncodable]): Pattern that triggered the message.
20
+ """
21
+
22
+ message: TEncodable
23
+ channel: TEncodable
24
+ pattern: Optional[TEncodable]
25
+
26
+
27
+ class ConditionalChange(Enum):
28
+ """
29
+ A condition to the `SET`, `ZADD` and `GEOADD` commands.
30
+ """
31
+
32
+ ONLY_IF_EXISTS = "XX"
33
+ """ Only update key / elements that already exist. Equivalent to `XX` in the Valkey API. """
34
+
35
+ ONLY_IF_DOES_NOT_EXIST = "NX"
36
+ """ Only set key / add elements that does not already exist. Equivalent to `NX` in the Valkey API. """
37
+
38
+
39
+ class HashFieldConditionalChange(Enum):
40
+ """
41
+ Field conditional change options for HSETEX command.
42
+ """
43
+
44
+ ONLY_IF_ALL_EXIST = "FXX"
45
+ """ Only set fields if all of them already exist. Equivalent to `FXX` in the Valkey API. """
46
+
47
+ ONLY_IF_NONE_EXIST = "FNX"
48
+ """ Only set fields if none of them already exist. Equivalent to `FNX` in the Valkey API. """
49
+
50
+
51
+ @dataclass
52
+ class OnlyIfEqual:
53
+ """
54
+ Change condition to the `SET` command,
55
+ For additional conditonal options see ConditionalChange
56
+
57
+ - comparison_value - value to compare to the current value of a key.
58
+
59
+ If comparison_value is equal to the key, it will overwrite the value of key to the new provided value
60
+ Equivalent to the IFEQ comparison-value in the Valkey API
61
+ """
62
+
63
+ comparison_value: TEncodable
64
+
65
+
66
+ class ExpiryType(Enum):
67
+ """
68
+ SET option: The type of the expiry.
69
+ """
70
+
71
+ SEC = 0, Union[int, timedelta]
72
+ """
73
+ Set the specified expire time, in seconds. Equivalent to `EX` in the Valkey API.
74
+ """
75
+
76
+ MILLSEC = 1, Union[int, timedelta]
77
+ """
78
+ Set the specified expire time, in milliseconds. Equivalent to `PX` in the Valkey API.
79
+ """
80
+
81
+ UNIX_SEC = 2, Union[int, datetime]
82
+ """
83
+ Set the specified Unix time at which the key will expire, in seconds. Equivalent to `EXAT` in the Valkey API.
84
+ """
85
+
86
+ UNIX_MILLSEC = 3, Union[int, datetime]
87
+ """
88
+ Set the specified Unix time at which the key will expire, in milliseconds. Equivalent to `PXAT` in the Valkey API.
89
+ """
90
+
91
+ KEEP_TTL = 4, Type[None]
92
+ """
93
+ Retain the time to live associated with the key. Equivalent to `KEEPTTL` in the Valkey API.
94
+ """
95
+
96
+
97
+ class ExpiryTypeGetEx(Enum):
98
+ """
99
+ GetEx option: The type of the expiry.
100
+ """
101
+
102
+ SEC = 0, Union[int, timedelta]
103
+ """ Set the specified expire time, in seconds. Equivalent to `EX` in the Valkey API. """
104
+
105
+ MILLSEC = 1, Union[int, timedelta]
106
+ """ Set the specified expire time, in milliseconds. Equivalent to `PX` in the Valkey API. """
107
+
108
+ UNIX_SEC = 2, Union[int, datetime]
109
+ """ Set the specified Unix time at which the key will expire, in seconds. Equivalent to `EXAT` in the Valkey API. """
110
+
111
+ UNIX_MILLSEC = 3, Union[int, datetime]
112
+ """ Set the specified Unix time at which the key will expire, in milliseconds. Equivalent to `PXAT` in the Valkey API. """
113
+
114
+ PERSIST = 4, Type[None]
115
+ """ Remove the time to live associated with the key. Equivalent to `PERSIST` in the Valkey API. """
116
+
117
+
118
+ class InfoSection(Enum):
119
+ """
120
+ INFO option: a specific section of information:
121
+
122
+ When no parameter is provided, the default option is assumed.
123
+ """
124
+
125
+ SERVER = "server"
126
+ """ General information about the server """
127
+
128
+ CLIENTS = "clients"
129
+ """ Client connections section """
130
+
131
+ MEMORY = "memory"
132
+ """ Memory consumption related information """
133
+
134
+ PERSISTENCE = "persistence"
135
+ """ RDB and AOF related information """
136
+
137
+ STATS = "stats"
138
+ """ General statistics """
139
+
140
+ REPLICATION = "replication"
141
+ """ Master/replica replication information """
142
+
143
+ CPU = "cpu"
144
+ """ CPU consumption statistics """
145
+
146
+ COMMAND_STATS = "commandstats"
147
+ """ Valkey command statistics """
148
+
149
+ LATENCY_STATS = "latencystats"
150
+ """ Valkey command latency percentile distribution statistics """
151
+
152
+ SENTINEL = "sentinel"
153
+ """ Valkey Sentinel section (only applicable to Sentinel instances) """
154
+
155
+ CLUSTER = "cluster"
156
+ """ Valkey Cluster section """
157
+
158
+ MODULES = "modules"
159
+ """ Modules section """
160
+
161
+ KEYSPACE = "keyspace"
162
+ """ Database related statistics """
163
+
164
+ ERROR_STATS = "errorstats"
165
+ """ Valkey error statistics """
166
+
167
+ ALL = "all"
168
+ """ Return all sections (excluding module generated ones) """
169
+
170
+ DEFAULT = "default"
171
+ """ Return only the default set of sections """
172
+
173
+ EVERYTHING = "everything"
174
+ """ Includes all and modules """
175
+
176
+
177
+ class ExpireOptions(Enum):
178
+ """
179
+ EXPIRE option: options for setting key expiry.
180
+ """
181
+
182
+ HasNoExpiry = "NX"
183
+ """ Set expiry only when the key has no expiry (Equivalent to "NX" in Valkey). """
184
+
185
+ HasExistingExpiry = "XX"
186
+ """ Set expiry only when the key has an existing expiry (Equivalent to "XX" in Valkey). """
187
+
188
+ NewExpiryGreaterThanCurrent = "GT"
189
+ """
190
+ Set expiry only when the new expiry is greater than the current one (Equivalent to "GT" in Valkey).
191
+ """
192
+
193
+ NewExpiryLessThanCurrent = "LT"
194
+ """
195
+ Set expiry only when the new expiry is less than the current one (Equivalent to "LT" in Valkey).
196
+ """
197
+
198
+
199
+ class UpdateOptions(Enum):
200
+ """
201
+ Options for updating elements of a sorted set key.
202
+ """
203
+
204
+ LESS_THAN = "LT"
205
+ """ Only update existing elements if the new score is less than the current score. """
206
+
207
+ GREATER_THAN = "GT"
208
+ """ Only update existing elements if the new score is greater than the current score. """
209
+
210
+
211
+ class ExpirySet:
212
+ """
213
+ SET option: Represents the expiry type and value to be executed with "SET" command.
214
+
215
+ Attributes:
216
+ cmd_arg (str): The expiry type.
217
+ value (str): The value for the expiry type.
218
+ """
219
+
220
+ def __init__(
221
+ self,
222
+ expiry_type: ExpiryType,
223
+ value: Optional[Union[int, datetime, timedelta]],
224
+ ) -> None:
225
+ self.set_expiry_type_and_value(expiry_type, value)
226
+
227
+ def __eq__(self, other: "object") -> bool:
228
+ if not isinstance(other, ExpirySet):
229
+ return NotImplemented
230
+ return self.expiry_type == other.expiry_type and self.value == other.value
231
+
232
+ def set_expiry_type_and_value(
233
+ self, expiry_type: ExpiryType, value: Optional[Union[int, datetime, timedelta]]
234
+ ):
235
+ """
236
+ Args:
237
+ expiry_type (ExpiryType): The expiry type.
238
+ value (Optional[Union[int, datetime, timedelta]]): The value of the expiration type. The type of expiration
239
+ determines the type of expiration value:
240
+
241
+ - SEC: Union[int, timedelta]
242
+ - MILLSEC: Union[int, timedelta]
243
+ - UNIX_SEC: Union[int, datetime]
244
+ - UNIX_MILLSEC: Union[int, datetime]
245
+ - KEEP_TTL: Type[None]
246
+ """
247
+ if not isinstance(value, get_args(expiry_type.value[1])):
248
+ raise ValueError(
249
+ f"The value of {expiry_type} should be of type {expiry_type.value[1]}"
250
+ )
251
+ self.expiry_type = expiry_type
252
+ if self.expiry_type == ExpiryType.SEC:
253
+ self.cmd_arg = "EX"
254
+ if isinstance(value, timedelta):
255
+ value = int(value.total_seconds())
256
+ elif self.expiry_type == ExpiryType.MILLSEC:
257
+ self.cmd_arg = "PX"
258
+ if isinstance(value, timedelta):
259
+ value = int(value.total_seconds() * 1000)
260
+ elif self.expiry_type == ExpiryType.UNIX_SEC:
261
+ self.cmd_arg = "EXAT"
262
+ if isinstance(value, datetime):
263
+ value = int(value.timestamp())
264
+ elif self.expiry_type == ExpiryType.UNIX_MILLSEC:
265
+ self.cmd_arg = "PXAT"
266
+ if isinstance(value, datetime):
267
+ value = int(value.timestamp() * 1000)
268
+ elif self.expiry_type == ExpiryType.KEEP_TTL:
269
+ self.cmd_arg = "KEEPTTL"
270
+ self.value = str(value) if value else None
271
+
272
+ def get_cmd_args(self) -> List[str]:
273
+ return [self.cmd_arg] if self.value is None else [self.cmd_arg, self.value]
274
+
275
+
276
+ class ExpiryGetEx:
277
+ """
278
+ GetEx option: Represents the expiry type and value to be executed with "GetEx" command.
279
+
280
+ Attributes:
281
+ cmd_arg (str): The expiry type.
282
+ value (str): The value for the expiry type.
283
+ """
284
+
285
+ def __init__(
286
+ self,
287
+ expiry_type: ExpiryTypeGetEx,
288
+ value: Optional[Union[int, datetime, timedelta]],
289
+ ) -> None:
290
+ self.set_expiry_type_and_value(expiry_type, value)
291
+
292
+ def set_expiry_type_and_value(
293
+ self,
294
+ expiry_type: ExpiryTypeGetEx,
295
+ value: Optional[Union[int, datetime, timedelta]],
296
+ ):
297
+ """
298
+ Args:
299
+ expiry_type (ExpiryType): The expiry type.
300
+ value (Optional[Union[int, datetime, timedelta]]): The value of the expiration type. The type of expiration
301
+ determines the type of expiration value:
302
+
303
+ - SEC: Union[int, timedelta]
304
+ - MILLSEC: Union[int, timedelta]
305
+ - UNIX_SEC: Union[int, datetime]
306
+ - UNIX_MILLSEC: Union[int, datetime]
307
+ - PERSIST: Type[None]
308
+ """
309
+ if not isinstance(value, get_args(expiry_type.value[1])):
310
+ raise ValueError(
311
+ f"The value of {expiry_type} should be of type {expiry_type.value[1]}"
312
+ )
313
+ self.expiry_type = expiry_type
314
+ if self.expiry_type == ExpiryTypeGetEx.SEC:
315
+ self.cmd_arg = "EX"
316
+ if isinstance(value, timedelta):
317
+ value = int(value.total_seconds())
318
+ elif self.expiry_type == ExpiryTypeGetEx.MILLSEC:
319
+ self.cmd_arg = "PX"
320
+ if isinstance(value, timedelta):
321
+ value = int(value.total_seconds() * 1000)
322
+ elif self.expiry_type == ExpiryTypeGetEx.UNIX_SEC:
323
+ self.cmd_arg = "EXAT"
324
+ if isinstance(value, datetime):
325
+ value = int(value.timestamp())
326
+ elif self.expiry_type == ExpiryTypeGetEx.UNIX_MILLSEC:
327
+ self.cmd_arg = "PXAT"
328
+ if isinstance(value, datetime):
329
+ value = int(value.timestamp() * 1000)
330
+ elif self.expiry_type == ExpiryTypeGetEx.PERSIST:
331
+ self.cmd_arg = "PERSIST"
332
+ self.value = str(value) if value else None
333
+
334
+ def get_cmd_args(self) -> List[str]:
335
+ return [self.cmd_arg] if self.value is None else [self.cmd_arg, self.value]
336
+
337
+
338
+ class InsertPosition(Enum):
339
+ BEFORE = "BEFORE"
340
+ AFTER = "AFTER"
341
+
342
+
343
+ class FlushMode(Enum):
344
+ """
345
+ Defines flushing mode for:
346
+
347
+ `FLUSHALL` command and `FUNCTION FLUSH` command.
348
+
349
+ See [FLUSHAL](https://valkey.io/commands/flushall/) and [FUNCTION-FLUSH](https://valkey.io/commands/function-flush/)
350
+ for details
351
+
352
+ SYNC was introduced in version 6.2.0.
353
+ """
354
+
355
+ ASYNC = "ASYNC"
356
+ SYNC = "SYNC"
357
+
358
+
359
+ class FunctionRestorePolicy(Enum):
360
+ """
361
+ Options for the FUNCTION RESTORE command.
362
+ """
363
+
364
+ APPEND = "APPEND"
365
+ """ Appends the restored libraries to the existing libraries and aborts on collision. This is the default policy. """
366
+
367
+ FLUSH = "FLUSH"
368
+ """ Deletes all existing libraries before restoring the payload. """
369
+
370
+ REPLACE = "REPLACE"
371
+ """
372
+ Appends the restored libraries to the existing libraries, replacing any existing ones in case
373
+ of name collisions. Note that this policy doesn't prevent function name collisions, only libraries.
374
+ """
375
+
376
+
377
+ def _build_sort_args(
378
+ key: TEncodable,
379
+ by_pattern: Optional[TEncodable] = None,
380
+ limit: Optional[Limit] = None,
381
+ get_patterns: Optional[List[TEncodable]] = None,
382
+ order: Optional[OrderBy] = None,
383
+ alpha: Optional[bool] = None,
384
+ store: Optional[TEncodable] = None,
385
+ ) -> List[TEncodable]:
386
+ args = [key]
387
+
388
+ if by_pattern:
389
+ args.extend(["BY", by_pattern])
390
+
391
+ if limit:
392
+ args.extend(["LIMIT", str(limit.offset), str(limit.count)])
393
+
394
+ if get_patterns:
395
+ for pattern in get_patterns:
396
+ args.extend(["GET", pattern])
397
+
398
+ if order:
399
+ args.append(order.value)
400
+
401
+ if alpha:
402
+ args.append("ALPHA")
403
+
404
+ if store:
405
+ args.extend(["STORE", store])
406
+
407
+ return args
@@ -0,0 +1,300 @@
1
+ # Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
2
+ from abc import ABC, abstractmethod
3
+ from typing import List, Mapping, Optional
4
+
5
+ from glide_shared.commands.command_args import OrderBy
6
+ from glide_shared.commands.server_modules.ft_options.ft_constants import (
7
+ FtAggregateKeywords,
8
+ )
9
+ from glide_shared.constants import TEncodable
10
+
11
+
12
+ class FtAggregateClause(ABC):
13
+ """
14
+ Abstract base class for the FT.AGGREGATE command clauses.
15
+ """
16
+
17
+ @abstractmethod
18
+ def to_args(self) -> List[TEncodable]:
19
+ """
20
+ Get the arguments for the clause of the FT.AGGREGATE command.
21
+
22
+ Returns:
23
+ List[TEncodable]: A list of arguments for the clause of the FT.AGGREGATE command.
24
+ """
25
+ args: List[TEncodable] = []
26
+ return args
27
+
28
+
29
+ class FtAggregateLimit(FtAggregateClause):
30
+ """
31
+ A clause for limiting the number of retained records.
32
+ """
33
+
34
+ def __init__(self, offset: int, count: int):
35
+ """
36
+ Initialize a new FtAggregateLimit instance.
37
+
38
+ Args:
39
+ offset (int): Starting point from which the records have to be retained.
40
+ count (int): The total number of records to be retained.
41
+ """
42
+ self.offset = offset
43
+ self.count = count
44
+
45
+ def to_args(self) -> List[TEncodable]:
46
+ """
47
+ Get the arguments for the Limit clause.
48
+
49
+ Returns:
50
+ List[TEncodable]: A list of Limit clause arguments.
51
+ """
52
+ return [FtAggregateKeywords.LIMIT, str(self.offset), str(self.count)]
53
+
54
+
55
+ class FtAggregateFilter(FtAggregateClause):
56
+ """
57
+ A clause for filtering the results using predicate expression relating to values in each result. It is applied post query
58
+ and relate to the current state of the pipeline.
59
+ """
60
+
61
+ def __init__(self, expression: TEncodable):
62
+ """
63
+ Initialize a new FtAggregateFilter instance.
64
+
65
+ Args:
66
+ expression (TEncodable): The expression to filter the results.
67
+ """
68
+ self.expression = expression
69
+
70
+ def to_args(self) -> List[TEncodable]:
71
+ """
72
+ Get the arguments for the Filter clause.
73
+
74
+ Returns:
75
+ List[TEncodable]: A list arguments for the filter clause.
76
+ """
77
+ return [FtAggregateKeywords.FILTER, self.expression]
78
+
79
+
80
+ class FtAggregateReducer:
81
+ """
82
+ A clause for reducing the matching results in each group using a reduction function. The matching results are reduced into
83
+ a single record.
84
+ """
85
+
86
+ def __init__(
87
+ self,
88
+ function: TEncodable,
89
+ args: List[TEncodable],
90
+ name: Optional[TEncodable] = None,
91
+ ):
92
+ """
93
+ Initialize a new FtAggregateReducer instance.
94
+
95
+ Args:
96
+ function (TEncodable): The reduction function names for the respective group.
97
+ args (List[TEncodable]): The list of arguments for the reducer.
98
+ name (Optional[TEncodable]): User defined property name for the reducer.
99
+ """
100
+ self.function = function
101
+ self.args = args
102
+ self.name = name
103
+
104
+ def to_args(self) -> List[TEncodable]:
105
+ """
106
+ Get the arguments for the Reducer.
107
+
108
+ Returns:
109
+ List[TEncodable]: A list of arguments for the reducer.
110
+ """
111
+ args: List[TEncodable] = [
112
+ FtAggregateKeywords.REDUCE,
113
+ self.function,
114
+ str(len(self.args)),
115
+ ] + self.args
116
+ if self.name:
117
+ args.extend([FtAggregateKeywords.AS, self.name])
118
+ return args
119
+
120
+
121
+ class FtAggregateGroupBy(FtAggregateClause):
122
+ """
123
+ A clause for grouping the results in the pipeline based on one or more properties.
124
+ """
125
+
126
+ def __init__(
127
+ self, properties: List[TEncodable], reducers: List[FtAggregateReducer]
128
+ ):
129
+ """
130
+ Initialize a new FtAggregateGroupBy instance.
131
+
132
+ Args:
133
+ properties (List[TEncodable]): The list of properties to be used for grouping the results in the pipeline.
134
+ reducers (List[Reducer]): The list of functions that handles the group entries by performing multiple
135
+ aggregate operations.
136
+ """
137
+ self.properties = properties
138
+ self.reducers = reducers
139
+
140
+ def to_args(self) -> List[TEncodable]:
141
+ args = [
142
+ FtAggregateKeywords.GROUPBY,
143
+ str(len(self.properties)),
144
+ ] + self.properties
145
+ if self.reducers:
146
+ for reducer in self.reducers:
147
+ args.extend(reducer.to_args())
148
+ return args
149
+
150
+
151
+ class FtAggregateSortProperty:
152
+ """
153
+ This class represents the a single property for the SortBy clause.
154
+ """
155
+
156
+ def __init__(self, property: TEncodable, order: OrderBy):
157
+ """
158
+ Initialize a new FtAggregateSortProperty instance.
159
+
160
+ Args:
161
+ property (TEncodable): The sorting parameter.
162
+ order (OrderBy): The order for the sorting. This option can be added for each property.
163
+ """
164
+ self.property = property
165
+ self.order = order
166
+
167
+ def to_args(self) -> List[TEncodable]:
168
+ """
169
+ Get the arguments for the SortBy clause property.
170
+
171
+ Returns:
172
+ List[TEncodable]: A list of arguments for the SortBy clause property.
173
+ """
174
+ return [self.property, self.order.value]
175
+
176
+
177
+ class FtAggregateSortBy(FtAggregateClause):
178
+ """
179
+ A clause for sorting the pipeline up until the point of SORTBY, using a list of properties.
180
+ """
181
+
182
+ def __init__(
183
+ self, properties: List[FtAggregateSortProperty], max: Optional[int] = None
184
+ ):
185
+ """
186
+ Initialize a new FtAggregateSortBy instance.
187
+
188
+ Args:
189
+ properties (List[FtAggregateSortProperty]): A list of sorting parameters for the sort operation.
190
+ max: (Optional[int]): The MAX value for optimizing the sorting, by sorting only for the n-largest elements.
191
+ """
192
+ self.properties = properties
193
+ self.max = max
194
+
195
+ def to_args(self) -> List[TEncodable]:
196
+ """
197
+ Get the arguments for the SortBy clause.
198
+
199
+ Returns:
200
+ List[TEncodable]: A list of arguments for the SortBy clause.
201
+ """
202
+ args: List[TEncodable] = [
203
+ FtAggregateKeywords.SORTBY,
204
+ str(len(self.properties) * 2),
205
+ ]
206
+ for property in self.properties:
207
+ args.extend(property.to_args())
208
+ if self.max:
209
+ args.extend([FtAggregateKeywords.MAX, str(self.max)])
210
+ return args
211
+
212
+
213
+ class FtAggregateApply(FtAggregateClause):
214
+ """
215
+ A clause for applying a 1-to-1 transformation on one or more properties and stores the result as a new property down the
216
+ pipeline or replaces any property using this transformation.
217
+ """
218
+
219
+ def __init__(self, expression: TEncodable, name: TEncodable):
220
+ """
221
+ Initialize a new FtAggregateApply instance.
222
+
223
+ Args:
224
+ expression (TEncodable): The expression to be transformed.
225
+ name (TEncodable): The new property name to store the result of apply. This name can be referenced by further
226
+ APPLY/SORTBY/GROUPBY/REDUCE operations down the pipeline.
227
+ """
228
+ self.expression = expression
229
+ self.name = name
230
+
231
+ def to_args(self) -> List[TEncodable]:
232
+ """
233
+ Get the arguments for the Apply clause.
234
+
235
+ Returns:
236
+ List[TEncodable]: A list of arguments for the Apply clause.
237
+ """
238
+ return [
239
+ FtAggregateKeywords.APPLY,
240
+ self.expression,
241
+ FtAggregateKeywords.AS,
242
+ self.name,
243
+ ]
244
+
245
+
246
+ class FtAggregateOptions:
247
+ """
248
+ This class represents the optional arguments for the FT.AGGREGATE command.
249
+ """
250
+
251
+ def __init__(
252
+ self,
253
+ loadAll: Optional[bool] = False,
254
+ loadFields: Optional[List[TEncodable]] = [],
255
+ timeout: Optional[int] = None,
256
+ params: Optional[Mapping[TEncodable, TEncodable]] = {},
257
+ clauses: Optional[List[FtAggregateClause]] = [],
258
+ ):
259
+ """
260
+ Initialize a new FtAggregateOptions instance.
261
+
262
+ Args:
263
+ loadAll (Optional[bool]): An option to load all fields declared in the index.
264
+ loadFields (Optional[List[TEncodable]]): An option to load only the fields passed in this list.
265
+ timeout (Optional[int]): Overrides the timeout parameter of the module.
266
+ params (Optional[Mapping[TEncodable, TEncodable]]): The key/value pairs can be referenced from within the
267
+ query expression.
268
+ clauses (Optional[List[FtAggregateClause]]): FILTER, LIMIT, GROUPBY, SORTBY and APPLY clauses, that can be
269
+ repeated multiple times in any order and be freely intermixed. They are applied in the order specified, with
270
+ the output of one clause feeding the input of the next clause.
271
+ """
272
+ self.loadAll = loadAll
273
+ self.loadFields = loadFields
274
+ self.timeout = timeout
275
+ self.params = params
276
+ self.clauses = clauses
277
+
278
+ def to_args(self) -> List[TEncodable]:
279
+ """
280
+ Get the optional arguments for the FT.AGGREGATE command.
281
+
282
+ Returns:
283
+ List[TEncodable]: A list of optional arguments for the FT.AGGREGATE command.
284
+ """
285
+ args: List[TEncodable] = []
286
+ if self.loadAll:
287
+ args.extend([FtAggregateKeywords.LOAD, "*"])
288
+ elif self.loadFields:
289
+ args.extend([FtAggregateKeywords.LOAD, str(len(self.loadFields))])
290
+ args.extend(self.loadFields)
291
+ if self.timeout:
292
+ args.extend([FtAggregateKeywords.TIMEOUT, str(self.timeout)])
293
+ if self.params:
294
+ args.extend([FtAggregateKeywords.PARAMS, str(len(self.params) * 2)])
295
+ for [name, value] in self.params.items():
296
+ args.extend([name, value])
297
+ if self.clauses:
298
+ for clause in self.clauses:
299
+ args.extend(clause.to_args())
300
+ return args