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,570 @@
1
+ """Redis 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 ...tracing._context import active_ctx_bytes
14
+ from ._base import CommandInterface, TypedCommand
15
+ from ._values import T, Value, encode, decode, decode_pop, U
16
+
17
+
18
+ class _SdiffCommand(TypedCommand[T]):
19
+ """A callable SDIFF command with selectable value decoding."""
20
+
21
+ def __getitem__(self, value_type: type[U]) -> _SdiffCommand[U]:
22
+ """Select the value type for this command.
23
+
24
+ Use sdiff[T](...) to decode stored values as T. Selecting a type does
25
+ not open a connection or change the decoder of an existing command.
26
+
27
+ Args:
28
+ value_type: bytes, str, int, float, or a class implementing
29
+ RedisValue.
30
+
31
+ Returns:
32
+ An independent command with the same arguments and the selected
33
+ decoder. Keys and other command metadata retain their existing
34
+ types.
35
+ """
36
+ return _SdiffCommand(self._get_handle, value_type)
37
+
38
+ async def __call__(self, key: str, *keys: str) -> list[T]:
39
+ """Return members of the first set absent from all subsequent sets.
40
+
41
+ Args:
42
+ key: The first database key, without an Encore prefix.
43
+ *keys: Additional database keys, without Encore prefixes.
44
+
45
+ Returns:
46
+ The differing decoded members, in unspecified order.
47
+
48
+ Raises:
49
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
50
+ argument is str.
51
+ ValueError: A stored value cannot be parsed as int or float.
52
+ EncoreError: Redis rejects the command or the request fails.
53
+ """
54
+ keys = (key, *keys)
55
+ result = await self._get_handle().set_sdiff(keys, source=active_ctx_bytes())
56
+ return [decode(value, self._value_type) for value in result]
57
+
58
+
59
+ class _SinterCommand(TypedCommand[T]):
60
+ """A callable SINTER command with selectable value decoding."""
61
+
62
+ def __getitem__(self, value_type: type[U]) -> _SinterCommand[U]:
63
+ """Select the value type for this command.
64
+
65
+ Use sinter[T](...) to decode stored values as T. Selecting a type does
66
+ not open a connection or change the decoder of an existing command.
67
+
68
+ Args:
69
+ value_type: bytes, str, int, float, or a class implementing
70
+ RedisValue.
71
+
72
+ Returns:
73
+ An independent command with the same arguments and the selected
74
+ decoder. Keys and other command metadata retain their existing
75
+ types.
76
+ """
77
+ return _SinterCommand(self._get_handle, value_type)
78
+
79
+ async def __call__(self, key: str, *keys: str) -> list[T]:
80
+ """Return members present in every supplied set.
81
+
82
+ Args:
83
+ key: The first database key, without an Encore prefix.
84
+ *keys: Additional database keys, without Encore prefixes.
85
+
86
+ Returns:
87
+ The common decoded members, in unspecified order.
88
+
89
+ Raises:
90
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
91
+ argument is str.
92
+ ValueError: A stored value cannot be parsed as int or float.
93
+ EncoreError: Redis rejects the command or the request fails.
94
+ """
95
+ keys = (key, *keys)
96
+ result = await self._get_handle().set_sinter(keys, source=active_ctx_bytes())
97
+ return [decode(value, self._value_type) for value in result]
98
+
99
+
100
+ class _SmembersCommand(TypedCommand[T]):
101
+ """A callable SMEMBERS command with selectable value decoding."""
102
+
103
+ def __getitem__(self, value_type: type[U]) -> _SmembersCommand[U]:
104
+ """Select the value type for this command.
105
+
106
+ Use smembers[T](...) to decode stored values as T. Selecting a type does
107
+ not open a connection or change the decoder of an existing command.
108
+
109
+ Args:
110
+ value_type: bytes, str, int, float, or a class implementing
111
+ RedisValue.
112
+
113
+ Returns:
114
+ An independent command with the same arguments and the selected
115
+ decoder. Keys and other command metadata retain their existing
116
+ types.
117
+ """
118
+ return _SmembersCommand(self._get_handle, value_type)
119
+
120
+ async def __call__(self, key: str) -> list[T]:
121
+ """Return all members of a set.
122
+
123
+ Args:
124
+ key: The database key, without an Encore key prefix.
125
+
126
+ Returns:
127
+ Decoded members, in unspecified order; empty if the key is missing.
128
+
129
+ Raises:
130
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
131
+ argument is str.
132
+ ValueError: A stored value cannot be parsed as int or float.
133
+ EncoreError: Redis rejects the command or the request fails.
134
+ """
135
+ result = await self._get_handle().set_smembers(key, source=active_ctx_bytes())
136
+ return [decode(value, self._value_type) for value in result]
137
+
138
+
139
+ class _SrandmemberCommand(TypedCommand[T]):
140
+ """A callable SRANDMEMBER command with selectable value decoding."""
141
+
142
+ def __getitem__(self, value_type: type[U]) -> _SrandmemberCommand[U]:
143
+ """Select the value type for this command.
144
+
145
+ Use srandmember[T](...) to decode stored values as T. Selecting a type
146
+ does not open a connection or change the decoder of an existing command.
147
+
148
+ Args:
149
+ value_type: bytes, str, int, float, or a class implementing
150
+ RedisValue.
151
+
152
+ Returns:
153
+ An independent command with the same arguments and the selected
154
+ decoder. Keys and other command metadata retain their existing
155
+ types.
156
+ """
157
+ return _SrandmemberCommand(self._get_handle, value_type)
158
+
159
+ async def __call__(
160
+ self, key: str, *, count: int | None = None
161
+ ) -> T | list[T] | None:
162
+ """Choose random members without removing them.
163
+
164
+ Args:
165
+ key: The database key, without an Encore key prefix.
166
+ count: Without count, return one random item. A positive count
167
+ selects distinct items; a negative count allows repeats and
168
+ requests abs(count) items.
169
+
170
+ Returns:
171
+ Without count, a decoded member or None if the set is missing. With
172
+ count, a list, empty if the set is missing.
173
+
174
+ Raises:
175
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
176
+ argument is str.
177
+ ValueError: A stored value cannot be parsed as int or float.
178
+ EncoreError: Redis rejects the command or the request fails.
179
+ """
180
+ result = await self._get_handle().set_srandmember(
181
+ key, count=count, source=active_ctx_bytes()
182
+ )
183
+ return decode_pop(result, self._value_type)
184
+
185
+
186
+ class _SscanCommand(TypedCommand[T]):
187
+ """A callable SSCAN command with selectable value decoding."""
188
+
189
+ def __getitem__(self, value_type: type[U]) -> _SscanCommand[U]:
190
+ """Select the value type for this command.
191
+
192
+ Use sscan[T](...) to decode stored values as T. Selecting a type does
193
+ not open a connection or change the decoder of an existing command.
194
+
195
+ Args:
196
+ value_type: bytes, str, int, float, or a class implementing
197
+ RedisValue.
198
+
199
+ Returns:
200
+ An independent command with the same arguments and the selected
201
+ decoder. Keys and other command metadata retain their existing
202
+ types.
203
+ """
204
+ return _SscanCommand(self._get_handle, value_type)
205
+
206
+ async def __call__(
207
+ self,
208
+ key: str,
209
+ cursor: int,
210
+ *,
211
+ pattern: str | None = None,
212
+ count: int | None = None,
213
+ ) -> tuple[int, list[T]]:
214
+ """Read a batch of set members using a scan cursor.
215
+
216
+ Continue with the returned cursor until it is zero. Scans may return
217
+ duplicates and do not provide a snapshot while data changes.
218
+
219
+ Args:
220
+ key: The database key, without an Encore key prefix.
221
+ cursor: Zero to start an iteration, or the cursor from the previous
222
+ call.
223
+ pattern: A Redis glob pattern to filter results, or None for no
224
+ filter.
225
+ count: A hint for work per call, not a result limit; None uses the
226
+ server default.
227
+
228
+ Returns:
229
+ A tuple (cursor, members), where cursor is the next scan cursor and
230
+ members is a list of decoded members. A zero cursor ends the
231
+ iteration; an empty batch does not.
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().set_sscan(
240
+ key, cursor, pattern=pattern, count=count, source=active_ctx_bytes()
241
+ )
242
+ return (result[0], [decode(value, self._value_type) for value in result[1]])
243
+
244
+
245
+ class _SunionCommand(TypedCommand[T]):
246
+ """A callable SUNION command with selectable value decoding."""
247
+
248
+ def __getitem__(self, value_type: type[U]) -> _SunionCommand[U]:
249
+ """Select the value type for this command.
250
+
251
+ Use sunion[T](...) to decode stored values as T. Selecting a type does
252
+ not open a connection or change the decoder of an existing command.
253
+
254
+ Args:
255
+ value_type: bytes, str, int, float, or a class implementing
256
+ RedisValue.
257
+
258
+ Returns:
259
+ An independent command with the same arguments and the selected
260
+ decoder. Keys and other command metadata retain their existing
261
+ types.
262
+ """
263
+ return _SunionCommand(self._get_handle, value_type)
264
+
265
+ async def __call__(self, key: str, *keys: str) -> list[T]:
266
+ """Return members present in any supplied set.
267
+
268
+ Args:
269
+ key: The first database key, without an Encore prefix.
270
+ *keys: Additional database keys, without Encore prefixes.
271
+
272
+ Returns:
273
+ The combined decoded members, in unspecified order.
274
+
275
+ Raises:
276
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
277
+ argument is str.
278
+ ValueError: A stored value cannot be parsed as int or float.
279
+ EncoreError: Redis rejects the command or the request fails.
280
+ """
281
+ keys = (key, *keys)
282
+ result = await self._get_handle().set_sunion(keys, source=active_ctx_bytes())
283
+ return [decode(value, self._value_type) for value in result]
284
+
285
+
286
+ class _SpopCommand(TypedCommand[T]):
287
+ """A callable SPOP command with selectable value decoding."""
288
+
289
+ def __getitem__(self, value_type: type[U]) -> _SpopCommand[U]:
290
+ """Select the value type for this command.
291
+
292
+ Use spop[T](...) to decode stored values as T. Selecting a type does not
293
+ open a connection or change the decoder of an existing command.
294
+
295
+ Args:
296
+ value_type: bytes, str, int, float, or a class implementing
297
+ RedisValue.
298
+
299
+ Returns:
300
+ An independent command with the same arguments and the selected
301
+ decoder. Keys and other command metadata retain their existing
302
+ types.
303
+ """
304
+ return _SpopCommand(self._get_handle, value_type)
305
+
306
+ async def __call__(
307
+ self, key: str, *, count: int | None = None
308
+ ) -> T | list[T] | None:
309
+ """Remove randomly chosen members from a set.
310
+
311
+ Redis executes the command before its result is decoded. A decoding
312
+ error does not undo the command's effects.
313
+
314
+ Args:
315
+ key: The database key, without an Encore key prefix.
316
+ count: The nonnegative maximum number of distinct members to remove.
317
+ None removes one member and returns it instead of a list.
318
+
319
+ Returns:
320
+ Without count, a decoded member or None if the set is missing. With
321
+ count, a list of up to count distinct members, empty if missing.
322
+
323
+ Raises:
324
+ UnicodeDecodeError: A value is not valid UTF-8 when the type
325
+ argument is str.
326
+ ValueError: A stored value cannot be parsed as int or float.
327
+ EncoreError: Redis rejects the command or the request fails.
328
+ """
329
+ result = await self._get_handle().set_spop(
330
+ key, count=count, source=active_ctx_bytes()
331
+ )
332
+ return decode_pop(result, self._value_type)
333
+
334
+
335
+ class ReadOnlyInterface(CommandInterface):
336
+ """Commands available through a read-only database handle."""
337
+
338
+ async def scard(self, key: str) -> int:
339
+ """Return the number of members in a set.
340
+
341
+ Args:
342
+ key: The database key, without an Encore key prefix.
343
+
344
+ Returns:
345
+ The set size, or zero if the key does not exist.
346
+
347
+ Raises:
348
+ EncoreError: Redis rejects the command or the request fails.
349
+ """
350
+ return await self._get_handle().set_scard(key, source=active_ctx_bytes())
351
+
352
+ @property
353
+ def sdiff(self) -> _SdiffCommand[bytes]:
354
+ """The callable SDIFF command.
355
+
356
+ Use sdiff[T](...) to select the decoded value type. Plain calls keep
357
+ stored values as bytes; keys and command metadata are unchanged.
358
+ """
359
+ return _SdiffCommand(self._get_handle, bytes)
360
+
361
+ @property
362
+ def sinter(self) -> _SinterCommand[bytes]:
363
+ """The callable SINTER command.
364
+
365
+ Use sinter[T](...) to select the decoded value type. Plain calls keep
366
+ stored values as bytes; keys and command metadata are unchanged.
367
+ """
368
+ return _SinterCommand(self._get_handle, bytes)
369
+
370
+ async def sismember(self, key: str, member: Value) -> bool:
371
+ """Check whether a set contains a member.
372
+
373
+ Args:
374
+ key: The database key, without an Encore key prefix.
375
+ member: The member to encode.
376
+
377
+ Returns:
378
+ True if the member exists, otherwise False.
379
+
380
+ Raises:
381
+ EncoreError: Redis rejects the command or the request fails.
382
+ """
383
+ return await self._get_handle().set_sismember(
384
+ key, encode(member), source=active_ctx_bytes()
385
+ )
386
+
387
+ @property
388
+ def smembers(self) -> _SmembersCommand[bytes]:
389
+ """The callable SMEMBERS command.
390
+
391
+ Use smembers[T](...) to select the decoded value type. Plain calls keep
392
+ stored values as bytes; keys and command metadata are unchanged.
393
+ """
394
+ return _SmembersCommand(self._get_handle, bytes)
395
+
396
+ async def smismember(self, key: str, member: Value, *members: Value) -> list[bool]:
397
+ """Check membership for several values in input order.
398
+
399
+ Args:
400
+ key: The database key, without an Encore key prefix.
401
+ member: The first member to encode.
402
+ *members: Additional members to encode, in order.
403
+
404
+ Returns:
405
+ One boolean per supplied member.
406
+
407
+ Raises:
408
+ EncoreError: Redis rejects the command or the request fails.
409
+ """
410
+ members = (member, *members)
411
+ return await self._get_handle().set_smismember(
412
+ key, [encode(value) for value in members], source=active_ctx_bytes()
413
+ )
414
+
415
+ @property
416
+ def srandmember(self) -> _SrandmemberCommand[bytes]:
417
+ """The callable SRANDMEMBER command.
418
+
419
+ Use srandmember[T](...) to select the decoded value type. Plain calls
420
+ keep stored values as bytes; keys and command metadata are unchanged.
421
+ """
422
+ return _SrandmemberCommand(self._get_handle, bytes)
423
+
424
+ @property
425
+ def sscan(self) -> _SscanCommand[bytes]:
426
+ """The callable SSCAN command.
427
+
428
+ Use sscan[T](...) to select the decoded value type. Plain calls keep
429
+ stored values as bytes; keys and command metadata are unchanged.
430
+ """
431
+ return _SscanCommand(self._get_handle, bytes)
432
+
433
+ @property
434
+ def sunion(self) -> _SunionCommand[bytes]:
435
+ """The callable SUNION command.
436
+
437
+ Use sunion[T](...) to select the decoded value type. Plain calls keep
438
+ stored values as bytes; keys and command metadata are unchanged.
439
+ """
440
+ return _SunionCommand(self._get_handle, bytes)
441
+
442
+
443
+ class Interface(ReadOnlyInterface):
444
+ """Read and write commands."""
445
+
446
+ async def sadd(self, key: str, member: Value, *members: Value) -> int:
447
+ """Add members to a set, creating it if needed.
448
+
449
+ Args:
450
+ key: The database key, without an Encore key prefix.
451
+ member: The first member to encode.
452
+ *members: Additional members to encode, in order.
453
+
454
+ Returns:
455
+ The number of newly added members, excluding existing members.
456
+
457
+ Raises:
458
+ EncoreError: Redis rejects the command or the request fails.
459
+ """
460
+ members = (member, *members)
461
+ return await self._get_handle().set_sadd(
462
+ key, [encode(value) for value in members], source=active_ctx_bytes()
463
+ )
464
+
465
+ async def sdiffstore(self, destination: str, key: str, *keys: str) -> int:
466
+ """Store the difference between the first set and subsequent sets.
467
+
468
+ Args:
469
+ destination: The destination key, without an Encore key prefix.
470
+ key: The first database key, without an Encore prefix.
471
+ *keys: Additional database keys, without Encore prefixes.
472
+
473
+ Returns:
474
+ The number of members stored, replacing the destination's previous
475
+ value.
476
+
477
+ Raises:
478
+ EncoreError: Redis rejects the command or the request fails.
479
+ """
480
+ keys = (key, *keys)
481
+ return await self._get_handle().set_sdiffstore(
482
+ destination, keys, source=active_ctx_bytes()
483
+ )
484
+
485
+ async def sinterstore(self, destination: str, key: str, *keys: str) -> int:
486
+ """Store the intersection of the supplied sets.
487
+
488
+ Args:
489
+ destination: The destination key, without an Encore key prefix.
490
+ key: The first database key, without an Encore prefix.
491
+ *keys: Additional database keys, without Encore prefixes.
492
+
493
+ Returns:
494
+ The number of members stored, replacing the destination's previous
495
+ value.
496
+
497
+ Raises:
498
+ EncoreError: Redis rejects the command or the request fails.
499
+ """
500
+ keys = (key, *keys)
501
+ return await self._get_handle().set_sinterstore(
502
+ destination, keys, source=active_ctx_bytes()
503
+ )
504
+
505
+ async def smove(self, key: str, destination: str, member: Value) -> bool:
506
+ """Move a member from one set to another atomically.
507
+
508
+ Args:
509
+ key: The database key, without an Encore key prefix.
510
+ destination: The destination key, without an Encore key prefix.
511
+ member: The member to encode.
512
+
513
+ Returns:
514
+ True if the member was removed from the source and added to the
515
+ destination; False if it was absent from the source.
516
+
517
+ Raises:
518
+ EncoreError: Redis rejects the command or the request fails.
519
+ """
520
+ return await self._get_handle().set_smove(
521
+ key, destination, encode(member), source=active_ctx_bytes()
522
+ )
523
+
524
+ @property
525
+ def spop(self) -> _SpopCommand[bytes]:
526
+ """The callable SPOP command.
527
+
528
+ Use spop[T](...) to select the decoded value type. Plain calls keep
529
+ stored values as bytes; keys and command metadata are unchanged.
530
+ """
531
+ return _SpopCommand(self._get_handle, bytes)
532
+
533
+ async def srem(self, key: str, member: Value, *members: Value) -> int:
534
+ """Remove members from a set.
535
+
536
+ Args:
537
+ key: The database key, without an Encore key prefix.
538
+ member: The first member to encode.
539
+ *members: Additional members to encode, in order.
540
+
541
+ Returns:
542
+ The number of members removed; absent members are ignored.
543
+
544
+ Raises:
545
+ EncoreError: Redis rejects the command or the request fails.
546
+ """
547
+ members = (member, *members)
548
+ return await self._get_handle().set_srem(
549
+ key, [encode(value) for value in members], source=active_ctx_bytes()
550
+ )
551
+
552
+ async def sunionstore(self, destination: str, key: str, *keys: str) -> int:
553
+ """Store the union of the supplied sets.
554
+
555
+ Args:
556
+ destination: The destination key, without an Encore key prefix.
557
+ key: The first database key, without an Encore prefix.
558
+ *keys: Additional database keys, without Encore prefixes.
559
+
560
+ Returns:
561
+ The number of members stored, replacing the destination's previous
562
+ value.
563
+
564
+ Raises:
565
+ EncoreError: Redis rejects the command or the request fails.
566
+ """
567
+ keys = (key, *keys)
568
+ return await self._get_handle().set_sunionstore(
569
+ destination, keys, source=active_ctx_bytes()
570
+ )