valkey-glide 2.0.0rc7__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl → 2.2.1rc3__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.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.
- glide/__init__.py +160 -106
- glide/async_commands/cluster_commands.py +101 -104
- glide/async_commands/core.py +617 -424
- glide/async_commands/{server_modules/ft.py → ft.py} +8 -7
- glide/async_commands/{server_modules/glide_json.py → glide_json.py} +15 -92
- glide/async_commands/standalone_commands.py +19 -57
- glide/glide.cpython-312-aarch64-linux-gnu.so +0 -0
- glide/glide.pyi +26 -1
- glide/glide_client.py +85 -47
- glide/logger.py +33 -21
- glide/opentelemetry.py +185 -0
- glide_shared/__init__.py +330 -0
- glide_shared/commands/__init__.py +0 -0
- {glide/async_commands → glide_shared/commands}/batch.py +441 -40
- glide_shared/commands/batch_options.py +261 -0
- glide_shared/commands/core_options.py +407 -0
- {glide/async_commands → glide_shared/commands}/server_modules/ft_options/ft_aggregate_options.py +3 -3
- {glide/async_commands → glide_shared/commands}/server_modules/ft_options/ft_create_options.py +4 -2
- {glide/async_commands → glide_shared/commands}/server_modules/ft_options/ft_profile_options.py +4 -4
- {glide/async_commands → glide_shared/commands}/server_modules/ft_options/ft_search_options.py +4 -2
- {glide/async_commands → glide_shared/commands}/server_modules/json_batch.py +4 -4
- glide_shared/commands/server_modules/json_options.py +93 -0
- {glide/async_commands → glide_shared/commands}/sorted_set.py +2 -2
- {glide/async_commands → glide_shared/commands}/stream.py +1 -1
- {glide → glide_shared}/config.py +386 -61
- {glide → glide_shared}/constants.py +3 -3
- {glide → glide_shared}/exceptions.py +27 -1
- glide_shared/protobuf/command_request_pb2.py +56 -0
- glide_shared/protobuf/connection_request_pb2.py +56 -0
- {glide → glide_shared}/protobuf/response_pb2.py +6 -6
- {glide → glide_shared}/routes.py +29 -15
- valkey_glide-2.2.1rc3.dist-info/METADATA +210 -0
- valkey_glide-2.2.1rc3.dist-info/RECORD +40 -0
- glide/protobuf/command_request_pb2.py +0 -54
- glide/protobuf/command_request_pb2.pyi +0 -1187
- glide/protobuf/connection_request_pb2.py +0 -54
- glide/protobuf/connection_request_pb2.pyi +0 -320
- glide/protobuf/response_pb2.pyi +0 -100
- valkey_glide-2.0.0rc7.dist-info/METADATA +0 -144
- valkey_glide-2.0.0rc7.dist-info/RECORD +0 -37
- {glide/async_commands → glide_shared/commands}/bitmap.py +0 -0
- {glide/async_commands → glide_shared/commands}/command_args.py +0 -0
- {glide/async_commands → glide_shared/commands}/server_modules/ft_options/ft_constants.py +0 -0
- {glide → glide_shared}/protobuf_codec.py +0 -0
- {valkey_glide-2.0.0rc7.dist-info → valkey_glide-2.2.1rc3.dist-info}/WHEEL +0 -0
glide/__init__.py
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
# Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import sys
|
|
4
|
+
import types
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
from glide.glide import (
|
|
8
|
+
ClusterScanCursor,
|
|
9
|
+
OpenTelemetryConfig,
|
|
10
|
+
OpenTelemetryMetricsConfig,
|
|
11
|
+
OpenTelemetryTracesConfig,
|
|
12
|
+
Script,
|
|
9
13
|
)
|
|
10
|
-
from
|
|
14
|
+
from glide_shared import (
|
|
15
|
+
OK,
|
|
16
|
+
TOK,
|
|
17
|
+
AdvancedGlideClientConfiguration,
|
|
18
|
+
AdvancedGlideClusterClientConfiguration,
|
|
19
|
+
AggregationType,
|
|
20
|
+
AllNodes,
|
|
21
|
+
AllPrimaries,
|
|
22
|
+
BackoffStrategy,
|
|
23
|
+
Batch,
|
|
24
|
+
BatchOptions,
|
|
25
|
+
BatchRetryStrategy,
|
|
11
26
|
BitEncoding,
|
|
12
27
|
BitFieldGet,
|
|
13
28
|
BitFieldIncrBy,
|
|
@@ -20,28 +35,26 @@ from glide.async_commands.bitmap import (
|
|
|
20
35
|
BitOffsetMultiplier,
|
|
21
36
|
BitOverflowControl,
|
|
22
37
|
BitwiseOperation,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
from glide.async_commands.core import (
|
|
38
|
+
ByAddressRoute,
|
|
39
|
+
ClosingError,
|
|
40
|
+
ClusterBatch,
|
|
41
|
+
ClusterBatchOptions,
|
|
42
|
+
ClusterTransaction,
|
|
29
43
|
ConditionalChange,
|
|
30
|
-
|
|
44
|
+
ConfigurationError,
|
|
45
|
+
ConnectionError,
|
|
46
|
+
DataType,
|
|
47
|
+
DistanceMetricType,
|
|
48
|
+
ExclusiveIdBound,
|
|
49
|
+
ExecAbortError,
|
|
31
50
|
ExpireOptions,
|
|
32
51
|
ExpiryGetEx,
|
|
33
52
|
ExpirySet,
|
|
34
53
|
ExpiryType,
|
|
35
54
|
ExpiryTypeGetEx,
|
|
55
|
+
Field,
|
|
56
|
+
FieldType,
|
|
36
57
|
FlushMode,
|
|
37
|
-
FunctionRestorePolicy,
|
|
38
|
-
InfoSection,
|
|
39
|
-
InsertPosition,
|
|
40
|
-
OnlyIfEqual,
|
|
41
|
-
UpdateOptions,
|
|
42
|
-
)
|
|
43
|
-
from glide.async_commands.server_modules import ft, glide_json, json_batch
|
|
44
|
-
from glide.async_commands.server_modules.ft_options.ft_aggregate_options import (
|
|
45
58
|
FtAggregateApply,
|
|
46
59
|
FtAggregateClause,
|
|
47
60
|
FtAggregateFilter,
|
|
@@ -49,59 +62,66 @@ from glide.async_commands.server_modules.ft_options.ft_aggregate_options import
|
|
|
49
62
|
FtAggregateLimit,
|
|
50
63
|
FtAggregateOptions,
|
|
51
64
|
FtAggregateReducer,
|
|
65
|
+
FtAggregateResponse,
|
|
52
66
|
FtAggregateSortBy,
|
|
53
67
|
FtAggregateSortProperty,
|
|
54
|
-
)
|
|
55
|
-
from glide.async_commands.server_modules.ft_options.ft_create_options import (
|
|
56
|
-
DataType,
|
|
57
|
-
DistanceMetricType,
|
|
58
|
-
Field,
|
|
59
|
-
FieldType,
|
|
60
68
|
FtCreateOptions,
|
|
61
|
-
|
|
62
|
-
TagField,
|
|
63
|
-
TextField,
|
|
64
|
-
VectorAlgorithm,
|
|
65
|
-
VectorField,
|
|
66
|
-
VectorFieldAttributes,
|
|
67
|
-
VectorFieldAttributesFlat,
|
|
68
|
-
VectorFieldAttributesHnsw,
|
|
69
|
-
VectorType,
|
|
70
|
-
)
|
|
71
|
-
from glide.async_commands.server_modules.ft_options.ft_profile_options import (
|
|
69
|
+
FtInfoResponse,
|
|
72
70
|
FtProfileOptions,
|
|
73
|
-
|
|
74
|
-
)
|
|
75
|
-
from glide.async_commands.server_modules.ft_options.ft_search_options import (
|
|
71
|
+
FtProfileResponse,
|
|
76
72
|
FtSearchLimit,
|
|
77
73
|
FtSearchOptions,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
from glide.async_commands.server_modules.glide_json import (
|
|
81
|
-
JsonArrIndexOptions,
|
|
82
|
-
JsonArrPopOptions,
|
|
83
|
-
JsonGetOptions,
|
|
84
|
-
)
|
|
85
|
-
from glide.async_commands.sorted_set import (
|
|
86
|
-
AggregationType,
|
|
74
|
+
FtSearchResponse,
|
|
75
|
+
FunctionRestorePolicy,
|
|
87
76
|
GeoSearchByBox,
|
|
88
77
|
GeoSearchByRadius,
|
|
89
78
|
GeoSearchCount,
|
|
90
79
|
GeospatialData,
|
|
91
80
|
GeoUnit,
|
|
81
|
+
GlideClientConfiguration,
|
|
82
|
+
GlideClusterClientConfiguration,
|
|
83
|
+
GlideError,
|
|
84
|
+
HashFieldConditionalChange,
|
|
85
|
+
IamAuthConfig,
|
|
86
|
+
IdBound,
|
|
92
87
|
InfBound,
|
|
88
|
+
InfoSection,
|
|
89
|
+
InsertPosition,
|
|
90
|
+
JsonArrIndexOptions,
|
|
91
|
+
JsonArrPopOptions,
|
|
92
|
+
JsonGetOptions,
|
|
93
93
|
LexBoundary,
|
|
94
|
+
Limit,
|
|
95
|
+
ListDirection,
|
|
96
|
+
MaxId,
|
|
97
|
+
MinId,
|
|
98
|
+
NodeAddress,
|
|
99
|
+
NumericField,
|
|
100
|
+
ObjectType,
|
|
101
|
+
OffsetOptions,
|
|
102
|
+
OnlyIfEqual,
|
|
103
|
+
OrderBy,
|
|
104
|
+
PeriodicChecksManualInterval,
|
|
105
|
+
PeriodicChecksStatus,
|
|
106
|
+
ProtocolVersion,
|
|
107
|
+
PubSubMsg,
|
|
108
|
+
QueryType,
|
|
109
|
+
RandomNode,
|
|
94
110
|
RangeByIndex,
|
|
95
111
|
RangeByLex,
|
|
96
112
|
RangeByScore,
|
|
113
|
+
ReadFrom,
|
|
114
|
+
RequestError,
|
|
115
|
+
ReturnField,
|
|
116
|
+
Route,
|
|
97
117
|
ScoreBoundary,
|
|
98
118
|
ScoreFilter,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
119
|
+
ServerCredentials,
|
|
120
|
+
ServiceType,
|
|
121
|
+
SignedEncoding,
|
|
122
|
+
SlotIdRoute,
|
|
123
|
+
SlotKeyRoute,
|
|
124
|
+
SlotType,
|
|
105
125
|
StreamAddOptions,
|
|
106
126
|
StreamClaimOptions,
|
|
107
127
|
StreamGroupOptions,
|
|
@@ -110,78 +130,105 @@ from glide.async_commands.stream import (
|
|
|
110
130
|
StreamReadGroupOptions,
|
|
111
131
|
StreamReadOptions,
|
|
112
132
|
StreamTrimOptions,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
)
|
|
116
|
-
from glide.config import (
|
|
117
|
-
AdvancedGlideClientConfiguration,
|
|
118
|
-
AdvancedGlideClusterClientConfiguration,
|
|
119
|
-
BackoffStrategy,
|
|
120
|
-
GlideClientConfiguration,
|
|
121
|
-
GlideClusterClientConfiguration,
|
|
122
|
-
NodeAddress,
|
|
123
|
-
PeriodicChecksManualInterval,
|
|
124
|
-
PeriodicChecksStatus,
|
|
125
|
-
ProtocolVersion,
|
|
126
|
-
ReadFrom,
|
|
127
|
-
ServerCredentials,
|
|
128
|
-
)
|
|
129
|
-
from glide.constants import (
|
|
130
|
-
OK,
|
|
131
|
-
TOK,
|
|
132
|
-
FtAggregateResponse,
|
|
133
|
-
FtInfoResponse,
|
|
134
|
-
FtProfileResponse,
|
|
135
|
-
FtSearchResponse,
|
|
133
|
+
TagField,
|
|
134
|
+
TBatch,
|
|
136
135
|
TClusterResponse,
|
|
137
136
|
TEncodable,
|
|
137
|
+
TextField,
|
|
138
138
|
TFunctionListResponse,
|
|
139
139
|
TFunctionStatsFullResponse,
|
|
140
140
|
TFunctionStatsSingleNodeResponse,
|
|
141
|
+
TimeoutError,
|
|
141
142
|
TJsonResponse,
|
|
142
143
|
TJsonUniversalResponse,
|
|
144
|
+
TlsAdvancedConfiguration,
|
|
145
|
+
Transaction,
|
|
143
146
|
TResult,
|
|
147
|
+
TrimByMaxLen,
|
|
148
|
+
TrimByMinId,
|
|
144
149
|
TSingleNodeRoute,
|
|
145
150
|
TXInfoStreamFullResponse,
|
|
146
151
|
TXInfoStreamResponse,
|
|
152
|
+
UnsignedEncoding,
|
|
153
|
+
UpdateOptions,
|
|
154
|
+
VectorAlgorithm,
|
|
155
|
+
VectorField,
|
|
156
|
+
VectorFieldAttributes,
|
|
157
|
+
VectorFieldAttributesFlat,
|
|
158
|
+
VectorFieldAttributesHnsw,
|
|
159
|
+
VectorType,
|
|
160
|
+
json_batch,
|
|
147
161
|
)
|
|
148
|
-
from glide.exceptions import (
|
|
149
|
-
ClosingError,
|
|
150
|
-
ConfigurationError,
|
|
151
|
-
ConnectionError,
|
|
152
|
-
ExecAbortError,
|
|
153
|
-
GlideError,
|
|
154
|
-
RequestError,
|
|
155
|
-
TimeoutError,
|
|
156
|
-
)
|
|
157
|
-
from glide.glide_client import GlideClient, GlideClusterClient, TGlideClient
|
|
158
|
-
from glide.logger import Level as LogLevel
|
|
159
|
-
from glide.logger import Logger
|
|
160
|
-
from glide.routes import (
|
|
161
|
-
AllNodes,
|
|
162
|
-
AllPrimaries,
|
|
163
|
-
ByAddressRoute,
|
|
164
|
-
RandomNode,
|
|
165
|
-
Route,
|
|
166
|
-
SlotIdRoute,
|
|
167
|
-
SlotKeyRoute,
|
|
168
|
-
SlotType,
|
|
169
|
-
)
|
|
170
162
|
|
|
171
|
-
from .
|
|
163
|
+
from .async_commands import ft, glide_json
|
|
164
|
+
from .glide_client import GlideClient, GlideClusterClient, TGlideClient
|
|
165
|
+
from .logger import Level as LogLevel
|
|
166
|
+
from .logger import Logger
|
|
167
|
+
|
|
168
|
+
_glide_module = sys.modules[__name__]
|
|
169
|
+
|
|
170
|
+
_legacy_modules = [
|
|
171
|
+
"glide.exceptions",
|
|
172
|
+
"glide.config",
|
|
173
|
+
"glide.constants",
|
|
174
|
+
"glide.routes",
|
|
175
|
+
"glide.async_commands",
|
|
176
|
+
"glide.async_commands.batch",
|
|
177
|
+
"glide.async_commands.batch_options",
|
|
178
|
+
"glide.async_commands.bitmap",
|
|
179
|
+
"glide.async_commands.command_args",
|
|
180
|
+
"glide.async_commands.server_modules",
|
|
181
|
+
"glide.async_commands.server_modules.ft_options",
|
|
182
|
+
"glide.async_commands.server_modules.ft_options.ft_aggregate_options",
|
|
183
|
+
"glide.async_commands.server_modules.ft_options.ft_create_options",
|
|
184
|
+
"glide.async_commands.server_modules.ft_options.ft_profile_options",
|
|
185
|
+
"glide.async_commands.server_modules.ft_options.ft_search_options",
|
|
186
|
+
"glide.async_commands.server_modules.glide_json",
|
|
187
|
+
"glide.async_commands.sorted_set",
|
|
188
|
+
"glide.async_commands.stream",
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class _LegacyModule(types.ModuleType):
|
|
193
|
+
"""Proxy for a deprecated module that warns when first accessed."""
|
|
194
|
+
|
|
195
|
+
def __init__(self, name):
|
|
196
|
+
super().__init__(name)
|
|
197
|
+
self._warned = False
|
|
198
|
+
|
|
199
|
+
def __getattr__(self, name):
|
|
200
|
+
if not self._warned:
|
|
201
|
+
warnings.warn(
|
|
202
|
+
f"Importing from '{self.__name__}' is deprecated. "
|
|
203
|
+
f"Please import directly from 'glide' instead.",
|
|
204
|
+
DeprecationWarning,
|
|
205
|
+
stacklevel=2,
|
|
206
|
+
)
|
|
207
|
+
self._warned = True
|
|
208
|
+
|
|
209
|
+
# Access the attribute from the real top-level glide module
|
|
210
|
+
return getattr(_glide_module, name)
|
|
172
211
|
|
|
173
|
-
|
|
212
|
+
|
|
213
|
+
# Replace old modules with lazy proxy modules
|
|
214
|
+
for old_name in _legacy_modules:
|
|
215
|
+
if old_name not in sys.modules:
|
|
216
|
+
sys.modules[old_name] = _LegacyModule(old_name)
|
|
174
217
|
|
|
175
218
|
__all__ = [
|
|
176
219
|
# Client
|
|
220
|
+
"TGlideClient",
|
|
177
221
|
"GlideClient",
|
|
178
222
|
"GlideClusterClient",
|
|
179
223
|
"Batch",
|
|
180
224
|
"ClusterBatch",
|
|
181
225
|
"ClusterTransaction",
|
|
182
226
|
"Transaction",
|
|
183
|
-
"TGlideClient",
|
|
184
227
|
"TBatch",
|
|
228
|
+
# Batch Options
|
|
229
|
+
"BatchOptions",
|
|
230
|
+
"BatchRetryStrategy",
|
|
231
|
+
"ClusterBatchOptions",
|
|
185
232
|
# Config
|
|
186
233
|
"AdvancedGlideClientConfiguration",
|
|
187
234
|
"AdvancedGlideClusterClientConfiguration",
|
|
@@ -190,10 +237,16 @@ __all__ = [
|
|
|
190
237
|
"BackoffStrategy",
|
|
191
238
|
"ReadFrom",
|
|
192
239
|
"ServerCredentials",
|
|
240
|
+
"ServiceType",
|
|
241
|
+
"IamAuthConfig",
|
|
193
242
|
"NodeAddress",
|
|
243
|
+
"OpenTelemetryConfig",
|
|
244
|
+
"OpenTelemetryMetricsConfig",
|
|
245
|
+
"OpenTelemetryTracesConfig",
|
|
194
246
|
"ProtocolVersion",
|
|
195
247
|
"PeriodicChecksManualInterval",
|
|
196
248
|
"PeriodicChecksStatus",
|
|
249
|
+
"TlsAdvancedConfiguration",
|
|
197
250
|
# Response
|
|
198
251
|
"OK",
|
|
199
252
|
"TClusterResponse",
|
|
@@ -243,11 +296,11 @@ __all__ = [
|
|
|
243
296
|
"GeoSearchCount",
|
|
244
297
|
"GeoUnit",
|
|
245
298
|
"GeospatialData",
|
|
299
|
+
"HashFieldConditionalChange",
|
|
246
300
|
"AggregationType",
|
|
247
301
|
"InfBound",
|
|
248
302
|
"InfoSection",
|
|
249
303
|
"InsertPosition",
|
|
250
|
-
"ft",
|
|
251
304
|
"LexBoundary",
|
|
252
305
|
"Limit",
|
|
253
306
|
"ListDirection",
|
|
@@ -303,6 +356,7 @@ __all__ = [
|
|
|
303
356
|
"RequestError",
|
|
304
357
|
"TimeoutError",
|
|
305
358
|
# Ft
|
|
359
|
+
"ft",
|
|
306
360
|
"DataType",
|
|
307
361
|
"DistanceMetricType",
|
|
308
362
|
"Field",
|
|
@@ -4,27 +4,28 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import Dict, List, Mapping, Optional, Union, cast
|
|
6
6
|
|
|
7
|
-
from glide.
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
|
|
7
|
+
from glide.glide import ClusterScanCursor, Script
|
|
8
|
+
from glide_shared.commands.batch import ClusterBatch
|
|
9
|
+
from glide_shared.commands.batch_options import ClusterBatchOptions
|
|
10
|
+
from glide_shared.commands.command_args import ObjectType
|
|
11
|
+
from glide_shared.commands.core_options import (
|
|
11
12
|
FlushMode,
|
|
12
13
|
FunctionRestorePolicy,
|
|
13
14
|
InfoSection,
|
|
14
15
|
)
|
|
15
|
-
from
|
|
16
|
+
from glide_shared.constants import (
|
|
16
17
|
TOK,
|
|
17
18
|
TClusterResponse,
|
|
18
19
|
TEncodable,
|
|
19
20
|
TFunctionListResponse,
|
|
20
21
|
TFunctionStatsSingleNodeResponse,
|
|
21
22
|
TResult,
|
|
22
|
-
TSingleNodeRoute,
|
|
23
23
|
)
|
|
24
|
-
from
|
|
25
|
-
from
|
|
24
|
+
from glide_shared.exceptions import RequestError
|
|
25
|
+
from glide_shared.protobuf.command_request_pb2 import RequestType
|
|
26
|
+
from glide_shared.routes import Route
|
|
26
27
|
|
|
27
|
-
from
|
|
28
|
+
from .core import CoreCommands
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class ClusterCommands(CoreCommands):
|
|
@@ -74,8 +75,8 @@ class ClusterCommands(CoreCommands):
|
|
|
74
75
|
Args:
|
|
75
76
|
sections (Optional[List[InfoSection]]): A list of InfoSection values specifying which sections of
|
|
76
77
|
information to retrieve. When no parameter is provided, the default option is assumed.
|
|
77
|
-
route (Optional[Route]): The command will be routed to all primaries, unless `route` is provided, in
|
|
78
|
-
case the client will route the command to the nodes defined by `route`. Defaults to None.
|
|
78
|
+
route (Optional[Route]): The command will be routed to all primaries, unless `route` is provided, in
|
|
79
|
+
which case the client will route the command to the nodes defined by `route`. Defaults to None.
|
|
79
80
|
|
|
80
81
|
Returns:
|
|
81
82
|
TClusterResponse[bytes]: If a single node route is requested, returns a bytes string containing the information for
|
|
@@ -94,128 +95,109 @@ class ClusterCommands(CoreCommands):
|
|
|
94
95
|
self,
|
|
95
96
|
batch: ClusterBatch,
|
|
96
97
|
raise_on_error: bool,
|
|
97
|
-
|
|
98
|
-
timeout: Optional[int] = None,
|
|
99
|
-
retry_server_error: bool = False,
|
|
100
|
-
retry_connection_error: bool = False,
|
|
98
|
+
options: Optional[ClusterBatchOptions] = None,
|
|
101
99
|
) -> Optional[List[TResult]]:
|
|
102
100
|
"""
|
|
103
101
|
Executes a batch by processing the queued commands.
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
See [Valkey Pipelines (Non-Atomic Batches)](https://valkey.io/docs/topics/pipelining/) for details.
|
|
107
|
-
|
|
108
|
-
#### Routing Behavior:
|
|
109
|
-
|
|
110
|
-
- If a `route` is specified:
|
|
111
|
-
- The entire batch is sent to the specified node.
|
|
103
|
+
**Routing Behavior:**
|
|
112
104
|
|
|
105
|
+
- If a `route` is specified in `ClusterBatchOptions`, the entire batch is sent
|
|
106
|
+
to the specified node.
|
|
113
107
|
- If no `route` is specified:
|
|
114
|
-
- Atomic batches (Transactions)
|
|
115
|
-
If no key is found, the request is sent to a random node.
|
|
116
|
-
- Non-atomic batches (Pipelines)
|
|
117
|
-
key's slot. If no key is present, routing follows the
|
|
118
|
-
Multi-node commands are automatically split and
|
|
108
|
+
- **Atomic batches (Transactions):** Routed to the slot owner of the
|
|
109
|
+
first key in the batch. If no key is found, the request is sent to a random node.
|
|
110
|
+
- **Non-atomic batches (Pipelines):** Each command is routed to the node
|
|
111
|
+
owning the corresponding key's slot. If no key is present, routing follows the
|
|
112
|
+
command's request policy. Multi-node commands are automatically split and
|
|
113
|
+
dispatched to the appropriate nodes.
|
|
119
114
|
|
|
120
|
-
|
|
115
|
+
**Behavior notes:**
|
|
121
116
|
|
|
122
|
-
- Atomic Batches (Transactions)
|
|
123
|
-
If keys span different slots, the transaction will fail. If the
|
|
124
|
-
`WATCH` command, `
|
|
117
|
+
- **Atomic Batches (Transactions):** All key-based commands must map to the
|
|
118
|
+
same hash slot. If keys span different slots, the transaction will fail. If the
|
|
119
|
+
transaction fails due to a `WATCH` command, `EXEC` will return `None`.
|
|
125
120
|
|
|
126
|
-
|
|
121
|
+
**Retry and Redirection:**
|
|
127
122
|
|
|
128
123
|
- If a redirection error occurs:
|
|
129
|
-
- Atomic batches (Transactions)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
124
|
+
- **Atomic batches (Transactions):** The entire transaction will be
|
|
125
|
+
redirected.
|
|
126
|
+
- **Non-atomic batches:** Only commands that encountered redirection
|
|
127
|
+
errors will be redirected.
|
|
128
|
+
- Retries for failures will be handled according to the configured `BatchRetryStrategy`.
|
|
134
129
|
|
|
135
130
|
Args:
|
|
136
|
-
batch (ClusterBatch): A `ClusterBatch`
|
|
137
|
-
raise_on_error (bool): Determines how errors are handled within the batch response.
|
|
138
|
-
`True`, the first encountered error in the batch will be raised as
|
|
139
|
-
exception after all retries and reconnections have been
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
If a redirection error occurs:
|
|
147
|
-
- For Atomic Batches (Transactions), the entire transaction will be redirected.
|
|
148
|
-
- For Non-Atomic Batches (Pipelines), only the commands that encountered redirection errors
|
|
149
|
-
will be redirected.
|
|
150
|
-
timeout (Optional[int]): The duration in milliseconds that the client should wait for the batch request
|
|
151
|
-
to complete. This duration encompasses sending the request, awaiting a response from the server,
|
|
152
|
-
and any required reconnections or retries.
|
|
153
|
-
|
|
154
|
-
If the specified timeout is exceeded, a timeout error will be raised. If not explicitly set,
|
|
155
|
-
the client's default request timeout will be used.
|
|
156
|
-
retry_server_error (bool): If `True`, retriable server errors (e.g., `TRYAGAIN`) will trigger a retry.
|
|
157
|
-
Warning: Retrying server errors may cause commands targeting the same slot to execute out of order.
|
|
158
|
-
Note: Currently supported only for non-atomic batches. Recommended to increase timeout when enabled.
|
|
159
|
-
retry_connection_error (bool): If `True`, connection failures will trigger a retry. Warning:
|
|
160
|
-
Retrying connection errors may lead to duplicate executions, as it is unclear which commands have
|
|
161
|
-
already been processed. Note: Currently supported only for non-atomic batches. Recommended to increase
|
|
162
|
-
timeout when enabled.
|
|
131
|
+
batch (ClusterBatch): A `ClusterBatch` containing the commands to execute.
|
|
132
|
+
raise_on_error (bool): Determines how errors are handled within the batch response.
|
|
133
|
+
When set to `True`, the first encountered error in the batch will be raised as an
|
|
134
|
+
exception of type `RequestError` after all retries and reconnections have been
|
|
135
|
+
executed.
|
|
136
|
+
When set to `False`, errors will be included as part of the batch response,
|
|
137
|
+
allowing the caller to process both successful and failed commands together. In this case,
|
|
138
|
+
error details will be provided as instances of `RequestError`.
|
|
139
|
+
options (Optional[ClusterBatchOptions]): A `ClusterBatchOptions` object containing execution options.
|
|
163
140
|
|
|
164
141
|
Returns:
|
|
165
|
-
Optional[List[TResult]]:
|
|
166
|
-
|
|
167
|
-
the list entry will be `None`. If the batch failed due to a `WATCH` command, `exec` will return
|
|
168
|
-
`None`.
|
|
169
|
-
|
|
170
|
-
Examples:
|
|
171
|
-
# Example 1: Atomic Batch (Transaction)
|
|
172
|
-
>>> atomic_batch = ClusterBatch(is_atomic=True) # Atomic (Transaction)
|
|
173
|
-
>>> atomic_batch.set("key", "1")
|
|
174
|
-
>>> atomic_batch.incr("key")
|
|
175
|
-
>>> atomic_batch.get("key")
|
|
176
|
-
>>> atomic_result = await cluster_client.exec(atomic_batch, false)
|
|
177
|
-
>>> print(f"Atomic Batch Result: {atomic_result}")
|
|
178
|
-
# Expected Output: Atomic Batch Result: [OK, 2, 2]
|
|
142
|
+
Optional[List[TResult]]: An array of results, where each entry
|
|
143
|
+
corresponds to a command's execution result.
|
|
179
144
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
>>> non_atomic_batch.set("key2", "value2")
|
|
184
|
-
>>> non_atomic_batch.get("key1")
|
|
185
|
-
>>> non_atomic_batch.get("key2")
|
|
186
|
-
>>> non_atomic_result = await cluster_client.exec(non_atomic_batch, false)
|
|
187
|
-
>>> print(f"Non-Atomic Batch Result: {non_atomic_result}")
|
|
188
|
-
# Expected Output: Non-Atomic Batch Result: [OK, OK, value1, value2]
|
|
145
|
+
See Also:
|
|
146
|
+
[Valkey Transactions (Atomic Batches)](https://valkey.io/docs/topics/transactions/)
|
|
147
|
+
[Valkey Pipelines (Non-Atomic Batches)](https://valkey.io/docs/topics/pipelining/)
|
|
189
148
|
|
|
190
|
-
|
|
149
|
+
Examples:
|
|
150
|
+
# Atomic batch (transaction): all keys must share the same hash slot
|
|
151
|
+
>>> options = ClusterBatchOptions(timeout=1000) # Set a timeout of 1000 milliseconds
|
|
191
152
|
>>> atomic_batch = ClusterBatch(is_atomic=True)
|
|
192
153
|
>>> atomic_batch.set("key", "1")
|
|
193
154
|
>>> atomic_batch.incr("key")
|
|
194
155
|
>>> atomic_batch.get("key")
|
|
195
|
-
>>> atomic_result = await cluster_client.exec(
|
|
196
|
-
... atomic_batch,
|
|
197
|
-
... timeout=1000, # Set a timeout of 1000 milliseconds
|
|
198
|
-
... raise_on_error=False # Do not raise an error on failure
|
|
199
|
-
... )
|
|
156
|
+
>>> atomic_result = await cluster_client.exec(atomic_batch, False, options)
|
|
200
157
|
>>> print(f"Atomic Batch Result: {atomic_result}")
|
|
201
158
|
# Output: Atomic Batch Result: [OK, 2, 2]
|
|
202
159
|
|
|
203
|
-
#
|
|
160
|
+
# Non-atomic batch (pipeline): keys may span different hash slots
|
|
161
|
+
>>> retry_strategy = BatchRetryStrategy(retry_server_error=True, retry_connection_error=False)
|
|
162
|
+
>>> pipeline_options = ClusterBatchOptions(retry_strategy=retry_strategy)
|
|
204
163
|
>>> non_atomic_batch = ClusterBatch(is_atomic=False)
|
|
205
164
|
>>> non_atomic_batch.set("key1", "value1")
|
|
206
165
|
>>> non_atomic_batch.set("key2", "value2")
|
|
207
166
|
>>> non_atomic_batch.get("key1")
|
|
208
167
|
>>> non_atomic_batch.get("key2")
|
|
209
|
-
>>> non_atomic_result = await cluster_client.exec(
|
|
210
|
-
... non_atomic_batch,
|
|
211
|
-
... raise_on_error=False,
|
|
212
|
-
... retry_server_error=True,
|
|
213
|
-
... retry_connection_error=False
|
|
214
|
-
... )
|
|
168
|
+
>>> non_atomic_result = await cluster_client.exec(non_atomic_batch, False, pipeline_options)
|
|
215
169
|
>>> print(f"Non-Atomic Batch Result: {non_atomic_result}")
|
|
216
170
|
# Output: Non-Atomic Batch Result: [OK, OK, value1, value2]
|
|
217
171
|
"""
|
|
218
172
|
commands = batch.commands[:]
|
|
173
|
+
|
|
174
|
+
if (
|
|
175
|
+
batch.is_atomic
|
|
176
|
+
and options
|
|
177
|
+
and options.retry_strategy
|
|
178
|
+
and (
|
|
179
|
+
options.retry_strategy.retry_server_error
|
|
180
|
+
or options.retry_strategy.retry_connection_error
|
|
181
|
+
)
|
|
182
|
+
):
|
|
183
|
+
raise RequestError(
|
|
184
|
+
"Retry strategies are not supported for atomic batches (transactions). "
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Extract values to make the _execute_batch call cleaner
|
|
188
|
+
retry_server_error = (
|
|
189
|
+
options.retry_strategy.retry_server_error
|
|
190
|
+
if options and options.retry_strategy
|
|
191
|
+
else False
|
|
192
|
+
)
|
|
193
|
+
retry_connection_error = (
|
|
194
|
+
options.retry_strategy.retry_connection_error
|
|
195
|
+
if options and options.retry_strategy
|
|
196
|
+
else False
|
|
197
|
+
)
|
|
198
|
+
route = options.route if options else None
|
|
199
|
+
timeout = options.timeout if options else None
|
|
200
|
+
|
|
219
201
|
return await self._execute_batch(
|
|
220
202
|
commands,
|
|
221
203
|
batch.is_atomic,
|
|
@@ -1084,11 +1066,17 @@ class ClusterCommands(CoreCommands):
|
|
|
1084
1066
|
self,
|
|
1085
1067
|
source: TEncodable,
|
|
1086
1068
|
destination: TEncodable,
|
|
1069
|
+
# TODO next major release the arguments replace and destinationDB must have their order
|
|
1070
|
+
# swapped to align with the standalone order.
|
|
1071
|
+
# At the moment of the patch release 2.1.1. we can't have a breaking change
|
|
1087
1072
|
replace: Optional[bool] = None,
|
|
1073
|
+
destinationDB: Optional[int] = None,
|
|
1088
1074
|
) -> bool:
|
|
1089
1075
|
"""
|
|
1090
|
-
Copies the value stored at the `source` to the `destination` key.
|
|
1091
|
-
|
|
1076
|
+
Copies the value stored at the `source` to the `destination` key. If `destinationDB`
|
|
1077
|
+
is specified, the value will be copied to the database specified by `destinationDB`,
|
|
1078
|
+
otherwise the current database will be used. When `replace` is True, removes the
|
|
1079
|
+
`destination` key first if it already exists, otherwise performs no action.
|
|
1092
1080
|
|
|
1093
1081
|
See [valkey.io](https://valkey.io/commands/copy) for more details.
|
|
1094
1082
|
|
|
@@ -1099,6 +1087,7 @@ class ClusterCommands(CoreCommands):
|
|
|
1099
1087
|
source (TEncodable): The key to the source value.
|
|
1100
1088
|
destination (TEncodable): The key where the value should be copied to.
|
|
1101
1089
|
replace (Optional[bool]): If the destination key should be removed before copying the value to it.
|
|
1090
|
+
destinationDB (Optional[int]): The alternative logical database index for the destination key.
|
|
1102
1091
|
|
|
1103
1092
|
Returns:
|
|
1104
1093
|
bool: True if the source was copied. Otherwise, returns False.
|
|
@@ -1107,12 +1096,20 @@ class ClusterCommands(CoreCommands):
|
|
|
1107
1096
|
>>> await client.set("source", "sheep")
|
|
1108
1097
|
>>> await client.copy(b"source", b"destination")
|
|
1109
1098
|
True # Source was copied
|
|
1099
|
+
>>> await client.copy(b"source", b"destination", destinationDB=1)
|
|
1100
|
+
True # Source was copied to DB 1
|
|
1101
|
+
>>> await client.select(1)
|
|
1110
1102
|
>>> await client.get("destination")
|
|
1111
1103
|
b"sheep"
|
|
1112
1104
|
|
|
1113
1105
|
Since: Valkey version 6.2.0.
|
|
1106
|
+
The destinationDB argument is available since Valkey 9.0.0
|
|
1114
1107
|
"""
|
|
1108
|
+
|
|
1109
|
+
# Build command arguments
|
|
1115
1110
|
args: List[TEncodable] = [source, destination]
|
|
1111
|
+
if destinationDB is not None:
|
|
1112
|
+
args.extend(["DB", str(destinationDB)])
|
|
1116
1113
|
if replace is True:
|
|
1117
1114
|
args.append("REPLACE")
|
|
1118
1115
|
return cast(
|
|
@@ -1159,7 +1156,7 @@ class ClusterCommands(CoreCommands):
|
|
|
1159
1156
|
args.extend(["VERSION", str(version)])
|
|
1160
1157
|
if parameters:
|
|
1161
1158
|
for var in parameters:
|
|
1162
|
-
args.
|
|
1159
|
+
args.append(str(var))
|
|
1163
1160
|
return cast(
|
|
1164
1161
|
TClusterResponse[bytes],
|
|
1165
1162
|
await self._execute_command(RequestType.Lolwut, args, route),
|
|
@@ -1439,7 +1436,7 @@ class ClusterCommands(CoreCommands):
|
|
|
1439
1436
|
|
|
1440
1437
|
Examples:
|
|
1441
1438
|
>>> lua_script = Script("return { KEYS[1], ARGV[1] }")
|
|
1442
|
-
>>> await client.invoke_script(lua_script, keys=["foo"], args=["bar"]
|
|
1439
|
+
>>> await client.invoke_script(lua_script, keys=["foo"], args=["bar"])
|
|
1443
1440
|
[b"foo", b"bar"]
|
|
1444
1441
|
"""
|
|
1445
1442
|
return await self._execute_script(script.get_hash(), keys, args)
|