python-arango-async 1.2.3__py3-none-any.whl → 1.2.5__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.
- arangoasync/collection.py +62 -20
- arangoasync/replication.py +19 -3
- arangoasync/typings.py +12 -0
- arangoasync/version.py +1 -1
- {python_arango_async-1.2.3.dist-info → python_arango_async-1.2.5.dist-info}/METADATA +2 -2
- {python_arango_async-1.2.3.dist-info → python_arango_async-1.2.5.dist-info}/RECORD +9 -9
- {python_arango_async-1.2.3.dist-info → python_arango_async-1.2.5.dist-info}/WHEEL +1 -1
- {python_arango_async-1.2.3.dist-info → python_arango_async-1.2.5.dist-info}/licenses/LICENSE +0 -0
- {python_arango_async-1.2.3.dist-info → python_arango_async-1.2.5.dist-info}/top_level.txt +0 -0
arangoasync/collection.py
CHANGED
|
@@ -194,24 +194,49 @@ class Collection(Generic[T, U, V]):
|
|
|
194
194
|
|
|
195
195
|
return doc_id
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
@staticmethod
|
|
198
|
+
def _build_attribute_expression(field: str, prefix: str, bind_vars: Json) -> str:
|
|
199
|
+
"""Build a bind-safe AQL document attribute expression."""
|
|
200
|
+
bind_vars[prefix] = field
|
|
201
|
+
field_access = f"doc[@{prefix}]"
|
|
202
|
+
|
|
203
|
+
if "." not in field:
|
|
204
|
+
return field_access
|
|
205
|
+
|
|
206
|
+
nested_access = "doc"
|
|
207
|
+
for field_index, field_part in enumerate(field.split(".")):
|
|
208
|
+
field_var = f"{prefix}_{field_index}"
|
|
209
|
+
bind_vars[field_var] = field_part
|
|
210
|
+
nested_access += f"[@{field_var}]"
|
|
211
|
+
|
|
212
|
+
return f"(HAS(doc, @{prefix}) ? {field_access} : {nested_access})"
|
|
213
|
+
|
|
214
|
+
def _build_filter_conditions(self, filters: Optional[Json]) -> tuple[str, Json]:
|
|
198
215
|
"""Build filter conditions for an AQL query.
|
|
199
216
|
|
|
200
217
|
Args:
|
|
201
218
|
filters (dict | None): Document filters.
|
|
202
219
|
|
|
203
220
|
Returns:
|
|
204
|
-
|
|
221
|
+
tuple: The complete AQL filter condition and its bind variables.
|
|
205
222
|
"""
|
|
206
223
|
if not filters:
|
|
207
|
-
return ""
|
|
224
|
+
return "", {}
|
|
208
225
|
|
|
209
226
|
conditions = []
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
227
|
+
bind_vars: Json = {}
|
|
228
|
+
for filter_index, (field, value) in enumerate(filters.items()):
|
|
229
|
+
field_access = self._build_attribute_expression(
|
|
230
|
+
field,
|
|
231
|
+
f"filter_field_{filter_index}",
|
|
232
|
+
bind_vars,
|
|
233
|
+
)
|
|
213
234
|
|
|
214
|
-
|
|
235
|
+
value_var = f"filter_value_{filter_index}"
|
|
236
|
+
bind_vars[value_var] = value
|
|
237
|
+
conditions.append(f"{field_access} == @{value_var}")
|
|
238
|
+
|
|
239
|
+
return "FILTER " + " AND ".join(conditions), bind_vars
|
|
215
240
|
|
|
216
241
|
@staticmethod
|
|
217
242
|
def _is_none_or_int(obj: Any) -> bool:
|
|
@@ -259,24 +284,30 @@ class Collection(Generic[T, U, V]):
|
|
|
259
284
|
raise SortValidationError("'sort_order' must be either 'ASC' or 'DESC'")
|
|
260
285
|
|
|
261
286
|
@staticmethod
|
|
262
|
-
def _build_sort_expression(sort: Optional[Jsons]) -> str:
|
|
287
|
+
def _build_sort_expression(sort: Optional[Jsons]) -> tuple[str, Json]:
|
|
263
288
|
"""Build a sort condition for an AQL query.
|
|
264
289
|
|
|
265
290
|
Args:
|
|
266
291
|
sort (list | None): Document sort parameters.
|
|
267
292
|
|
|
268
293
|
Returns:
|
|
269
|
-
|
|
294
|
+
tuple: The complete AQL sort condition and its bind variables.
|
|
270
295
|
"""
|
|
271
296
|
if not sort:
|
|
272
|
-
return ""
|
|
297
|
+
return "", {}
|
|
273
298
|
|
|
274
299
|
sort_chunks = []
|
|
275
|
-
|
|
276
|
-
|
|
300
|
+
bind_vars: Json = {}
|
|
301
|
+
for sort_index, sort_param in enumerate(sort):
|
|
302
|
+
field_access = Collection._build_attribute_expression(
|
|
303
|
+
sort_param["sort_by"],
|
|
304
|
+
f"sort_field_{sort_index}",
|
|
305
|
+
bind_vars,
|
|
306
|
+
)
|
|
307
|
+
chunk = f"{field_access} {sort_param['sort_order'].upper()}"
|
|
277
308
|
sort_chunks.append(chunk)
|
|
278
309
|
|
|
279
|
-
return "SORT " + ", ".join(sort_chunks)
|
|
310
|
+
return "SORT " + ", ".join(sort_chunks), bind_vars
|
|
280
311
|
|
|
281
312
|
@property
|
|
282
313
|
def name(self) -> str:
|
|
@@ -1025,14 +1056,20 @@ class Collection(Generic[T, U, V]):
|
|
|
1025
1056
|
|
|
1026
1057
|
skip = skip if skip is not None else 0
|
|
1027
1058
|
limit = limit if limit is not None else "null"
|
|
1059
|
+
filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
|
|
1060
|
+
sort_expression, sort_bind_vars = self._build_sort_expression(sort)
|
|
1028
1061
|
query = f"""
|
|
1029
1062
|
FOR doc IN @@collection
|
|
1030
|
-
{
|
|
1063
|
+
{filter_conditions}
|
|
1031
1064
|
LIMIT {skip}, {limit}
|
|
1032
|
-
{
|
|
1065
|
+
{sort_expression}
|
|
1033
1066
|
RETURN doc
|
|
1034
1067
|
"""
|
|
1035
|
-
bind_vars = {
|
|
1068
|
+
bind_vars = {
|
|
1069
|
+
"@collection": self.name,
|
|
1070
|
+
**filter_bind_vars,
|
|
1071
|
+
**sort_bind_vars,
|
|
1072
|
+
}
|
|
1036
1073
|
data: Json = {"query": query, "bindVars": bind_vars, "count": True}
|
|
1037
1074
|
headers: RequestHeaders = {}
|
|
1038
1075
|
if allow_dirty_read is not None:
|
|
@@ -1095,9 +1132,10 @@ class Collection(Generic[T, U, V]):
|
|
|
1095
1132
|
raise ValueError("limit parameter must be a non-negative int")
|
|
1096
1133
|
|
|
1097
1134
|
sync = f", waitForSync: {wait_for_sync}" if wait_for_sync is not None else ""
|
|
1135
|
+
filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
|
|
1098
1136
|
query = f"""
|
|
1099
1137
|
FOR doc IN @@collection
|
|
1100
|
-
{
|
|
1138
|
+
{filter_conditions}
|
|
1101
1139
|
{f"LIMIT {limit}" if limit is not None else ""}
|
|
1102
1140
|
UPDATE doc WITH @body IN @@collection
|
|
1103
1141
|
OPTIONS {{ keepNull: @keep_none, mergeObjects: @merge {sync} }}
|
|
@@ -1107,6 +1145,7 @@ class Collection(Generic[T, U, V]):
|
|
|
1107
1145
|
"body": body,
|
|
1108
1146
|
"keep_none": keep_none,
|
|
1109
1147
|
"merge": merge_objects,
|
|
1148
|
+
**filter_bind_vars,
|
|
1110
1149
|
}
|
|
1111
1150
|
data = {"query": query, "bindVars": bind_vars}
|
|
1112
1151
|
|
|
@@ -1151,9 +1190,10 @@ class Collection(Generic[T, U, V]):
|
|
|
1151
1190
|
raise ValueError("limit parameter must be a non-negative int")
|
|
1152
1191
|
|
|
1153
1192
|
sync = f"waitForSync: {wait_for_sync}" if wait_for_sync is not None else ""
|
|
1193
|
+
filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
|
|
1154
1194
|
query = f"""
|
|
1155
1195
|
FOR doc IN @@collection
|
|
1156
|
-
{
|
|
1196
|
+
{filter_conditions}
|
|
1157
1197
|
{f"LIMIT {limit}" if limit is not None else ""}
|
|
1158
1198
|
REPLACE doc WITH @body IN @@collection
|
|
1159
1199
|
{f"OPTIONS {{ {sync} }}" if sync else ""}
|
|
@@ -1161,6 +1201,7 @@ class Collection(Generic[T, U, V]):
|
|
|
1161
1201
|
bind_vars = {
|
|
1162
1202
|
"@collection": self.name,
|
|
1163
1203
|
"body": body,
|
|
1204
|
+
**filter_bind_vars,
|
|
1164
1205
|
}
|
|
1165
1206
|
data = {"query": query, "bindVars": bind_vars}
|
|
1166
1207
|
|
|
@@ -1203,14 +1244,15 @@ class Collection(Generic[T, U, V]):
|
|
|
1203
1244
|
raise ValueError("limit parameter must be a non-negative int")
|
|
1204
1245
|
|
|
1205
1246
|
sync = f"waitForSync: {wait_for_sync}" if wait_for_sync is not None else ""
|
|
1247
|
+
filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
|
|
1206
1248
|
query = f"""
|
|
1207
1249
|
FOR doc IN @@collection
|
|
1208
|
-
{
|
|
1250
|
+
{filter_conditions}
|
|
1209
1251
|
{f"LIMIT {limit}" if limit is not None else ""}
|
|
1210
1252
|
REMOVE doc IN @@collection
|
|
1211
1253
|
{f"OPTIONS {{ {sync} }}" if sync else ""}
|
|
1212
1254
|
""" # noqa: E201 E202
|
|
1213
|
-
bind_vars = {"@collection": self.name}
|
|
1255
|
+
bind_vars = {"@collection": self.name, **filter_bind_vars}
|
|
1214
1256
|
data = {"query": query, "bindVars": bind_vars}
|
|
1215
1257
|
|
|
1216
1258
|
request = Request(
|
arangoasync/replication.py
CHANGED
|
@@ -2,6 +2,7 @@ __all__ = ["Replication"]
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
from typing import Optional
|
|
5
|
+
from warnings import warn
|
|
5
6
|
|
|
6
7
|
from arangoasync.exceptions import (
|
|
7
8
|
ReplicationApplierConfigError,
|
|
@@ -195,7 +196,9 @@ class Replication:
|
|
|
195
196
|
return await self._executor.execute(request, response_handler)
|
|
196
197
|
|
|
197
198
|
async def applier_config(self) -> Result[Json]:
|
|
198
|
-
"""
|
|
199
|
+
"""**Removed** in ArangoDB v3.12.10.
|
|
200
|
+
|
|
201
|
+
Return the configuration of the replication applier.
|
|
199
202
|
|
|
200
203
|
Returns:
|
|
201
204
|
dict: Configuration of the replication applier.
|
|
@@ -206,6 +209,9 @@ class Replication:
|
|
|
206
209
|
References:
|
|
207
210
|
- `get-the-replication-applier-configuration <https://docs.arango.ai/arangodb/stable/develop/http-api/replication/replication-applier/#get-the-replication-applier-configuration>`__
|
|
208
211
|
""" # noqa: E501
|
|
212
|
+
m = "/_api/replication/applier-config was removed in ArangoDB v3.12.10."
|
|
213
|
+
warn(m, DeprecationWarning, stacklevel=2)
|
|
214
|
+
|
|
209
215
|
request = Request(
|
|
210
216
|
method=Method.GET,
|
|
211
217
|
endpoint="/_api/replication/applier-config",
|
|
@@ -220,7 +226,9 @@ class Replication:
|
|
|
220
226
|
return await self._executor.execute(request, response_handler)
|
|
221
227
|
|
|
222
228
|
async def applier_state(self) -> Result[Json]:
|
|
223
|
-
"""
|
|
229
|
+
"""**Removed** in ArangoDB v3.12.10.
|
|
230
|
+
|
|
231
|
+
Return the state of the replication applier.
|
|
224
232
|
|
|
225
233
|
Returns:
|
|
226
234
|
dict: State of the replication applier.
|
|
@@ -231,6 +239,9 @@ class Replication:
|
|
|
231
239
|
References:
|
|
232
240
|
- `get-the-replication-applier-state <https://docs.arango.ai/arangodb/stable/develop/http-api/replication/replication-applier/#get-the-replication-applier-state>`__
|
|
233
241
|
""" # noqa: E501
|
|
242
|
+
m = "/_api/replication/applier-state was removed in ArangoDB v3.12.10."
|
|
243
|
+
warn(m, DeprecationWarning, stacklevel=2)
|
|
244
|
+
|
|
234
245
|
request = Request(
|
|
235
246
|
method=Method.GET,
|
|
236
247
|
endpoint="/_api/replication/applier-state",
|
|
@@ -245,7 +256,9 @@ class Replication:
|
|
|
245
256
|
return await self._executor.execute(request, response_handler)
|
|
246
257
|
|
|
247
258
|
async def server_id(self) -> Result[str]:
|
|
248
|
-
"""
|
|
259
|
+
"""**Removed** in ArangoDB v3.12.10.
|
|
260
|
+
|
|
261
|
+
Return the current server's ID.
|
|
249
262
|
|
|
250
263
|
Returns:
|
|
251
264
|
str: Server ID.
|
|
@@ -256,6 +269,9 @@ class Replication:
|
|
|
256
269
|
References:
|
|
257
270
|
- `get-the-replication-server-id <https://docs.arango.ai/arangodb/stable/develop/http-api/replication/other-replication-commands/#get-the-replication-server-id>`__
|
|
258
271
|
""" # noqa: E501
|
|
272
|
+
m = "/_api/replication/server-id was removed in ArangoDB v3.12.10."
|
|
273
|
+
warn(m, DeprecationWarning, stacklevel=2)
|
|
274
|
+
|
|
259
275
|
request = Request(
|
|
260
276
|
method=Method.GET,
|
|
261
277
|
endpoint="/_api/replication/server-id",
|
arangoasync/typings.py
CHANGED
|
@@ -1060,6 +1060,10 @@ class IndexProperties(JsonWrapper):
|
|
|
1060
1060
|
def legacy_polygons(self) -> Optional[bool]:
|
|
1061
1061
|
return self._data.get("legacyPolygons")
|
|
1062
1062
|
|
|
1063
|
+
@property
|
|
1064
|
+
def figures(self) -> Optional[Json]:
|
|
1065
|
+
return self._data.get("figures")
|
|
1066
|
+
|
|
1063
1067
|
@property
|
|
1064
1068
|
def estimates(self) -> Optional[bool]:
|
|
1065
1069
|
return self._data.get("estimates")
|
|
@@ -1140,6 +1144,10 @@ class IndexProperties(JsonWrapper):
|
|
|
1140
1144
|
def training_state(self) -> Optional[str]:
|
|
1141
1145
|
return self._data.get("trainingState")
|
|
1142
1146
|
|
|
1147
|
+
@property
|
|
1148
|
+
def shards(self) -> Optional[Json]:
|
|
1149
|
+
return self._data.get("shards")
|
|
1150
|
+
|
|
1143
1151
|
@staticmethod
|
|
1144
1152
|
def compatibility_formatter(data: Json) -> Json:
|
|
1145
1153
|
"""python-arango compatibility formatter."""
|
|
@@ -1170,6 +1178,8 @@ class IndexProperties(JsonWrapper):
|
|
|
1170
1178
|
result["storedValues"] = data["storedValues"]
|
|
1171
1179
|
if "legacyPolygons" in data:
|
|
1172
1180
|
result["legacyPolygons"] = data["legacyPolygons"]
|
|
1181
|
+
if "figures" in data:
|
|
1182
|
+
result["figures"] = data["figures"]
|
|
1173
1183
|
if "estimates" in data:
|
|
1174
1184
|
result["estimates"] = data["estimates"]
|
|
1175
1185
|
if "analyzer" in data:
|
|
@@ -1202,6 +1212,8 @@ class IndexProperties(JsonWrapper):
|
|
|
1202
1212
|
result["error_message"] = data["errorMessage"]
|
|
1203
1213
|
if "trainingState" in data:
|
|
1204
1214
|
result["training_state"] = data["trainingState"]
|
|
1215
|
+
if "shards" in data:
|
|
1216
|
+
result["shards"] = data["shards"]
|
|
1205
1217
|
return result
|
|
1206
1218
|
|
|
1207
1219
|
def format(self, formatter: Optional[Formatter] = None) -> Json:
|
arangoasync/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "1.2.
|
|
1
|
+
__version__ = "1.2.5"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-arango-async
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.5
|
|
4
4
|
Summary: Async Python Driver for ArangoDB
|
|
5
5
|
Author-email: Alexandru Petenchea <alexandru.petenchea@arangodb.com>, Anthony Mahanna <anthony.mahanna@arangodb.com>
|
|
6
6
|
Maintainer-email: Alexandru Petenchea <alexandru.petenchea@arangodb.com>, Anthony Mahanna <anthony.mahanna@arangodb.com>
|
|
@@ -26,7 +26,7 @@ Requires-Dist: multidict>=6.0
|
|
|
26
26
|
Requires-Dist: pyjwt>=2.10.0
|
|
27
27
|
Provides-Extra: dev
|
|
28
28
|
Requires-Dist: aiofiles>=24.1.0; extra == "dev"
|
|
29
|
-
Requires-Dist: black==26.
|
|
29
|
+
Requires-Dist: black==26.5.1; extra == "dev"
|
|
30
30
|
Requires-Dist: flake8==7.3.0; extra == "dev"
|
|
31
31
|
Requires-Dist: isort>=5.10.1; extra == "dev"
|
|
32
32
|
Requires-Dist: mypy==1.15.0; extra == "dev"
|
|
@@ -4,7 +4,7 @@ arangoasync/auth.py,sha256=16apz1_IvAB_ZSyenoPha6F_JkbHokmOWFHxPL_swxQ,3025
|
|
|
4
4
|
arangoasync/backup.py,sha256=6ZUDjP44bilv056K2fo8l7BnmoeksJ9G9keMVP7i9FI,10577
|
|
5
5
|
arangoasync/client.py,sha256=MKLYXPdDhBezFIKX1H5e7-dKzYnIHwbfN0CO8AEsAzs,10054
|
|
6
6
|
arangoasync/cluster.py,sha256=64GYlpz07wBczeNTrPpxnUd17tFocrhGijGHF_dqdoo,17260
|
|
7
|
-
arangoasync/collection.py,sha256=
|
|
7
|
+
arangoasync/collection.py,sha256=BXpFmCxqzB4qkCMMIJth4abq3ehHh62MEYovIzicFCY,124186
|
|
8
8
|
arangoasync/compression.py,sha256=vMhcg5nQPkbgplk48vxARUnJ6YeIwrCLC6pDCVJSwo0,3804
|
|
9
9
|
arangoasync/connection.py,sha256=f6HQOZHayluNVyH-j-sujlE_dvQrVxC1lPWnzrfQLqY,17459
|
|
10
10
|
arangoasync/cursor.py,sha256=RQJOtNpxEx5n3eKx7UYPl1N8gzWYQESjufvakr18azk,8464
|
|
@@ -17,16 +17,16 @@ arangoasync/graph.py,sha256=G-todTf-ldTQtS2uhCsiigdPL4WABbbfTrLKlIPFkhA,40953
|
|
|
17
17
|
arangoasync/http.py,sha256=xkxnLMbqFBEngmqGCuBOgRuXgQSBUk9-dzYXB1yrL98,6154
|
|
18
18
|
arangoasync/job.py,sha256=B9cPDzxaYflWDj95j941wrcCj4w5j-gnmSzs3TdNdfw,7471
|
|
19
19
|
arangoasync/logger.py,sha256=Ui4n-ELcYM4fujpZV6myU4by82L_70S1cfG0bhEhf-Q,58
|
|
20
|
-
arangoasync/replication.py,sha256=
|
|
20
|
+
arangoasync/replication.py,sha256=nbccH3jg-aiJhi1OgrGObmleP2SJsRSg5IELm2Swddc,10042
|
|
21
21
|
arangoasync/request.py,sha256=z9-MeoSh_6SP6we6VsaTICY7SFo6ZRjWuc1mbZcyN_E,3096
|
|
22
22
|
arangoasync/resolver.py,sha256=icsmQIkklrvq-a88vIR8C-M3rcv5BJxhDE2PK8LenG0,3409
|
|
23
23
|
arangoasync/response.py,sha256=VMnoWgtyrh1JGK7mEgRNsUtSawxWMgFjHT-Cff4d8zc,2132
|
|
24
24
|
arangoasync/result.py,sha256=NVwFxpYUDujHNRCqCZIBOlGLzB7XsiSmjWPFhUgRS6k,233
|
|
25
25
|
arangoasync/serialization.py,sha256=ExRqrEpbk11Hb3AfFUJGqPlGBD3dbvwQg_xsZUsrm6I,2910
|
|
26
|
-
arangoasync/typings.py,sha256=
|
|
27
|
-
arangoasync/version.py,sha256=
|
|
28
|
-
python_arango_async-1.2.
|
|
29
|
-
python_arango_async-1.2.
|
|
30
|
-
python_arango_async-1.2.
|
|
31
|
-
python_arango_async-1.2.
|
|
32
|
-
python_arango_async-1.2.
|
|
26
|
+
arangoasync/typings.py,sha256=LmKV4_jNUoxZ6cI91l8H2XimhYl945ow_3FrcVEoB50,70480
|
|
27
|
+
arangoasync/version.py,sha256=jBmZf3HLbiQlWiolOsAA6J5-BbxXD2bqFqEqDH3lfqo,22
|
|
28
|
+
python_arango_async-1.2.5.dist-info/licenses/LICENSE,sha256=6zoGhJon2tcnvzmycirNjLNBZ6rlLJtYDdVGO76RXVM,1065
|
|
29
|
+
python_arango_async-1.2.5.dist-info/METADATA,sha256=8dPPxISrFp18gU9zhZsuvdpW-OQreOptVKoJlrFZ62Y,7943
|
|
30
|
+
python_arango_async-1.2.5.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
31
|
+
python_arango_async-1.2.5.dist-info/top_level.txt,sha256=uabwJ6t-MiIaZQXGUvYikeSbZDcF0RK37GzikBnDz5k,12
|
|
32
|
+
python_arango_async-1.2.5.dist-info/RECORD,,
|
{python_arango_async-1.2.3.dist-info → python_arango_async-1.2.5.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|