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,142 @@
1
+ """Redis commands for bits stored in binary strings.
2
+
3
+ Keys are strings without Encore prefixes. Bit offsets are zero-based. Range
4
+ commands describe whether their offsets address bytes or individual bits; these
5
+ commands do not decode stored values.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from ...tracing._context import active_ctx_bytes
11
+ from ._base import CommandInterface
12
+
13
+
14
+ class ReadOnlyInterface(CommandInterface):
15
+ """Commands available through a read-only database handle."""
16
+
17
+ async def bitcount(
18
+ self,
19
+ key: str,
20
+ *,
21
+ start: int | None = None,
22
+ end: int | None = None,
23
+ unit: str | None = None,
24
+ ) -> int:
25
+ """Count set bits in a string or an inclusive range.
26
+
27
+ Args:
28
+ key: The database key, without an Encore key prefix.
29
+ start: The inclusive start in the selected unit; negative offsets
30
+ count from the end.
31
+ end: The inclusive end in the selected unit; negative offsets count
32
+ from the end. Supply start and end together.
33
+ unit: BYTE (default) or BIT, case-insensitively. Requires start and
34
+ end.
35
+
36
+ Returns:
37
+ The number of bits equal to one; zero for a missing key.
38
+
39
+ Raises:
40
+ EncoreError: Redis rejects the command or the request fails.
41
+ """
42
+ return await self._get_handle().bitmap_bitcount(
43
+ key, start=start, end=end, unit=unit, source=active_ctx_bytes()
44
+ )
45
+
46
+ async def bitpos(
47
+ self,
48
+ key: str,
49
+ bit: bool,
50
+ *,
51
+ start: int | None = None,
52
+ end: int | None = None,
53
+ unit: str | None = None,
54
+ ) -> int:
55
+ """Find the first occurrence of a bit in a string.
56
+
57
+ Args:
58
+ key: The database key, without an Encore key prefix.
59
+ bit: The bit to find: False for zero or True for one.
60
+ start: The inclusive start in the selected unit; negative offsets
61
+ count from the end.
62
+ end: The inclusive end in the selected unit; negative offsets count
63
+ from the end. Requires start.
64
+ unit: BYTE (default) or BIT, case-insensitively. Requires start and
65
+ end.
66
+
67
+ Returns:
68
+ The absolute bit offset, or -1 if no matching bit is found. When
69
+ searching for zero without an explicit end, Redis treats the string
70
+ as padded with zero bits.
71
+
72
+ Raises:
73
+ EncoreError: Redis rejects the command or the request fails.
74
+ """
75
+ return await self._get_handle().bitmap_bitpos(
76
+ key, bit, start=start, end=end, unit=unit, source=active_ctx_bytes()
77
+ )
78
+
79
+ async def getbit(self, key: str, offset: int) -> int:
80
+ """Read a bit at an offset in a string.
81
+
82
+ Args:
83
+ key: The database key, without an Encore key prefix.
84
+ offset: The nonnegative bit offset, with zero denoting the most
85
+ significant bit of the first byte.
86
+
87
+ Returns:
88
+ Zero or one; missing keys and offsets beyond the string read as
89
+ zero.
90
+
91
+ Raises:
92
+ EncoreError: Redis rejects the command or the request fails.
93
+ """
94
+ return await self._get_handle().bitmap_getbit(
95
+ key, offset, source=active_ctx_bytes()
96
+ )
97
+
98
+
99
+ class Interface(ReadOnlyInterface):
100
+ """Read and write commands."""
101
+
102
+ async def bitop(
103
+ self, operation: str, destination: str, key: str, *keys: str
104
+ ) -> int:
105
+ """Store the result of a bitwise operation on source strings.
106
+
107
+ Args:
108
+ operation: The case-insensitive operation: AND, OR, XOR, or NOT. NOT
109
+ requires exactly one source key.
110
+ destination: The destination key, without an Encore key prefix.
111
+ key: The first database key, without an Encore prefix.
112
+ *keys: Additional database keys, without Encore prefixes.
113
+
114
+ Returns:
115
+ The byte length of the stored result.
116
+
117
+ Raises:
118
+ EncoreError: Redis rejects the command or the request fails.
119
+ """
120
+ keys = (key, *keys)
121
+ return await self._get_handle().bitmap_bitop(
122
+ operation, destination, keys, source=active_ctx_bytes()
123
+ )
124
+
125
+ async def setbit(self, key: str, offset: int, value: bool) -> int:
126
+ """Set a bit, extending the string with zero bytes if needed.
127
+
128
+ Args:
129
+ key: The database key, without an Encore key prefix.
130
+ offset: The nonnegative bit offset, with zero denoting the most
131
+ significant bit of the first byte.
132
+ value: The new bit: False for zero or True for one.
133
+
134
+ Returns:
135
+ The previous bit value, either zero or one.
136
+
137
+ Raises:
138
+ EncoreError: Redis rejects the command or the request fails.
139
+ """
140
+ return await self._get_handle().bitmap_setbit(
141
+ key, offset, value, source=active_ctx_bytes()
142
+ )
@@ -0,0 +1,367 @@
1
+ """Redis commands for keys, expiration, and database scans.
2
+
3
+ Key arguments are strings without Encore prefixes. SCAN returns unprefixed key
4
+ names as bytes. These commands do not decode stored values.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from ...tracing._context import active_ctx_bytes
10
+ from ._base import CommandInterface
11
+
12
+
13
+ class ReadOnlyInterface(CommandInterface):
14
+ """Commands available through a read-only database handle."""
15
+
16
+ async def exists(self, key: str, *keys: str) -> int:
17
+ """Count the supplied keys that exist.
18
+
19
+ Args:
20
+ key: The first database key, without an Encore prefix.
21
+ *keys: Additional database keys, without Encore prefixes.
22
+
23
+ Returns:
24
+ The number of existing keys, counting repeated keys separately.
25
+
26
+ Raises:
27
+ EncoreError: Redis rejects the command or the request fails.
28
+ """
29
+ keys = (key, *keys)
30
+ return await self._get_handle().generic_exists(keys, source=active_ctx_bytes())
31
+
32
+ async def expiretime(self, key: str) -> int:
33
+ """Return a key's expiration time in Unix seconds.
34
+
35
+ Args:
36
+ key: The database key, without an Encore key prefix.
37
+
38
+ Returns:
39
+ The timestamp, -1 if the key has no expiry, or -2 if it is missing.
40
+
41
+ Raises:
42
+ EncoreError: Redis rejects the command or the request fails.
43
+ """
44
+ return await self._get_handle().generic_expiretime(
45
+ key, source=active_ctx_bytes()
46
+ )
47
+
48
+ async def pexpiretime(self, key: str) -> int:
49
+ """Return a key's expiration time in Unix milliseconds.
50
+
51
+ Args:
52
+ key: The database key, without an Encore key prefix.
53
+
54
+ Returns:
55
+ The timestamp, -1 if the key has no expiry, or -2 if it is missing.
56
+
57
+ Raises:
58
+ EncoreError: Redis rejects the command or the request fails.
59
+ """
60
+ return await self._get_handle().generic_pexpiretime(
61
+ key, source=active_ctx_bytes()
62
+ )
63
+
64
+ async def pttl(self, key: str) -> int:
65
+ """Return the remaining lifetime of a key in milliseconds.
66
+
67
+ Args:
68
+ key: The database key, without an Encore key prefix.
69
+
70
+ Returns:
71
+ The remaining milliseconds, -1 for no expiry, or -2 for a missing
72
+ key.
73
+
74
+ Raises:
75
+ EncoreError: Redis rejects the command or the request fails.
76
+ """
77
+ return await self._get_handle().generic_pttl(key, source=active_ctx_bytes())
78
+
79
+ async def scan(
80
+ self,
81
+ cursor: int,
82
+ *,
83
+ pattern: str | None = None,
84
+ count: int | None = None,
85
+ key_type: str | None = None,
86
+ ) -> tuple[int, list[bytes]]:
87
+ """Read a batch of keys using a scan cursor.
88
+
89
+ Continue with the returned cursor until it is zero. Scans may return
90
+ duplicates and do not provide a snapshot while data changes.
91
+
92
+ Args:
93
+ cursor: Zero to start an iteration, or the cursor from the previous
94
+ call.
95
+ pattern: A Redis glob pattern to filter results, or None for no
96
+ filter.
97
+ count: A hint for work per call, not a result limit; None uses the
98
+ server default.
99
+ key_type: An optional Redis type name, such as "string" or "hash".
100
+
101
+ Returns:
102
+ A tuple (cursor, keys), where cursor is the next scan cursor and
103
+ keys is a list of unprefixed byte key names. A zero cursor ends the
104
+ iteration; an empty batch does not.
105
+
106
+ Raises:
107
+ EncoreError: Redis rejects the command or the request fails.
108
+ """
109
+ return await self._get_handle().generic_scan(
110
+ cursor,
111
+ pattern=pattern,
112
+ count=count,
113
+ key_type=key_type,
114
+ source=active_ctx_bytes(),
115
+ )
116
+
117
+ async def touch(self, key: str, *keys: str) -> int:
118
+ """Update the last-access time of existing keys.
119
+
120
+ Args:
121
+ key: The first database key, without an Encore prefix.
122
+ *keys: Additional database keys, without Encore prefixes.
123
+
124
+ Returns:
125
+ The number of existing keys that were touched.
126
+
127
+ Raises:
128
+ EncoreError: Redis rejects the command or the request fails.
129
+ """
130
+ keys = (key, *keys)
131
+ return await self._get_handle().generic_touch(keys, source=active_ctx_bytes())
132
+
133
+ async def ttl(self, key: str) -> int:
134
+ """Return the remaining lifetime of a key in seconds.
135
+
136
+ Args:
137
+ key: The database key, without an Encore key prefix.
138
+
139
+ Returns:
140
+ The remaining seconds, -1 for no expiry, or -2 for a missing key.
141
+
142
+ Raises:
143
+ EncoreError: Redis rejects the command or the request fails.
144
+ """
145
+ return await self._get_handle().generic_ttl(key, source=active_ctx_bytes())
146
+
147
+ async def type(self, key: str) -> str:
148
+ """Return the Redis data type stored at a key.
149
+
150
+ Args:
151
+ key: The database key, without an Encore key prefix.
152
+
153
+ Returns:
154
+ The type name, such as "string" or "hash", or "none" for a missing
155
+ key.
156
+
157
+ Raises:
158
+ EncoreError: Redis rejects the command or the request fails.
159
+ """
160
+ return await self._get_handle().generic_type(key, source=active_ctx_bytes())
161
+
162
+
163
+ class Interface(ReadOnlyInterface):
164
+ """Read and write commands."""
165
+
166
+ async def copy(self, key: str, destination: str, *, replace: bool = False) -> bool:
167
+ """Copy a value to another key in the same database.
168
+
169
+ Args:
170
+ key: The database key, without an Encore key prefix.
171
+ destination: The destination key, without an Encore key prefix.
172
+ replace: Whether to overwrite an existing destination.
173
+
174
+ Returns:
175
+ True if the value was copied; False if the source is missing or an
176
+ existing destination was not replaced.
177
+
178
+ Raises:
179
+ EncoreError: Redis rejects the command or the request fails.
180
+ """
181
+ return await self._get_handle().generic_copy(
182
+ key, destination, replace=replace, source=active_ctx_bytes()
183
+ )
184
+
185
+ async def delete(self, key: str, *keys: str) -> int:
186
+ """Delete keys and free their values synchronously.
187
+
188
+ Args:
189
+ key: The first database key, without an Encore prefix.
190
+ *keys: Additional database keys, without Encore prefixes.
191
+
192
+ Returns:
193
+ The number of keys removed; missing keys are ignored.
194
+
195
+ Raises:
196
+ EncoreError: Redis rejects the command or the request fails.
197
+ """
198
+ keys = (key, *keys)
199
+ return await self._get_handle().generic_delete(keys, source=active_ctx_bytes())
200
+
201
+ async def expire(
202
+ self, key: str, seconds: int, *, condition: str | None = None
203
+ ) -> bool:
204
+ """Set a key's remaining lifetime in seconds.
205
+
206
+ A nonpositive lifetime or expiration time in the past deletes the key
207
+ when the condition permits the operation.
208
+
209
+ Args:
210
+ key: The database key, without an Encore key prefix.
211
+ seconds: The lifetime in seconds.
212
+ condition: An optional case-insensitive condition: NX for no current
213
+ expiry, XX for an existing expiry, GT for a later expiry, or LT
214
+ for an earlier expiry.
215
+
216
+ Returns:
217
+ True if the timeout was applied; False if the key is missing or the
218
+ condition failed.
219
+
220
+ Raises:
221
+ EncoreError: Redis rejects the command or the request fails.
222
+ """
223
+ return await self._get_handle().generic_expire(
224
+ key, seconds, condition=condition, source=active_ctx_bytes()
225
+ )
226
+
227
+ async def expireat(
228
+ self, key: str, timestamp: int, *, condition: str | None = None
229
+ ) -> bool:
230
+ """Set a key's expiration time using Unix seconds.
231
+
232
+ A nonpositive lifetime or expiration time in the past deletes the key
233
+ when the condition permits the operation.
234
+
235
+ Args:
236
+ key: The database key, without an Encore key prefix.
237
+ timestamp: The expiration time in seconds since the Unix epoch.
238
+ condition: An optional case-insensitive condition: NX for no current
239
+ expiry, XX for an existing expiry, GT for a later expiry, or LT
240
+ for an earlier expiry.
241
+
242
+ Returns:
243
+ True if the timeout was applied; False if the key is missing or the
244
+ condition failed.
245
+
246
+ Raises:
247
+ EncoreError: Redis rejects the command or the request fails.
248
+ """
249
+ return await self._get_handle().generic_expireat(
250
+ key, timestamp, condition=condition, source=active_ctx_bytes()
251
+ )
252
+
253
+ async def persist(self, key: str) -> bool:
254
+ """Remove a key's expiration time.
255
+
256
+ Args:
257
+ key: The database key, without an Encore key prefix.
258
+
259
+ Returns:
260
+ True if an expiry was removed; False if the key is missing or has no
261
+ expiry.
262
+
263
+ Raises:
264
+ EncoreError: Redis rejects the command or the request fails.
265
+ """
266
+ return await self._get_handle().generic_persist(key, source=active_ctx_bytes())
267
+
268
+ async def pexpire(
269
+ self, key: str, milliseconds: int, *, condition: str | None = None
270
+ ) -> bool:
271
+ """Set a key's remaining lifetime in milliseconds.
272
+
273
+ A nonpositive lifetime or expiration time in the past deletes the key
274
+ when the condition permits the operation.
275
+
276
+ Args:
277
+ key: The database key, without an Encore key prefix.
278
+ milliseconds: The lifetime in milliseconds.
279
+ condition: An optional case-insensitive condition: NX for no current
280
+ expiry, XX for an existing expiry, GT for a later expiry, or LT
281
+ for an earlier expiry.
282
+
283
+ Returns:
284
+ True if the timeout was applied; False if the key is missing or the
285
+ condition failed.
286
+
287
+ Raises:
288
+ EncoreError: Redis rejects the command or the request fails.
289
+ """
290
+ return await self._get_handle().generic_pexpire(
291
+ key, milliseconds, condition=condition, source=active_ctx_bytes()
292
+ )
293
+
294
+ async def pexpireat(
295
+ self, key: str, timestamp: int, *, condition: str | None = None
296
+ ) -> bool:
297
+ """Set a key's expiration time using Unix milliseconds.
298
+
299
+ A nonpositive lifetime or expiration time in the past deletes the key
300
+ when the condition permits the operation.
301
+
302
+ Args:
303
+ key: The database key, without an Encore key prefix.
304
+ timestamp: The expiration time in milliseconds since the Unix epoch.
305
+ condition: An optional case-insensitive condition: NX for no current
306
+ expiry, XX for an existing expiry, GT for a later expiry, or LT
307
+ for an earlier expiry.
308
+
309
+ Returns:
310
+ True if the timeout was applied; False if the key is missing or the
311
+ condition failed.
312
+
313
+ Raises:
314
+ EncoreError: Redis rejects the command or the request fails.
315
+ """
316
+ return await self._get_handle().generic_pexpireat(
317
+ key, timestamp, condition=condition, source=active_ctx_bytes()
318
+ )
319
+
320
+ async def rename(self, key: str, destination: str) -> None:
321
+ """Rename a key, replacing any existing destination.
322
+
323
+ Args:
324
+ key: The database key, without an Encore key prefix.
325
+ destination: The destination key, without an Encore key prefix.
326
+
327
+ Raises:
328
+ EncoreError: The source key does not exist, or Redis rejects the
329
+ command or the request fails.
330
+ """
331
+ return await self._get_handle().generic_rename(
332
+ key, destination, source=active_ctx_bytes()
333
+ )
334
+
335
+ async def renamenx(self, key: str, destination: str) -> bool:
336
+ """Rename a key only if the destination does not exist.
337
+
338
+ Args:
339
+ key: The database key, without an Encore key prefix.
340
+ destination: The destination key, without an Encore key prefix.
341
+
342
+ Returns:
343
+ True if renamed; False if the destination already exists.
344
+
345
+ Raises:
346
+ EncoreError: The source key does not exist, or Redis rejects the
347
+ command or the request fails.
348
+ """
349
+ return await self._get_handle().generic_renamenx(
350
+ key, destination, source=active_ctx_bytes()
351
+ )
352
+
353
+ async def unlink(self, key: str, *keys: str) -> int:
354
+ """Remove keys and reclaim their memory asynchronously.
355
+
356
+ Args:
357
+ key: The first database key, without an Encore prefix.
358
+ *keys: Additional database keys, without Encore prefixes.
359
+
360
+ Returns:
361
+ The number of keys removed; missing keys are ignored.
362
+
363
+ Raises:
364
+ EncoreError: Redis rejects the command or the request fails.
365
+ """
366
+ keys = (key, *keys)
367
+ return await self._get_handle().generic_unlink(keys, source=active_ctx_bytes())