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.
- encore/__init__.py +43 -0
- encore/cron/__init__.py +50 -0
- encore/internal/__init__.py +1 -0
- encore/internal/_loader.py +79 -0
- encore/internal/_native.pyi +734 -0
- encore/internal/lazy.py +35 -0
- encore/internal/runtime.py +133 -0
- encore/internal/startup.py +24 -0
- encore/logs/__init__.py +19 -0
- encore/logs/_console.py +155 -0
- encore/logs/_runtime.py +56 -0
- encore/meta/__init__.py +228 -0
- encore/metrics/__init__.py +390 -0
- encore/pubsub/__init__.py +425 -0
- encore/py.typed +0 -0
- encore/secrets/__init__.py +139 -0
- encore/shutdown/__init__.py +164 -0
- encore/storage/__init__.py +5 -0
- encore/storage/objects/__init__.py +396 -0
- encore/storage/postgres/__init__.py +737 -0
- encore/storage/redis/__init__.py +200 -0
- encore/storage/redis/_base.py +42 -0
- encore/storage/redis/_responses.py +150 -0
- encore/storage/redis/_values.py +189 -0
- encore/storage/redis/bitmap.py +142 -0
- encore/storage/redis/generic.py +367 -0
- encore/storage/redis/geo.py +508 -0
- encore/storage/redis/hash.py +504 -0
- encore/storage/redis/json.py +614 -0
- encore/storage/redis/list.py +511 -0
- encore/storage/redis/pubsub.py +276 -0
- encore/storage/redis/set.py +570 -0
- encore/storage/redis/sorted_set.py +753 -0
- encore/storage/redis/stream.py +773 -0
- encore/storage/redis/string.py +654 -0
- encore/tracing/__init__.py +19 -0
- encore/tracing/_context.py +27 -0
- encore/tracing/_encode.py +351 -0
- encore/tracing/_provider.py +62 -0
- encore/tracing/_span.py +226 -0
- encore/tracing/_tracer.py +93 -0
- encore_dev-2.0.0a7.dist-info/METADATA +791 -0
- encore_dev-2.0.0a7.dist-info/RECORD +44 -0
- encore_dev-2.0.0a7.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
"""RedisJSON commands using Python JSON values.
|
|
2
|
+
|
|
3
|
+
Values are serialized as JSON, including strings. Document replies are decoded
|
|
4
|
+
into Python values; JSONPath queries preserve the server's arrays of matches.
|
|
5
|
+
Requires a server with RedisJSON support.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json as _json
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from ...tracing._context import active_ctx_bytes
|
|
14
|
+
from ._base import CommandInterface
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _encode(value: Any) -> str:
|
|
18
|
+
"""Serialize a Python value as compact JSON text.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
value: A JSON-serializable value with finite numbers and no circular
|
|
22
|
+
references.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
JSON text with non-ASCII characters preserved.
|
|
26
|
+
"""
|
|
27
|
+
return _json.dumps(
|
|
28
|
+
value, ensure_ascii=False, allow_nan=False, separators=(",", ":")
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _decode(value: Any) -> Any:
|
|
33
|
+
"""Decode JSON byte strings within a RedisJSON reply.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
value: A byte string, a list of replies, or a scalar to preserve.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Decoded Python JSON values. Lists are traversed recursively; other
|
|
40
|
+
values are unchanged.
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
UnicodeDecodeError: JSON bytes use an invalid text encoding.
|
|
44
|
+
ValueError: A byte string is not valid JSON.
|
|
45
|
+
"""
|
|
46
|
+
if isinstance(value, bytes):
|
|
47
|
+
return _json.loads(value)
|
|
48
|
+
if isinstance(value, list):
|
|
49
|
+
return [_decode(item) for item in value]
|
|
50
|
+
return value
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _text(value: Any) -> Any:
|
|
54
|
+
"""Decode text byte strings within a RedisJSON metadata reply.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
value: A byte string, a list of replies, or a scalar to preserve.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
UTF-8-decoded strings. Lists are traversed recursively; other values are
|
|
61
|
+
unchanged.
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
UnicodeDecodeError: A byte string is not valid UTF-8.
|
|
65
|
+
"""
|
|
66
|
+
if isinstance(value, bytes):
|
|
67
|
+
return value.decode("utf-8")
|
|
68
|
+
if isinstance(value, list):
|
|
69
|
+
return [_text(item) for item in value]
|
|
70
|
+
return value
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ReadOnlyInterface(CommandInterface):
|
|
74
|
+
"""Commands available through a read-only database handle."""
|
|
75
|
+
|
|
76
|
+
async def arrindex(
|
|
77
|
+
self,
|
|
78
|
+
key: str,
|
|
79
|
+
path: str,
|
|
80
|
+
value: Any,
|
|
81
|
+
*,
|
|
82
|
+
start: int | None = None,
|
|
83
|
+
stop: int | None = None,
|
|
84
|
+
) -> Any:
|
|
85
|
+
"""Find a JSON value within arrays selected by a path.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
key: The database key, without an Encore key prefix.
|
|
89
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
90
|
+
expressions start with "$" and can select multiple values.
|
|
91
|
+
value: A Python JSON-serializable value; strings are encoded as JSON
|
|
92
|
+
strings, not treated as pre-encoded JSON. Numbers must be
|
|
93
|
+
finite, and values must not contain circular references.
|
|
94
|
+
start: The inclusive start index; negative indices count from the
|
|
95
|
+
end. Defaults to zero.
|
|
96
|
+
stop: The exclusive stop index; zero means through the end. Negative
|
|
97
|
+
indices count from the end. Requires start.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
For JSONPath, one index per match, -1 if not found, or None for a
|
|
101
|
+
non-array match. Legacy paths return a scalar index.
|
|
102
|
+
|
|
103
|
+
Raises:
|
|
104
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
105
|
+
"""
|
|
106
|
+
return await self._get_handle().json_arrindex(
|
|
107
|
+
key, path, _encode(value), start=start, stop=stop, source=active_ctx_bytes()
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
async def arrlen(self, key: str, *, path: str = "$") -> Any:
|
|
111
|
+
"""Return the lengths of arrays selected by a path.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
key: The database key, without an Encore key prefix.
|
|
115
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
116
|
+
expressions start with "$" and can select multiple values.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
For JSONPath, one length per match or None for a non-array match.
|
|
120
|
+
Legacy paths return a scalar length.
|
|
121
|
+
|
|
122
|
+
Raises:
|
|
123
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
124
|
+
"""
|
|
125
|
+
return await self._get_handle().json_arrlen(
|
|
126
|
+
key, path=path, source=active_ctx_bytes()
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
async def get(
|
|
130
|
+
self,
|
|
131
|
+
key: str,
|
|
132
|
+
*paths: str,
|
|
133
|
+
indent: str | None = None,
|
|
134
|
+
newline: str | None = None,
|
|
135
|
+
space: str | None = None,
|
|
136
|
+
) -> Any:
|
|
137
|
+
"""Return decoded JSON values selected by one or more paths.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
key: The database key, without an Encore key prefix.
|
|
141
|
+
*paths: Paths to retrieve; omit for the root document.
|
|
142
|
+
indent: The indentation in the server's JSON text; formatting is
|
|
143
|
+
discarded when decoded into Python values.
|
|
144
|
+
newline: The newline text in the server response; formatting is
|
|
145
|
+
discarded when decoded into Python values.
|
|
146
|
+
space: The spacing in the server response; formatting is discarded
|
|
147
|
+
when decoded into Python values.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Python JSON values, or None if the key is missing. A single JSONPath
|
|
151
|
+
returns a list of matches; multiple paths return a dictionary keyed
|
|
152
|
+
by path. With no paths, returns the root document.
|
|
153
|
+
|
|
154
|
+
Raises:
|
|
155
|
+
UnicodeDecodeError: The server response uses an invalid text
|
|
156
|
+
encoding.
|
|
157
|
+
ValueError: The server response is not valid JSON.
|
|
158
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
159
|
+
"""
|
|
160
|
+
return _decode(
|
|
161
|
+
await self._get_handle().json_get(
|
|
162
|
+
key,
|
|
163
|
+
paths=paths or None,
|
|
164
|
+
indent=indent,
|
|
165
|
+
newline=newline,
|
|
166
|
+
space=space,
|
|
167
|
+
source=active_ctx_bytes(),
|
|
168
|
+
)
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
async def mget(self, key: str, *keys: str, path: str) -> Any:
|
|
172
|
+
"""Return decoded JSON values from several keys in input order.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
key: The first database key, without an Encore prefix.
|
|
176
|
+
*keys: Additional database keys, without Encore prefixes.
|
|
177
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
178
|
+
expressions start with "$" and can select multiple values.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
One result per key, with None for missing keys or paths. JSONPath
|
|
182
|
+
results retain their lists of matches.
|
|
183
|
+
|
|
184
|
+
Raises:
|
|
185
|
+
UnicodeDecodeError: The server response uses an invalid text
|
|
186
|
+
encoding.
|
|
187
|
+
ValueError: The server response is not valid JSON.
|
|
188
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
189
|
+
"""
|
|
190
|
+
keys = (key, *keys)
|
|
191
|
+
return _decode(
|
|
192
|
+
await self._get_handle().json_mget(keys, path, source=active_ctx_bytes())
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
async def objkeys(self, key: str, *, path: str = "$") -> Any:
|
|
196
|
+
"""Return field names of JSON objects selected by a path.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
key: The database key, without an Encore key prefix.
|
|
200
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
201
|
+
expressions start with "$" and can select multiple values.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
For JSONPath, one list of Python string field names per match or
|
|
205
|
+
None for a non-object match. Legacy paths return a single list of
|
|
206
|
+
names.
|
|
207
|
+
|
|
208
|
+
Raises:
|
|
209
|
+
UnicodeDecodeError: The server response uses an invalid text
|
|
210
|
+
encoding.
|
|
211
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
212
|
+
"""
|
|
213
|
+
return _text(
|
|
214
|
+
await self._get_handle().json_objkeys(
|
|
215
|
+
key, path=path, source=active_ctx_bytes()
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
async def objlen(self, key: str, *, path: str = "$") -> Any:
|
|
220
|
+
"""Return the sizes of JSON objects selected by a path.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
key: The database key, without an Encore key prefix.
|
|
224
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
225
|
+
expressions start with "$" and can select multiple values.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
For JSONPath, one field count per match or None for a non-object
|
|
229
|
+
match. Legacy paths return a scalar count.
|
|
230
|
+
|
|
231
|
+
Raises:
|
|
232
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
233
|
+
"""
|
|
234
|
+
return await self._get_handle().json_objlen(
|
|
235
|
+
key, path=path, source=active_ctx_bytes()
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
async def strlen(self, key: str, *, path: str = "$") -> Any:
|
|
239
|
+
"""Return the lengths of JSON strings selected by a path.
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
key: The database key, without an Encore key prefix.
|
|
243
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
244
|
+
expressions start with "$" and can select multiple values.
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
For JSONPath, one length per match or None for a non-string match.
|
|
248
|
+
Legacy paths return a scalar length.
|
|
249
|
+
|
|
250
|
+
Raises:
|
|
251
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
252
|
+
"""
|
|
253
|
+
return await self._get_handle().json_strlen(
|
|
254
|
+
key, path=path, source=active_ctx_bytes()
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
async def type(self, key: str, *, path: str = "$") -> Any:
|
|
258
|
+
"""Return the JSON types of values selected by a path.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
key: The database key, without an Encore key prefix.
|
|
262
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
263
|
+
expressions start with "$" and can select multiple values.
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
For JSONPath, a list of Python string type names. Legacy paths
|
|
267
|
+
return a single type name, or None if the path is missing.
|
|
268
|
+
|
|
269
|
+
Raises:
|
|
270
|
+
UnicodeDecodeError: The server response uses an invalid text
|
|
271
|
+
encoding.
|
|
272
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
273
|
+
"""
|
|
274
|
+
return _text(
|
|
275
|
+
await self._get_handle().json_type(
|
|
276
|
+
key, path=path, source=active_ctx_bytes()
|
|
277
|
+
)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
class Interface(ReadOnlyInterface):
|
|
282
|
+
"""Read and write commands."""
|
|
283
|
+
|
|
284
|
+
async def arrappend(self, key: str, path: str, value: Any, *values: Any) -> Any:
|
|
285
|
+
"""Append Python JSON values to arrays selected by a path.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
key: The database key, without an Encore key prefix.
|
|
289
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
290
|
+
expressions start with "$" and can select multiple values.
|
|
291
|
+
value: The first JSON value to append.
|
|
292
|
+
Numbers must be finite, and values must not contain circular
|
|
293
|
+
references.
|
|
294
|
+
*values: Additional JSON values with the same restrictions,
|
|
295
|
+
in order.
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
For JSONPath, one resulting length per match or None for a non-array
|
|
299
|
+
match. Legacy paths return a scalar length.
|
|
300
|
+
|
|
301
|
+
Raises:
|
|
302
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
303
|
+
"""
|
|
304
|
+
values = (value, *values)
|
|
305
|
+
return await self._get_handle().json_arrappend(
|
|
306
|
+
key, path, [_encode(value) for value in values], source=active_ctx_bytes()
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
async def arrinsert(
|
|
310
|
+
self, key: str, path: str, index: int, value: Any, *values: Any
|
|
311
|
+
) -> Any:
|
|
312
|
+
"""Insert Python JSON values into arrays selected by a path.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
key: The database key, without an Encore key prefix.
|
|
316
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
317
|
+
expressions start with "$" and can select multiple values.
|
|
318
|
+
index: The zero-based index; negative values count from the end.
|
|
319
|
+
value: The first JSON value to insert.
|
|
320
|
+
Numbers must be finite, and values must not contain circular
|
|
321
|
+
references.
|
|
322
|
+
*values: Additional JSON values with the same restrictions,
|
|
323
|
+
in order.
|
|
324
|
+
|
|
325
|
+
Returns:
|
|
326
|
+
For JSONPath, one resulting length per match or None for a non-array
|
|
327
|
+
match. Legacy paths return a scalar length.
|
|
328
|
+
|
|
329
|
+
Raises:
|
|
330
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
331
|
+
"""
|
|
332
|
+
values = (value, *values)
|
|
333
|
+
return await self._get_handle().json_arrinsert(
|
|
334
|
+
key,
|
|
335
|
+
path,
|
|
336
|
+
index,
|
|
337
|
+
[_encode(value) for value in values],
|
|
338
|
+
source=active_ctx_bytes(),
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
async def arrpop(self, key: str, *, path: str = "$", index: int = -1) -> Any:
|
|
342
|
+
"""Remove and return elements from arrays selected by a path.
|
|
343
|
+
|
|
344
|
+
The command executes before the reply is decoded. A decoding error does
|
|
345
|
+
not undo changes to the stored document.
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
key: The database key, without an Encore key prefix.
|
|
349
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
350
|
+
expressions start with "$" and can select multiple values.
|
|
351
|
+
index: The index to remove; -1 selects the last element.
|
|
352
|
+
Out-of-range indices are clamped to the nearest end.
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
For JSONPath, one decoded Python value per match, or None for an
|
|
356
|
+
empty array or non-array match. Legacy paths return a single decoded
|
|
357
|
+
value.
|
|
358
|
+
|
|
359
|
+
Raises:
|
|
360
|
+
UnicodeDecodeError: The server response uses an invalid text
|
|
361
|
+
encoding.
|
|
362
|
+
ValueError: The server response is not valid JSON.
|
|
363
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
364
|
+
"""
|
|
365
|
+
return _decode(
|
|
366
|
+
await self._get_handle().json_arrpop(
|
|
367
|
+
key, path=path, index=index, source=active_ctx_bytes()
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
async def arrtrim(self, key: str, path: str, start: int, stop: int) -> Any:
|
|
372
|
+
"""Keep an inclusive range of elements in selected JSON arrays.
|
|
373
|
+
|
|
374
|
+
Args:
|
|
375
|
+
key: The database key, without an Encore key prefix.
|
|
376
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
377
|
+
expressions start with "$" and can select multiple values.
|
|
378
|
+
start: The inclusive starting index; negative values count from the
|
|
379
|
+
end.
|
|
380
|
+
stop: The inclusive ending index; negative values count from the
|
|
381
|
+
end.
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
For JSONPath, one resulting length per match or None for a non-array
|
|
385
|
+
match. Legacy paths return a scalar length.
|
|
386
|
+
|
|
387
|
+
Raises:
|
|
388
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
389
|
+
"""
|
|
390
|
+
return await self._get_handle().json_arrtrim(
|
|
391
|
+
key, path, start, stop, source=active_ctx_bytes()
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
async def clear(self, key: str, *, path: str = "$") -> Any:
|
|
395
|
+
"""Empty selected containers and reset selected numbers to zero.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
key: The database key, without an Encore key prefix.
|
|
399
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
400
|
+
expressions start with "$" and can select multiple values.
|
|
401
|
+
|
|
402
|
+
Returns:
|
|
403
|
+
The number of values changed; values already empty or zero are not
|
|
404
|
+
counted.
|
|
405
|
+
|
|
406
|
+
Raises:
|
|
407
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
408
|
+
"""
|
|
409
|
+
return await self._get_handle().json_clear(
|
|
410
|
+
key, path=path, source=active_ctx_bytes()
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
async def delete(self, key: str, *, path: str = "$") -> Any:
|
|
414
|
+
"""Delete the JSON values selected by a path.
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
key: The database key, without an Encore key prefix.
|
|
418
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
419
|
+
expressions start with "$" and can select multiple values.
|
|
420
|
+
|
|
421
|
+
Returns:
|
|
422
|
+
The number of values deleted, or zero if nothing matches.
|
|
423
|
+
|
|
424
|
+
Raises:
|
|
425
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
426
|
+
"""
|
|
427
|
+
return await self._get_handle().json_delete(
|
|
428
|
+
key, path=path, source=active_ctx_bytes()
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
async def forget(self, key: str, *, path: str = "$") -> Any:
|
|
432
|
+
"""Delete selected JSON values, as an alias for delete.
|
|
433
|
+
|
|
434
|
+
Args:
|
|
435
|
+
key: The database key, without an Encore key prefix.
|
|
436
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
437
|
+
expressions start with "$" and can select multiple values.
|
|
438
|
+
|
|
439
|
+
Returns:
|
|
440
|
+
The number of values deleted, or zero if nothing matches.
|
|
441
|
+
|
|
442
|
+
Raises:
|
|
443
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
444
|
+
"""
|
|
445
|
+
return await self._get_handle().json_forget(
|
|
446
|
+
key, path=path, source=active_ctx_bytes()
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
async def merge(self, key: str, path: str, value: Any) -> Any:
|
|
450
|
+
"""Apply a JSON Merge Patch to the values selected by a path.
|
|
451
|
+
|
|
452
|
+
Uses JSON Merge Patch semantics: object fields are merged, null fields
|
|
453
|
+
remove existing fields, and arrays or scalars replace the target value.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
key: The database key, without an Encore key prefix.
|
|
457
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
458
|
+
expressions start with "$" and can select multiple values.
|
|
459
|
+
value: A Python JSON-serializable value; strings are encoded as JSON
|
|
460
|
+
strings, not treated as pre-encoded JSON. Numbers must be
|
|
461
|
+
finite, and values must not contain circular references.
|
|
462
|
+
|
|
463
|
+
Returns:
|
|
464
|
+
b"OK" when the merge succeeds.
|
|
465
|
+
|
|
466
|
+
Raises:
|
|
467
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
468
|
+
"""
|
|
469
|
+
return await self._get_handle().json_merge(
|
|
470
|
+
key, path, _encode(value), source=active_ctx_bytes()
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
async def mset(
|
|
474
|
+
self, item: tuple[str, str, Any], *items: tuple[str, str, Any]
|
|
475
|
+
) -> Any:
|
|
476
|
+
"""Set multiple JSON values atomically.
|
|
477
|
+
|
|
478
|
+
Args:
|
|
479
|
+
item: The first (key, path, Python JSON value) tuple. Numbers must
|
|
480
|
+
be finite, and values must not contain circular references.
|
|
481
|
+
*items: Additional tuples of the same shape, in order.
|
|
482
|
+
|
|
483
|
+
Raises:
|
|
484
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
485
|
+
"""
|
|
486
|
+
items = (item, *items)
|
|
487
|
+
return await self._get_handle().json_mset(
|
|
488
|
+
[(key, path, _encode(value)) for key, path, value in items],
|
|
489
|
+
source=active_ctx_bytes(),
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
async def numincrby(self, key: str, path: str, number: float) -> Any:
|
|
493
|
+
"""Add a number to JSON numeric values selected by a path.
|
|
494
|
+
|
|
495
|
+
The command executes before the reply is decoded. A decoding error does
|
|
496
|
+
not undo changes to the stored document.
|
|
497
|
+
|
|
498
|
+
Args:
|
|
499
|
+
key: The database key, without an Encore key prefix.
|
|
500
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
501
|
+
expressions start with "$" and can select multiple values.
|
|
502
|
+
number: The number used in the arithmetic operation.
|
|
503
|
+
|
|
504
|
+
Returns:
|
|
505
|
+
For JSONPath, a list of resulting numbers or None for non-numeric
|
|
506
|
+
matches. Legacy paths return a scalar number.
|
|
507
|
+
|
|
508
|
+
Raises:
|
|
509
|
+
UnicodeDecodeError: The server response uses an invalid text
|
|
510
|
+
encoding.
|
|
511
|
+
ValueError: The server response is not valid JSON.
|
|
512
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
513
|
+
"""
|
|
514
|
+
return _decode(
|
|
515
|
+
await self._get_handle().json_numincrby(
|
|
516
|
+
key, path, number, source=active_ctx_bytes()
|
|
517
|
+
)
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
async def nummultby(self, key: str, path: str, number: float) -> Any:
|
|
521
|
+
"""Multiply JSON numeric values selected by a path.
|
|
522
|
+
|
|
523
|
+
The command executes before the reply is decoded. A decoding error does
|
|
524
|
+
not undo changes to the stored document.
|
|
525
|
+
|
|
526
|
+
Args:
|
|
527
|
+
key: The database key, without an Encore key prefix.
|
|
528
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
529
|
+
expressions start with "$" and can select multiple values.
|
|
530
|
+
number: The number used in the arithmetic operation.
|
|
531
|
+
|
|
532
|
+
Returns:
|
|
533
|
+
For JSONPath, a list of resulting numbers or None for non-numeric
|
|
534
|
+
matches. Legacy paths return a scalar number.
|
|
535
|
+
|
|
536
|
+
Raises:
|
|
537
|
+
UnicodeDecodeError: The server response uses an invalid text
|
|
538
|
+
encoding.
|
|
539
|
+
ValueError: The server response is not valid JSON.
|
|
540
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
541
|
+
"""
|
|
542
|
+
return _decode(
|
|
543
|
+
await self._get_handle().json_nummultby(
|
|
544
|
+
key, path, number, source=active_ctx_bytes()
|
|
545
|
+
)
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
async def set(
|
|
549
|
+
self, key: str, path: str, value: Any, *, condition: str | None = None
|
|
550
|
+
) -> Any:
|
|
551
|
+
"""Set a JSON value, optionally requiring an existing or new path.
|
|
552
|
+
|
|
553
|
+
Args:
|
|
554
|
+
key: The database key, without an Encore key prefix.
|
|
555
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
556
|
+
expressions start with "$" and can select multiple values.
|
|
557
|
+
value: A Python JSON-serializable value; strings are encoded as JSON
|
|
558
|
+
strings, not treated as pre-encoded JSON. Numbers must be
|
|
559
|
+
finite, and values must not contain circular references.
|
|
560
|
+
condition: NX to set only a new path, XX to set only an existing
|
|
561
|
+
path, or None for no condition. Case-insensitive.
|
|
562
|
+
|
|
563
|
+
Returns:
|
|
564
|
+
b"OK" if the value was set, or None if the condition failed or the
|
|
565
|
+
server could not create the path.
|
|
566
|
+
|
|
567
|
+
Raises:
|
|
568
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
569
|
+
"""
|
|
570
|
+
return await self._get_handle().json_set(
|
|
571
|
+
key, path, _encode(value), condition=condition, source=active_ctx_bytes()
|
|
572
|
+
)
|
|
573
|
+
|
|
574
|
+
async def strappend(self, key: str, path: str, value: Any) -> Any:
|
|
575
|
+
"""Append a Python string to JSON strings selected by a path.
|
|
576
|
+
|
|
577
|
+
Args:
|
|
578
|
+
key: The database key, without an Encore key prefix.
|
|
579
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
580
|
+
expressions start with "$" and can select multiple values.
|
|
581
|
+
value: The Python string to append; it is JSON-encoded
|
|
582
|
+
automatically. Numbers must be finite, and values must not
|
|
583
|
+
contain circular references.
|
|
584
|
+
|
|
585
|
+
Returns:
|
|
586
|
+
For JSONPath, one resulting length per match or None for a
|
|
587
|
+
non-string match. Legacy paths return a scalar length.
|
|
588
|
+
|
|
589
|
+
Raises:
|
|
590
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
591
|
+
"""
|
|
592
|
+
return await self._get_handle().json_strappend(
|
|
593
|
+
key, path, _encode(value), source=active_ctx_bytes()
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
async def toggle(self, key: str, *, path: str = "$") -> Any:
|
|
597
|
+
"""Invert JSON boolean values selected by a path.
|
|
598
|
+
|
|
599
|
+
Args:
|
|
600
|
+
key: The database key, without an Encore key prefix.
|
|
601
|
+
path: The JSONPath expression, or a legacy RedisJSON path. JSONPath
|
|
602
|
+
expressions start with "$" and can select multiple values.
|
|
603
|
+
|
|
604
|
+
Returns:
|
|
605
|
+
For JSONPath, a list of 0/1 results or None for non-boolean matches.
|
|
606
|
+
Legacy paths return a scalar 0 or 1, or None for a non-boolean
|
|
607
|
+
match.
|
|
608
|
+
|
|
609
|
+
Raises:
|
|
610
|
+
EncoreError: Redis rejects the command or the request fails.
|
|
611
|
+
"""
|
|
612
|
+
return await self._get_handle().json_toggle(
|
|
613
|
+
key, path=path, source=active_ctx_bytes()
|
|
614
|
+
)
|