valkey-glide 2.2.1rc1__cp313-cp313-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.

Potentially problematic release.


This version of valkey-glide might be problematic. Click here for more details.

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-313-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.1rc1.dist-info/METADATA +210 -0
  39. valkey_glide-2.2.1rc1.dist-info/RECORD +40 -0
  40. valkey_glide-2.2.1rc1.dist-info/WHEEL +4 -0
@@ -0,0 +1,449 @@
1
+ # Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
2
+ from __future__ import annotations
3
+
4
+ from abc import ABC, abstractmethod
5
+ from typing import List, Optional, Union
6
+
7
+ from glide_shared.constants import TEncodable
8
+
9
+
10
+ class StreamTrimOptions(ABC):
11
+ """
12
+ Abstract base class for stream trim options.
13
+
14
+ Attributes:
15
+ exact (bool): If `true`, the stream will be trimmed exactly.
16
+ Otherwise the stream will be trimmed in a near-exact manner, which is more efficient.
17
+ threshold (Union[TEncodable, int]): Threshold for trimming.
18
+ method (str): Method for trimming (e.g., MINID, MAXLEN).
19
+ limit (Optional[int]): Max number of entries to be trimmed. Defaults to None.
20
+ Note: If `exact` is set to `True`, `limit` cannot be specified.
21
+ """
22
+
23
+ @abstractmethod
24
+ def __init__(
25
+ self,
26
+ exact: bool,
27
+ threshold: Union[TEncodable, int],
28
+ method: str,
29
+ limit: Optional[int] = None,
30
+ ):
31
+ """
32
+ Initialize stream trim options.
33
+ """
34
+ if exact and limit:
35
+ raise ValueError(
36
+ "If `exact` is set to `True`, `limit` cannot be specified."
37
+ )
38
+ self.exact = exact
39
+ self.threshold = threshold
40
+ self.method = method
41
+ self.limit = limit
42
+
43
+ def to_args(self) -> List[str]:
44
+ """
45
+ Convert options to arguments for the command.
46
+
47
+ Returns:
48
+ List[str]: List of arguments for the command.
49
+ """
50
+ option_args = [
51
+ self.method,
52
+ "=" if self.exact else "~",
53
+ str(self.threshold),
54
+ ]
55
+ if self.limit is not None:
56
+ option_args.extend(["LIMIT", str(self.limit)])
57
+ return option_args
58
+
59
+
60
+ class TrimByMinId(StreamTrimOptions):
61
+ """
62
+ Stream trim option to trim by minimum ID.
63
+
64
+ Attributes:
65
+ exact (bool): If `true`, the stream will be trimmed exactly.
66
+ Otherwise the stream will be trimmed in a near-exact manner, which is more efficient.
67
+ threshold (TEncodable): Threshold for trimming by minimum ID.
68
+ limit (Optional[int]): Max number of entries to be trimmed. Defaults to None.
69
+ Note: If `exact` is set to `True`, `limit` cannot be specified.
70
+ """
71
+
72
+ def __init__(self, exact: bool, threshold: TEncodable, limit: Optional[int] = None):
73
+ """
74
+ Initialize trim option by minimum ID.
75
+ """
76
+ super().__init__(exact, threshold, "MINID", limit)
77
+
78
+
79
+ class TrimByMaxLen(StreamTrimOptions):
80
+ """
81
+ Stream trim option to trim by maximum length.
82
+
83
+ Attributes:
84
+ exact (bool): If `true`, the stream will be trimmed exactly.
85
+ Otherwise the stream will be trimmed in a near-exact manner, which is more efficient.
86
+ threshold (int): Threshold for trimming by maximum length.
87
+ limit (Optional[int]): Max number of entries to be trimmed. Defaults to None.
88
+ Note: If `exact` is set to `True`, `limit` cannot be specified.
89
+ """
90
+
91
+ def __init__(self, exact: bool, threshold: int, limit: Optional[int] = None):
92
+ """
93
+ Initialize trim option by maximum length.
94
+ """
95
+ super().__init__(exact, threshold, "MAXLEN", limit)
96
+
97
+
98
+ class StreamAddOptions:
99
+ """
100
+ Options for adding entries to a stream.
101
+
102
+ Attributes:
103
+ id (Optional[TEncodable]): ID for the new entry. If set, the new entry will be added with this ID. If not
104
+ specified, '*' is used.
105
+ make_stream (bool, optional): If set to False, a new stream won't be created if no stream matches the given key.
106
+ trim (Optional[StreamTrimOptions]): If set, the add operation will also trim the older entries in the stream.
107
+ See `StreamTrimOptions`.
108
+ """
109
+
110
+ def __init__(
111
+ self,
112
+ id: Optional[TEncodable] = None,
113
+ make_stream: bool = True,
114
+ trim: Optional[StreamTrimOptions] = None,
115
+ ):
116
+ """
117
+ Initialize stream add options.
118
+ """
119
+ self.id = id
120
+ self.make_stream = make_stream
121
+ self.trim = trim
122
+
123
+ def to_args(self) -> List[TEncodable]:
124
+ """
125
+ Convert options to arguments for the command.
126
+
127
+ Returns:
128
+ List[str]: List of arguments for the command.
129
+ """
130
+ option_args: List[TEncodable] = []
131
+ if not self.make_stream:
132
+ option_args.append("NOMKSTREAM")
133
+ if self.trim:
134
+ option_args.extend(self.trim.to_args())
135
+ option_args.append(self.id if self.id else "*")
136
+
137
+ return option_args
138
+
139
+
140
+ class StreamRangeBound(ABC):
141
+ """
142
+ Abstract Base Class used in the `XPENDING`, `XRANGE`, and `XREVRANGE` commands to specify the starting and ending
143
+ range bound for the stream search by stream entry ID.
144
+ """
145
+
146
+ @abstractmethod
147
+ def to_arg(self) -> TEncodable:
148
+ """
149
+ Returns the stream range bound as a string argument to be used in the `XRANGE` or `XREVRANGE` commands.
150
+ """
151
+ pass
152
+
153
+
154
+ class MinId(StreamRangeBound):
155
+ """
156
+ Stream ID boundary used to specify the minimum stream entry ID. Can be used in the `XRANGE` or `XREVRANGE` commands
157
+ to get the first stream ID.
158
+ """
159
+
160
+ MIN_RANGE_VALKEY_API = "-"
161
+
162
+ def to_arg(self) -> str:
163
+ return self.MIN_RANGE_VALKEY_API
164
+
165
+
166
+ class MaxId(StreamRangeBound):
167
+ """
168
+ Stream ID boundary used to specify the maximum stream entry ID. Can be used in the `XRANGE` or `XREVRANGE` commands
169
+ to get the last stream ID.
170
+ """
171
+
172
+ MAX_RANGE_VALKEY_API = "+"
173
+
174
+ def to_arg(self) -> str:
175
+ return self.MAX_RANGE_VALKEY_API
176
+
177
+
178
+ class IdBound(StreamRangeBound):
179
+ """
180
+ Inclusive (closed) stream ID boundary used to specify a range of IDs to search. Stream ID bounds can be complete
181
+ with a timestamp and sequence number separated by a dash ("-"), for example "1526985054069-0". Stream ID bounds can
182
+ also be incomplete, with just a timestamp.
183
+
184
+ Attributes:
185
+ stream_id (str): The stream ID.
186
+ """
187
+
188
+ @staticmethod
189
+ def from_timestamp(timestamp: int) -> IdBound:
190
+ """
191
+ Creates an incomplete stream ID boundary without the sequence number for a range search.
192
+
193
+ Args:
194
+ timestamp (int): The stream ID timestamp.
195
+ """
196
+ return IdBound(str(timestamp))
197
+
198
+ def __init__(self, stream_id: TEncodable):
199
+ """
200
+ Creates a stream ID boundary for a range search.
201
+ """
202
+ self.stream_id = stream_id
203
+
204
+ def to_arg(self) -> TEncodable:
205
+ return self.stream_id
206
+
207
+
208
+ class ExclusiveIdBound(StreamRangeBound):
209
+ """
210
+ Exclusive (open) stream ID boundary used to specify a range of IDs to search. Stream ID bounds can be complete with
211
+ a timestamp and sequence number separated by a dash ("-"), for example "1526985054069-0". Stream ID bounds can also
212
+ be incomplete, with just a timestamp.
213
+
214
+ Since: Valkey version 6.2.0.
215
+
216
+ Attributes:
217
+ stream_id (TEncodable): The stream ID.
218
+ """
219
+
220
+ EXCLUSIVE_BOUND_VALKEY_API = "("
221
+
222
+ @staticmethod
223
+ def from_timestamp(timestamp: int) -> ExclusiveIdBound:
224
+ """
225
+ Creates an incomplete stream ID boundary without the sequence number for a range search.
226
+
227
+ Args:
228
+ timestamp (int): The stream ID timestamp.
229
+ """
230
+ return ExclusiveIdBound(str(timestamp))
231
+
232
+ def __init__(self, stream_id: TEncodable):
233
+ """
234
+ Creates a stream ID boundary for a range search.
235
+ """
236
+ if isinstance(stream_id, bytes):
237
+ stream_id = stream_id.decode("utf-8")
238
+ self.stream_id = f"{self.EXCLUSIVE_BOUND_VALKEY_API}{stream_id}"
239
+
240
+ def to_arg(self) -> TEncodable:
241
+ return self.stream_id
242
+
243
+
244
+ class StreamReadOptions:
245
+ """
246
+ Options for reading entries from streams. Can be used as an optional argument to `XREAD`.
247
+
248
+ Attributes:
249
+ block_ms (Optional[int]): If provided, the request will be blocked for the set amount of milliseconds or
250
+ until the server has the required number of entries. Equivalent to `BLOCK` in the Valkey API.
251
+ count (Optional[int]): The maximum number of elements requested. Equivalent to `COUNT` in the Valkey API.
252
+ """
253
+
254
+ READ_COUNT_VALKEY_API = "COUNT"
255
+ READ_BLOCK_VALKEY_API = "BLOCK"
256
+
257
+ def __init__(self, block_ms: Optional[int] = None, count: Optional[int] = None):
258
+ self.block_ms = block_ms
259
+ self.count = count
260
+
261
+ def to_args(self) -> List[TEncodable]:
262
+ """
263
+ Returns the options as a list of string arguments to be used in the `XREAD` command.
264
+
265
+ Returns:
266
+ List[TEncodable]: The options as a list of arguments for the `XREAD` command.
267
+ """
268
+ args: List[TEncodable] = []
269
+ if self.block_ms is not None:
270
+ args.extend([self.READ_BLOCK_VALKEY_API, str(self.block_ms)])
271
+
272
+ if self.count is not None:
273
+ args.extend([self.READ_COUNT_VALKEY_API, str(self.count)])
274
+
275
+ return args
276
+
277
+
278
+ class StreamGroupOptions:
279
+ """
280
+ Options for creating stream consumer groups. Can be used as an optional argument to `XGROUP CREATE`.
281
+
282
+ Attributes:
283
+ make_stream (bool): If set to True and the stream doesn't exist, this creates a new stream with a
284
+ length of 0.
285
+ entries_read: (Optional[int]): A value representing the number of stream entries already read by the
286
+ group. This option can only be specified if you are using Valkey version 7.0.0 or above.
287
+ """
288
+
289
+ MAKE_STREAM_VALKEY_API = "MKSTREAM"
290
+ ENTRIES_READ_VALKEY_API = "ENTRIESREAD"
291
+
292
+ def __init__(self, make_stream: bool = False, entries_read: Optional[int] = None):
293
+ self.make_stream = make_stream
294
+ self.entries_read = entries_read
295
+
296
+ def to_args(self) -> List[TEncodable]:
297
+ """
298
+ Returns the options as a list of string arguments to be used in the `XGROUP CREATE` command.
299
+
300
+ Returns:
301
+ List[TEncodable]: The options as a list of arguments for the `XGROUP CREATE` command.
302
+ """
303
+ args: List[TEncodable] = []
304
+ if self.make_stream is True:
305
+ args.append(self.MAKE_STREAM_VALKEY_API)
306
+
307
+ if self.entries_read is not None:
308
+ args.extend([self.ENTRIES_READ_VALKEY_API, str(self.entries_read)])
309
+
310
+ return args
311
+
312
+
313
+ class StreamReadGroupOptions(StreamReadOptions):
314
+ """
315
+ Options for reading entries from streams using a consumer group. Can be used as an optional argument to
316
+ `XREADGROUP`.
317
+
318
+ Attributes:
319
+ no_ack (bool): If set, messages are not added to the Pending Entries List (PEL). This is equivalent to
320
+ acknowledging the message when it is read. Equivalent to `NOACK` in the Valkey API.
321
+ block_ms (Optional[int]): If provided, the request will be blocked for the set amount of milliseconds or
322
+ until the server has the required number of entries. Equivalent to `BLOCK` in the Valkey API.
323
+ count (Optional[int]): The maximum number of elements requested. Equivalent to `COUNT` in the Valkey API.
324
+ """
325
+
326
+ READ_NOACK_VALKEY_API = "NOACK"
327
+
328
+ def __init__(
329
+ self, no_ack=False, block_ms: Optional[int] = None, count: Optional[int] = None
330
+ ):
331
+ super().__init__(block_ms=block_ms, count=count)
332
+ self.no_ack = no_ack
333
+
334
+ def to_args(self) -> List[TEncodable]:
335
+ """
336
+ Returns the options as a list of string arguments to be used in the `XREADGROUP` command.
337
+
338
+ Returns:
339
+ List[TEncodable]: The options as a list of arguments for the `XREADGROUP` command.
340
+ """
341
+ args: List[TEncodable] = super().to_args()
342
+ if self.no_ack:
343
+ args.append(self.READ_NOACK_VALKEY_API)
344
+
345
+ return args
346
+
347
+
348
+ class StreamPendingOptions:
349
+ """
350
+ Options for `XPENDING` that can be used to filter returned items by minimum idle time and consumer name.
351
+
352
+ Attributes:
353
+ min_idle_time_ms (Optional[int]): Filters pending entries by their minimum idle time in milliseconds. This
354
+ option can only be specified if you are using Valkey version 6.2.0 or above.
355
+ consumer_name (Optional[TEncodable]): Filters pending entries by consumer name.
356
+ """
357
+
358
+ IDLE_TIME_VALKEY_API = "IDLE"
359
+
360
+ def __init__(
361
+ self,
362
+ min_idle_time_ms: Optional[int] = None,
363
+ consumer_name: Optional[TEncodable] = None,
364
+ ):
365
+ self.min_idle_time = min_idle_time_ms
366
+ self.consumer_name = consumer_name
367
+
368
+
369
+ class StreamClaimOptions:
370
+ """
371
+ Options for `XCLAIM`.
372
+
373
+ Attributes:
374
+ idle (Optional[int]): Set the idle time (last time it was delivered) of the message in milliseconds. If idle
375
+ is not specified, an idle of `0` is assumed, that is, the time count is reset because the message now has a
376
+ new owner trying to process it.
377
+ idle_unix_time (Optional[int]): This is the same as idle but instead of a relative amount of milliseconds,
378
+ it sets the idle time to a specific Unix time (in milliseconds). This is useful in order to rewrite the AOF
379
+ file generating `XCLAIM` commands.
380
+ retry_count (Optional[int]): Set the retry counter to the specified value. This counter is incremented every
381
+ time a message is delivered again. Normally `XCLAIM` does not alter this counter, which is just served to
382
+ clients when the `XPENDING` command is called: this way clients can detect anomalies, like messages that
383
+ are never processed for some reason after a big number of delivery attempts.
384
+ is_force (Optional[bool]): Creates the pending message entry in the PEL even if certain specified IDs are not
385
+ already in the PEL assigned to a different client. However, the message must exist in the stream, otherwise
386
+ the IDs of non-existing messages are ignored.
387
+ """
388
+
389
+ IDLE_VALKEY_API = "IDLE"
390
+ TIME_VALKEY_API = "TIME"
391
+ RETRY_COUNT_VALKEY_API = "RETRYCOUNT"
392
+ FORCE_VALKEY_API = "FORCE"
393
+ JUST_ID_VALKEY_API = "JUSTID"
394
+
395
+ def __init__(
396
+ self,
397
+ idle: Optional[int] = None,
398
+ idle_unix_time: Optional[int] = None,
399
+ retry_count: Optional[int] = None,
400
+ is_force: Optional[bool] = False,
401
+ ):
402
+ self.idle = idle
403
+ self.idle_unix_time = idle_unix_time
404
+ self.retry_count = retry_count
405
+ self.is_force = is_force
406
+
407
+ def to_args(self) -> List[TEncodable]:
408
+ """
409
+ Converts options for `XCLAIM` into a List.
410
+
411
+ Returns:
412
+ List[str]: The options as a list of arguments for the `XCLAIM` command.
413
+ """
414
+ args: List[TEncodable] = []
415
+ if self.idle:
416
+ args.append(self.IDLE_VALKEY_API)
417
+ args.append(str(self.idle))
418
+
419
+ if self.idle_unix_time:
420
+ args.append(self.TIME_VALKEY_API)
421
+ args.append(str(self.idle_unix_time))
422
+
423
+ if self.retry_count:
424
+ args.append(self.RETRY_COUNT_VALKEY_API)
425
+ args.append(str(self.retry_count))
426
+
427
+ if self.is_force:
428
+ args.append(self.FORCE_VALKEY_API)
429
+
430
+ return args
431
+
432
+
433
+ def _create_xpending_range_args(
434
+ key: TEncodable,
435
+ group_name: TEncodable,
436
+ start: StreamRangeBound,
437
+ end: StreamRangeBound,
438
+ count: int,
439
+ options: Optional[StreamPendingOptions],
440
+ ) -> List[TEncodable]:
441
+ args = [key, group_name]
442
+ if options is not None and options.min_idle_time is not None:
443
+ args.extend([options.IDLE_TIME_VALKEY_API, str(options.min_idle_time)])
444
+
445
+ args.extend([start.to_arg(), end.to_arg(), str(count)])
446
+ if options is not None and options.consumer_name is not None:
447
+ args.append(options.consumer_name)
448
+
449
+ return args