encore-dev 2.0.0a7__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.
Files changed (44) hide show
  1. encore/__init__.py +43 -0
  2. encore/cron/__init__.py +50 -0
  3. encore/internal/__init__.py +1 -0
  4. encore/internal/_loader.py +79 -0
  5. encore/internal/_native.pyi +734 -0
  6. encore/internal/lazy.py +35 -0
  7. encore/internal/runtime.py +133 -0
  8. encore/internal/startup.py +24 -0
  9. encore/logs/__init__.py +19 -0
  10. encore/logs/_console.py +155 -0
  11. encore/logs/_runtime.py +56 -0
  12. encore/meta/__init__.py +228 -0
  13. encore/metrics/__init__.py +390 -0
  14. encore/pubsub/__init__.py +425 -0
  15. encore/py.typed +0 -0
  16. encore/secrets/__init__.py +139 -0
  17. encore/shutdown/__init__.py +164 -0
  18. encore/storage/__init__.py +5 -0
  19. encore/storage/objects/__init__.py +396 -0
  20. encore/storage/postgres/__init__.py +737 -0
  21. encore/storage/redis/__init__.py +200 -0
  22. encore/storage/redis/_base.py +42 -0
  23. encore/storage/redis/_responses.py +150 -0
  24. encore/storage/redis/_values.py +189 -0
  25. encore/storage/redis/bitmap.py +142 -0
  26. encore/storage/redis/generic.py +367 -0
  27. encore/storage/redis/geo.py +508 -0
  28. encore/storage/redis/hash.py +504 -0
  29. encore/storage/redis/json.py +614 -0
  30. encore/storage/redis/list.py +511 -0
  31. encore/storage/redis/pubsub.py +276 -0
  32. encore/storage/redis/set.py +570 -0
  33. encore/storage/redis/sorted_set.py +753 -0
  34. encore/storage/redis/stream.py +773 -0
  35. encore/storage/redis/string.py +654 -0
  36. encore/tracing/__init__.py +19 -0
  37. encore/tracing/_context.py +27 -0
  38. encore/tracing/_encode.py +351 -0
  39. encore/tracing/_provider.py +62 -0
  40. encore/tracing/_span.py +226 -0
  41. encore/tracing/_tracer.py +93 -0
  42. encore_dev-2.0.0a7.dist-info/METADATA +791 -0
  43. encore_dev-2.0.0a7.dist-info/RECORD +44 -0
  44. encore_dev-2.0.0a7.dist-info/WHEEL +4 -0
@@ -0,0 +1,753 @@
1
+ """Redis sorted set commands.
2
+
3
+ Keys are strings without Encore prefixes. Values accept bytes, str, int, float,
4
+ or
5
+ RedisValue implementations; value reads default to bytes. Use command[T](...) to
6
+ decode values as T. Custom encoding and decoding errors propagate to the caller.
7
+ Repeated arguments are variadic. Individual commands document their reply
8
+ shapes and any option-dependent behavior.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from collections.abc import Sequence
14
+ from typing import Optional
15
+
16
+ from ...tracing._context import active_ctx_bytes
17
+ from ._base import CommandInterface, TypedCommand
18
+ from ._values import T, Value, encode, decode, decode_sorted, U
19
+
20
+
21
+ class _ZrandmemberCommand(TypedCommand[T]):
22
+ """A callable ZRANDMEMBER command with selectable value decoding."""
23
+
24
+ def __getitem__(self, value_type: type[U]) -> _ZrandmemberCommand[U]:
25
+ """Select the value type for this command.
26
+
27
+ Use zrandmember[T](...) to decode stored values as T. Selecting a type
28
+ does not open a connection or change the decoder of an existing command.
29
+
30
+ Args:
31
+ value_type: bytes, str, int, float, or a class implementing
32
+ RedisValue.
33
+
34
+ Returns:
35
+ An independent command with the same arguments and the selected
36
+ decoder. Keys and other command metadata retain their existing
37
+ types.
38
+ """
39
+ return _ZrandmemberCommand(self._get_handle, value_type)
40
+
41
+ async def __call__(
42
+ self, key: str, *, count: int | None = None, withscores: bool = False
43
+ ) -> T | list[T] | list[tuple[T, float]] | None:
44
+ """Choose random members from a sorted set.
45
+
46
+ Args:
47
+ key: The database key, without an Encore key prefix.
48
+ count: Without count, return one random item. A positive count
49
+ selects distinct items; a negative count allows repeats and
50
+ requests abs(count) items.
51
+ withscores: Whether to include scores; requires count.
52
+
53
+ Returns:
54
+ Without count, a decoded member or None if missing. With count, a
55
+ list of members, or (member, float score) tuples when
56
+ withscores=True.
57
+
58
+ Raises:
59
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
60
+ argument is str.
61
+ ValueError: A stored value cannot be parsed as int or float.
62
+ EncoreError: Redis rejects the command or the request fails.
63
+ """
64
+ result = await self._get_handle().sorted_set_zrandmember(
65
+ key, count=count, withscores=withscores, source=active_ctx_bytes()
66
+ )
67
+ return decode_sorted(result, self._value_type)
68
+
69
+
70
+ class _ZrangeCommand(TypedCommand[T]):
71
+ """A callable ZRANGE command with selectable value decoding."""
72
+
73
+ def __getitem__(self, value_type: type[U]) -> _ZrangeCommand[U]:
74
+ """Select the value type for this command.
75
+
76
+ Use zrange[T](...) to decode stored values as T. Selecting a type does
77
+ not open a connection or change the decoder of an existing command.
78
+
79
+ Args:
80
+ value_type: bytes, str, int, float, or a class implementing
81
+ RedisValue.
82
+
83
+ Returns:
84
+ An independent command with the same arguments and the selected
85
+ decoder. Keys and other command metadata retain their existing
86
+ types.
87
+ """
88
+ return _ZrangeCommand(self._get_handle, value_type)
89
+
90
+ async def __call__(
91
+ self, key: str, start: int, stop: int, *, withscores: bool = False
92
+ ) -> list[T] | list[tuple[T, float]]:
93
+ """Return members by rank in ascending score order.
94
+
95
+ Args:
96
+ key: The database key, without an Encore key prefix.
97
+ start: The inclusive starting index; negative values count from the
98
+ end.
99
+ stop: The inclusive ending index; negative values count from the
100
+ end.
101
+ withscores: Whether to include each member's score in the result.
102
+
103
+ Returns:
104
+ Decoded members, or (member, float score) tuples when
105
+ withscores=True. Equal scores are ordered lexicographically by
106
+ member bytes.
107
+
108
+ Raises:
109
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
110
+ argument is str.
111
+ ValueError: A stored value cannot be parsed as int or float.
112
+ EncoreError: Redis rejects the command or the request fails.
113
+ """
114
+ result = await self._get_handle().sorted_set_zrange(
115
+ key, start, stop, withscores=withscores, source=active_ctx_bytes()
116
+ )
117
+ return (
118
+ [(decode(member, self._value_type), score) for member, score in result]
119
+ if withscores
120
+ else [decode(member, self._value_type) for member in result]
121
+ )
122
+
123
+
124
+ class _ZrangebyscoreCommand(TypedCommand[T]):
125
+ """A callable ZRANGEBYSCORE command with selectable value decoding."""
126
+
127
+ def __getitem__(self, value_type: type[U]) -> _ZrangebyscoreCommand[U]:
128
+ """Select the value type for this command.
129
+
130
+ Use zrangebyscore[T](...) to decode stored values as T. Selecting a type
131
+ does not open a connection or change the decoder of an existing command.
132
+
133
+ Args:
134
+ value_type: bytes, str, int, float, or a class implementing
135
+ RedisValue.
136
+
137
+ Returns:
138
+ An independent command with the same arguments and the selected
139
+ decoder. Keys and other command metadata retain their existing
140
+ types.
141
+ """
142
+ return _ZrangebyscoreCommand(self._get_handle, value_type)
143
+
144
+ async def __call__(
145
+ self,
146
+ key: str,
147
+ minimum: str,
148
+ maximum: str,
149
+ *,
150
+ withscores: bool = False,
151
+ offset: int | None = None,
152
+ count: int | None = None,
153
+ ) -> list[T] | list[tuple[T, float]]:
154
+ """Return members within a score range in ascending order.
155
+
156
+ Args:
157
+ key: The database key, without an Encore key prefix.
158
+ minimum: The lower score bound as a string; prefix with "(" to
159
+ exclude it. Use "-inf" for no lower bound.
160
+ maximum: The upper score bound as a string; prefix with "(" to
161
+ exclude it. Use "+inf" for no upper bound.
162
+ withscores: Whether to include each member's score in the result.
163
+ offset: The nonnegative number of matching members to skip; supply
164
+ together with count.
165
+ count: The nonnegative maximum number of members to return; supply
166
+ together with offset.
167
+
168
+ Returns:
169
+ Decoded members, or (member, float score) tuples when
170
+ withscores=True. Equal scores are ordered lexicographically by
171
+ member bytes.
172
+
173
+ Raises:
174
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
175
+ argument is str.
176
+ ValueError: A stored value cannot be parsed as int or float.
177
+ EncoreError: Redis rejects the command or the request fails.
178
+ """
179
+ result = await self._get_handle().sorted_set_zrangebyscore(
180
+ key,
181
+ minimum,
182
+ maximum,
183
+ withscores=withscores,
184
+ offset=offset,
185
+ count=count,
186
+ source=active_ctx_bytes(),
187
+ )
188
+ return (
189
+ [(decode(member, self._value_type), score) for member, score in result]
190
+ if withscores
191
+ else [decode(member, self._value_type) for member in result]
192
+ )
193
+
194
+
195
+ class _ZrevrangeCommand(TypedCommand[T]):
196
+ """A callable ZREVRANGE command with selectable value decoding."""
197
+
198
+ def __getitem__(self, value_type: type[U]) -> _ZrevrangeCommand[U]:
199
+ """Select the value type for this command.
200
+
201
+ Use zrevrange[T](...) to decode stored values as T. Selecting a type
202
+ does not open a connection or change the decoder of an existing command.
203
+
204
+ Args:
205
+ value_type: bytes, str, int, float, or a class implementing
206
+ RedisValue.
207
+
208
+ Returns:
209
+ An independent command with the same arguments and the selected
210
+ decoder. Keys and other command metadata retain their existing
211
+ types.
212
+ """
213
+ return _ZrevrangeCommand(self._get_handle, value_type)
214
+
215
+ async def __call__(
216
+ self, key: str, start: int, stop: int, *, withscores: bool = False
217
+ ) -> list[T] | list[tuple[T, float]]:
218
+ """Return members by rank in descending score order.
219
+
220
+ Args:
221
+ key: The database key, without an Encore key prefix.
222
+ start: The inclusive starting index; negative values count from the
223
+ end.
224
+ stop: The inclusive ending index; negative values count from the
225
+ end.
226
+ withscores: Whether to include each member's score in the result.
227
+
228
+ Returns:
229
+ Decoded members, or (member, float score) tuples when
230
+ withscores=True. Equal scores use reverse lexicographic member
231
+ order.
232
+
233
+ Raises:
234
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
235
+ argument is str.
236
+ ValueError: A stored value cannot be parsed as int or float.
237
+ EncoreError: Redis rejects the command or the request fails.
238
+ """
239
+ result = await self._get_handle().sorted_set_zrevrange(
240
+ key, start, stop, withscores=withscores, source=active_ctx_bytes()
241
+ )
242
+ return (
243
+ [(decode(member, self._value_type), score) for member, score in result]
244
+ if withscores
245
+ else [decode(member, self._value_type) for member in result]
246
+ )
247
+
248
+
249
+ class _ZscanCommand(TypedCommand[T]):
250
+ """A callable ZSCAN command with selectable value decoding."""
251
+
252
+ def __getitem__(self, value_type: type[U]) -> _ZscanCommand[U]:
253
+ """Select the value type for this command.
254
+
255
+ Use zscan[T](...) to decode stored values as T. Selecting a type does
256
+ not open a connection or change the decoder of an existing command.
257
+
258
+ Args:
259
+ value_type: bytes, str, int, float, or a class implementing
260
+ RedisValue.
261
+
262
+ Returns:
263
+ An independent command with the same arguments and the selected
264
+ decoder. Keys and other command metadata retain their existing
265
+ types.
266
+ """
267
+ return _ZscanCommand(self._get_handle, value_type)
268
+
269
+ async def __call__(
270
+ self,
271
+ key: str,
272
+ cursor: int,
273
+ *,
274
+ pattern: str | None = None,
275
+ count: int | None = None,
276
+ ) -> tuple[int, list[tuple[T, float]]]:
277
+ """Read a batch of sorted-set members using a scan cursor.
278
+
279
+ Continue with the returned cursor until it is zero. Scans may return
280
+ duplicates and do not provide a snapshot while data changes.
281
+
282
+ Args:
283
+ key: The database key, without an Encore key prefix.
284
+ cursor: Zero to start an iteration, or the cursor from the previous
285
+ call.
286
+ pattern: A Redis glob pattern to filter results, or None for no
287
+ filter.
288
+ count: A hint for work per call, not a result limit; None uses the
289
+ server default.
290
+
291
+ Returns:
292
+ A tuple (cursor, members), where cursor is the next scan cursor and
293
+ members is a list of (decoded member, float score) tuples. A zero
294
+ cursor ends the iteration; an empty batch does not. Members are not
295
+ sorted.
296
+
297
+ Raises:
298
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
299
+ argument is str.
300
+ ValueError: A stored value cannot be parsed as int or float.
301
+ EncoreError: Redis rejects the command or the request fails.
302
+ """
303
+ result = await self._get_handle().sorted_set_zscan(
304
+ key, cursor, pattern=pattern, count=count, source=active_ctx_bytes()
305
+ )
306
+ return (
307
+ result[0],
308
+ [(decode(member, self._value_type), score) for member, score in result[1]],
309
+ )
310
+
311
+
312
+ class _ZpopmaxCommand(TypedCommand[T]):
313
+ """A callable ZPOPMAX command with selectable value decoding."""
314
+
315
+ def __getitem__(self, value_type: type[U]) -> _ZpopmaxCommand[U]:
316
+ """Select the value type for this command.
317
+
318
+ Use zpopmax[T](...) to decode stored values as T. Selecting a type does
319
+ not open a connection or change the decoder of an existing command.
320
+
321
+ Args:
322
+ value_type: bytes, str, int, float, or a class implementing
323
+ RedisValue.
324
+
325
+ Returns:
326
+ An independent command with the same arguments and the selected
327
+ decoder. Keys and other command metadata retain their existing
328
+ types.
329
+ """
330
+ return _ZpopmaxCommand(self._get_handle, value_type)
331
+
332
+ async def __call__(self, key: str, *, count: int = 1) -> list[tuple[T, float]]:
333
+ """Remove the members with the highest scores.
334
+
335
+ Redis executes the command before its result is decoded. A decoding
336
+ error does not undo the command's effects.
337
+
338
+ Args:
339
+ key: The database key, without an Encore key prefix.
340
+ count: The nonnegative maximum number of members to remove; defaults
341
+ to one.
342
+
343
+ Returns:
344
+ Removed (decoded member, float score) tuples in descending score
345
+ order; empty if the key is missing.
346
+
347
+ Raises:
348
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
349
+ argument is str.
350
+ ValueError: A stored value cannot be parsed as int or float.
351
+ EncoreError: Redis rejects the command or the request fails.
352
+ """
353
+ result = await self._get_handle().sorted_set_zpopmax(
354
+ key, count=count, source=active_ctx_bytes()
355
+ )
356
+ return [(decode(member, self._value_type), score) for member, score in result]
357
+
358
+
359
+ class _ZpopminCommand(TypedCommand[T]):
360
+ """A callable ZPOPMIN command with selectable value decoding."""
361
+
362
+ def __getitem__(self, value_type: type[U]) -> _ZpopminCommand[U]:
363
+ """Select the value type for this command.
364
+
365
+ Use zpopmin[T](...) to decode stored values as T. Selecting a type does
366
+ not open a connection or change the decoder of an existing command.
367
+
368
+ Args:
369
+ value_type: bytes, str, int, float, or a class implementing
370
+ RedisValue.
371
+
372
+ Returns:
373
+ An independent command with the same arguments and the selected
374
+ decoder. Keys and other command metadata retain their existing
375
+ types.
376
+ """
377
+ return _ZpopminCommand(self._get_handle, value_type)
378
+
379
+ async def __call__(self, key: str, *, count: int = 1) -> list[tuple[T, float]]:
380
+ """Remove the members with the lowest scores.
381
+
382
+ Redis executes the command before its result is decoded. A decoding
383
+ error does not undo the command's effects.
384
+
385
+ Args:
386
+ key: The database key, without an Encore key prefix.
387
+ count: The nonnegative maximum number of members to remove; defaults
388
+ to one.
389
+
390
+ Returns:
391
+ Removed (decoded member, float score) tuples in ascending score
392
+ order; empty if the key is missing.
393
+
394
+ Raises:
395
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
396
+ argument is str.
397
+ ValueError: A stored value cannot be parsed as int or float.
398
+ EncoreError: Redis rejects the command or the request fails.
399
+ """
400
+ result = await self._get_handle().sorted_set_zpopmin(
401
+ key, count=count, source=active_ctx_bytes()
402
+ )
403
+ return [(decode(member, self._value_type), score) for member, score in result]
404
+
405
+
406
+ class ReadOnlyInterface(CommandInterface):
407
+ """Commands available through a read-only database handle."""
408
+
409
+ async def zcard(self, key: str) -> int:
410
+ """Return the number of members in a sorted set.
411
+
412
+ Args:
413
+ key: The database key, without an Encore key prefix.
414
+
415
+ Returns:
416
+ The set size, or zero if the key does not exist.
417
+
418
+ Raises:
419
+ EncoreError: Redis rejects the command or the request fails.
420
+ """
421
+ return await self._get_handle().sorted_set_zcard(key, source=active_ctx_bytes())
422
+
423
+ async def zcount(self, key: str, minimum: str, maximum: str) -> int:
424
+ """Count members within a score range.
425
+
426
+ Args:
427
+ key: The database key, without an Encore key prefix.
428
+ minimum: The lower score bound as a string; prefix with "(" to
429
+ exclude it. Use "-inf" for no lower bound.
430
+ maximum: The upper score bound as a string; prefix with "(" to
431
+ exclude it. Use "+inf" for no upper bound.
432
+
433
+ Returns:
434
+ The number of members whose scores fall within the bounds.
435
+
436
+ Raises:
437
+ EncoreError: Redis rejects the command or the request fails.
438
+ """
439
+ return await self._get_handle().sorted_set_zcount(
440
+ key, minimum, maximum, source=active_ctx_bytes()
441
+ )
442
+
443
+ @property
444
+ def zrandmember(self) -> _ZrandmemberCommand[bytes]:
445
+ """The callable ZRANDMEMBER command.
446
+
447
+ Use zrandmember[T](...) to select the decoded value type. Plain calls
448
+ keep stored values as bytes; keys and command metadata are unchanged.
449
+ """
450
+ return _ZrandmemberCommand(self._get_handle, bytes)
451
+
452
+ @property
453
+ def zrange(self) -> _ZrangeCommand[bytes]:
454
+ """The callable ZRANGE command.
455
+
456
+ Use zrange[T](...) to select the decoded value type. Plain calls keep
457
+ stored values as bytes; keys and command metadata are unchanged.
458
+ """
459
+ return _ZrangeCommand(self._get_handle, bytes)
460
+
461
+ @property
462
+ def zrangebyscore(self) -> _ZrangebyscoreCommand[bytes]:
463
+ """The callable ZRANGEBYSCORE command.
464
+
465
+ Use zrangebyscore[T](...) to select the decoded value type. Plain calls
466
+ keep stored values as bytes; keys and command metadata are unchanged.
467
+ """
468
+ return _ZrangebyscoreCommand(self._get_handle, bytes)
469
+
470
+ async def zrank(self, key: str, member: Value) -> Optional[int]:
471
+ """Return a member's rank in ascending score order.
472
+
473
+ Args:
474
+ key: The database key, without an Encore key prefix.
475
+ member: The member to encode.
476
+
477
+ Returns:
478
+ The zero-based rank, or None if the key or member is missing.
479
+
480
+ Raises:
481
+ EncoreError: Redis rejects the command or the request fails.
482
+ """
483
+ return await self._get_handle().sorted_set_zrank(
484
+ key, encode(member), source=active_ctx_bytes()
485
+ )
486
+
487
+ @property
488
+ def zrevrange(self) -> _ZrevrangeCommand[bytes]:
489
+ """The callable ZREVRANGE command.
490
+
491
+ Use zrevrange[T](...) to select the decoded value type. Plain calls keep
492
+ stored values as bytes; keys and command metadata are unchanged.
493
+ """
494
+ return _ZrevrangeCommand(self._get_handle, bytes)
495
+
496
+ async def zrevrank(self, key: str, member: Value) -> Optional[int]:
497
+ """Return a member's rank in descending score order.
498
+
499
+ Args:
500
+ key: The database key, without an Encore key prefix.
501
+ member: The member to encode.
502
+
503
+ Returns:
504
+ The zero-based rank, or None if the key or member is missing.
505
+
506
+ Raises:
507
+ EncoreError: Redis rejects the command or the request fails.
508
+ """
509
+ return await self._get_handle().sorted_set_zrevrank(
510
+ key, encode(member), source=active_ctx_bytes()
511
+ )
512
+
513
+ @property
514
+ def zscan(self) -> _ZscanCommand[bytes]:
515
+ """The callable ZSCAN command.
516
+
517
+ Use zscan[T](...) to select the decoded value type. Plain calls keep
518
+ stored values as bytes; keys and command metadata are unchanged.
519
+ """
520
+ return _ZscanCommand(self._get_handle, bytes)
521
+
522
+ async def zscore(self, key: str, member: Value) -> Optional[float]:
523
+ """Return a sorted-set member's score.
524
+
525
+ Args:
526
+ key: The database key, without an Encore key prefix.
527
+ member: The member to encode.
528
+
529
+ Returns:
530
+ The score as a float, or None if the key or member is missing.
531
+
532
+ Raises:
533
+ EncoreError: Redis rejects the command or the request fails.
534
+ """
535
+ return await self._get_handle().sorted_set_zscore(
536
+ key, encode(member), source=active_ctx_bytes()
537
+ )
538
+
539
+
540
+ class Interface(ReadOnlyInterface):
541
+ """Read and write commands."""
542
+
543
+ async def zadd(
544
+ self,
545
+ key: str,
546
+ item: tuple[float, Value],
547
+ *items: tuple[float, Value],
548
+ nx: bool = False,
549
+ xx: bool = False,
550
+ gt: bool = False,
551
+ lt: bool = False,
552
+ ch: bool = False,
553
+ ) -> int:
554
+ """Add members or update their scores in a sorted set.
555
+
556
+ Args:
557
+ key: The database key, without an Encore key prefix.
558
+ item: The first (score, member) pair.
559
+ *items: Additional tuples of the same shape, in order.
560
+ nx: Only add new entries; mutually exclusive with xx.
561
+ xx: Only update existing entries; mutually exclusive with nx.
562
+ gt: Only update existing scores when the new score is greater;
563
+ incompatible with lt and nx. New members are still added unless
564
+ xx=True.
565
+ lt: Only update existing scores when the new score is smaller;
566
+ incompatible with gt and nx. New members are still added unless
567
+ xx=True.
568
+ ch: Whether to count changed existing members as well as new
569
+ members.
570
+
571
+ Returns:
572
+ The number of new members, or the number of added and changed
573
+ members when ch=True.
574
+
575
+ Raises:
576
+ EncoreError: Redis rejects the command or the request fails.
577
+ """
578
+ items = (item, *items)
579
+ return await self._get_handle().sorted_set_zadd(
580
+ key,
581
+ [(score, encode(member)) for score, member in items],
582
+ nx=nx,
583
+ xx=xx,
584
+ gt=gt,
585
+ lt=lt,
586
+ ch=ch,
587
+ source=active_ctx_bytes(),
588
+ )
589
+
590
+ async def zincrby(self, key: str, amount: float, member: Value) -> float:
591
+ """Increment a member's score, starting from zero if missing.
592
+
593
+ Args:
594
+ key: The database key, without an Encore key prefix.
595
+ amount: The amount to add; negative values subtract.
596
+ member: The member to encode.
597
+
598
+ Returns:
599
+ The resulting score as a float.
600
+
601
+ Raises:
602
+ EncoreError: Redis rejects the command or the request fails.
603
+ """
604
+ return await self._get_handle().sorted_set_zincrby(
605
+ key, amount, encode(member), source=active_ctx_bytes()
606
+ )
607
+
608
+ async def zinterstore(
609
+ self,
610
+ destination: str,
611
+ key: str,
612
+ *keys: str,
613
+ weights: Sequence[float] | None = None,
614
+ aggregate: str | None = None,
615
+ ) -> int:
616
+ """Store the weighted intersection of sorted sets.
617
+
618
+ Args:
619
+ destination: The destination key, without an Encore key prefix.
620
+ key: The first database key, without an Encore prefix.
621
+ *keys: Additional database keys, without Encore prefixes.
622
+ weights: One score multiplier per source key, or None to use one for
623
+ each.
624
+ aggregate: The case-insensitive score aggregation: SUM, MIN, or MAX.
625
+ Defaults to SUM.
626
+
627
+ Returns:
628
+ The number of members stored, replacing the destination's previous
629
+ value.
630
+
631
+ Raises:
632
+ EncoreError: Redis rejects the command or the request fails.
633
+ """
634
+ keys = (key, *keys)
635
+ return await self._get_handle().sorted_set_zinterstore(
636
+ destination,
637
+ keys,
638
+ weights=weights,
639
+ aggregate=aggregate,
640
+ source=active_ctx_bytes(),
641
+ )
642
+
643
+ @property
644
+ def zpopmax(self) -> _ZpopmaxCommand[bytes]:
645
+ """The callable ZPOPMAX command.
646
+
647
+ Use zpopmax[T](...) to select the decoded value type. Plain calls keep
648
+ stored values as bytes; keys and command metadata are unchanged.
649
+ """
650
+ return _ZpopmaxCommand(self._get_handle, bytes)
651
+
652
+ @property
653
+ def zpopmin(self) -> _ZpopminCommand[bytes]:
654
+ """The callable ZPOPMIN command.
655
+
656
+ Use zpopmin[T](...) to select the decoded value type. Plain calls keep
657
+ stored values as bytes; keys and command metadata are unchanged.
658
+ """
659
+ return _ZpopminCommand(self._get_handle, bytes)
660
+
661
+ async def zrem(self, key: str, member: Value, *members: Value) -> int:
662
+ """Remove members from a sorted set.
663
+
664
+ Args:
665
+ key: The database key, without an Encore key prefix.
666
+ member: The first member to encode.
667
+ *members: Additional members to encode, in order.
668
+
669
+ Returns:
670
+ The number of members removed; absent members are ignored.
671
+
672
+ Raises:
673
+ EncoreError: Redis rejects the command or the request fails.
674
+ """
675
+ members = (member, *members)
676
+ return await self._get_handle().sorted_set_zrem(
677
+ key, [encode(value) for value in members], source=active_ctx_bytes()
678
+ )
679
+
680
+ async def zremrangebyrank(self, key: str, start: int, stop: int) -> int:
681
+ """Remove members within an inclusive rank range.
682
+
683
+ Args:
684
+ key: The database key, without an Encore key prefix.
685
+ start: The inclusive starting index; negative values count from the
686
+ end.
687
+ stop: The inclusive ending index; negative values count from the
688
+ end.
689
+
690
+ Returns:
691
+ The number of members removed.
692
+
693
+ Raises:
694
+ EncoreError: Redis rejects the command or the request fails.
695
+ """
696
+ return await self._get_handle().sorted_set_zremrangebyrank(
697
+ key, start, stop, source=active_ctx_bytes()
698
+ )
699
+
700
+ async def zremrangebyscore(self, key: str, minimum: str, maximum: str) -> int:
701
+ """Remove members within a score range.
702
+
703
+ Args:
704
+ key: The database key, without an Encore key prefix.
705
+ minimum: The lower score bound as a string; prefix with "(" to
706
+ exclude it. Use "-inf" for no lower bound.
707
+ maximum: The upper score bound as a string; prefix with "(" to
708
+ exclude it. Use "+inf" for no upper bound.
709
+
710
+ Returns:
711
+ The number of members removed.
712
+
713
+ Raises:
714
+ EncoreError: Redis rejects the command or the request fails.
715
+ """
716
+ return await self._get_handle().sorted_set_zremrangebyscore(
717
+ key, minimum, maximum, source=active_ctx_bytes()
718
+ )
719
+
720
+ async def zunionstore(
721
+ self,
722
+ destination: str,
723
+ key: str,
724
+ *keys: str,
725
+ weights: Sequence[float] | None = None,
726
+ aggregate: str | None = None,
727
+ ) -> int:
728
+ """Store the weighted union of sorted sets.
729
+
730
+ Args:
731
+ destination: The destination key, without an Encore key prefix.
732
+ key: The first database key, without an Encore prefix.
733
+ *keys: Additional database keys, without Encore prefixes.
734
+ weights: One score multiplier per source key, or None to use one for
735
+ each.
736
+ aggregate: The case-insensitive score aggregation: SUM, MIN, or MAX.
737
+ Defaults to SUM.
738
+
739
+ Returns:
740
+ The number of members stored, replacing the destination's previous
741
+ value.
742
+
743
+ Raises:
744
+ EncoreError: Redis rejects the command or the request fails.
745
+ """
746
+ keys = (key, *keys)
747
+ return await self._get_handle().sorted_set_zunionstore(
748
+ destination,
749
+ keys,
750
+ weights=weights,
751
+ aggregate=aggregate,
752
+ source=active_ctx_bytes(),
753
+ )