python-arango-async 0.0.1__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/__init__.py +5 -0
- arangoasync/aql.py +760 -0
- arangoasync/auth.py +121 -0
- arangoasync/client.py +239 -0
- arangoasync/collection.py +1688 -0
- arangoasync/compression.py +139 -0
- arangoasync/connection.py +515 -0
- arangoasync/cursor.py +262 -0
- arangoasync/database.py +1533 -0
- arangoasync/errno.py +1168 -0
- arangoasync/exceptions.py +379 -0
- arangoasync/executor.py +168 -0
- arangoasync/http.py +182 -0
- arangoasync/job.py +214 -0
- arangoasync/logger.py +3 -0
- arangoasync/request.py +107 -0
- arangoasync/resolver.py +119 -0
- arangoasync/response.py +65 -0
- arangoasync/result.py +9 -0
- arangoasync/serialization.py +111 -0
- arangoasync/typings.py +1646 -0
- arangoasync/version.py +1 -0
- python_arango_async-0.0.1.dist-info/METADATA +142 -0
- python_arango_async-0.0.1.dist-info/RECORD +27 -0
- python_arango_async-0.0.1.dist-info/WHEEL +5 -0
- python_arango_async-0.0.1.dist-info/licenses/LICENSE +21 -0
- python_arango_async-0.0.1.dist-info/top_level.txt +1 -0
arangoasync/aql.py
ADDED
|
@@ -0,0 +1,760 @@
|
|
|
1
|
+
__all__ = ["AQL", "AQLQueryCache"]
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from typing import Optional, cast
|
|
5
|
+
|
|
6
|
+
from arangoasync.cursor import Cursor
|
|
7
|
+
from arangoasync.errno import HTTP_NOT_FOUND
|
|
8
|
+
from arangoasync.exceptions import (
|
|
9
|
+
AQLCacheClearError,
|
|
10
|
+
AQLCacheConfigureError,
|
|
11
|
+
AQLCacheEntriesError,
|
|
12
|
+
AQLCachePropertiesError,
|
|
13
|
+
AQLFunctionCreateError,
|
|
14
|
+
AQLFunctionDeleteError,
|
|
15
|
+
AQLFunctionListError,
|
|
16
|
+
AQLQueryClearError,
|
|
17
|
+
AQLQueryExecuteError,
|
|
18
|
+
AQLQueryExplainError,
|
|
19
|
+
AQLQueryKillError,
|
|
20
|
+
AQLQueryListError,
|
|
21
|
+
AQLQueryRulesGetError,
|
|
22
|
+
AQLQueryTrackingGetError,
|
|
23
|
+
AQLQueryTrackingSetError,
|
|
24
|
+
AQLQueryValidateError,
|
|
25
|
+
)
|
|
26
|
+
from arangoasync.executor import ApiExecutor, DefaultApiExecutor, NonAsyncExecutor
|
|
27
|
+
from arangoasync.request import Method, Request
|
|
28
|
+
from arangoasync.response import Response
|
|
29
|
+
from arangoasync.result import Result
|
|
30
|
+
from arangoasync.serialization import Deserializer, Serializer
|
|
31
|
+
from arangoasync.typings import (
|
|
32
|
+
Json,
|
|
33
|
+
Jsons,
|
|
34
|
+
QueryCacheProperties,
|
|
35
|
+
QueryExplainOptions,
|
|
36
|
+
QueryProperties,
|
|
37
|
+
QueryTrackingConfiguration,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AQLQueryCache:
|
|
42
|
+
"""AQL Query Cache API wrapper.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
executor: API executor. Required to execute the API requests.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __init__(self, executor: ApiExecutor) -> None:
|
|
49
|
+
self._executor = executor
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def name(self) -> str:
|
|
53
|
+
"""Return the name of the current database."""
|
|
54
|
+
return self._executor.db_name
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def serializer(self) -> Serializer[Json]:
|
|
58
|
+
"""Return the serializer."""
|
|
59
|
+
return self._executor.serializer
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def deserializer(self) -> Deserializer[Json, Jsons]:
|
|
63
|
+
"""Return the deserializer."""
|
|
64
|
+
return self._executor.deserializer
|
|
65
|
+
|
|
66
|
+
def __repr__(self) -> str:
|
|
67
|
+
return f"<AQLQueryCache in {self.name}>"
|
|
68
|
+
|
|
69
|
+
async def entries(self) -> Result[Jsons]:
|
|
70
|
+
"""Return a list of all AQL query results cache entries.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
list: List of AQL query results cache entries.
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
AQLCacheEntriesError: If retrieval fails.
|
|
78
|
+
|
|
79
|
+
References:
|
|
80
|
+
- `list-the-entries-of-the-aql-query-results-cache <https://docs.arangodb.com/stable/develop/http-api/queries/aql-query-results-cache/#list-the-entries-of-the-aql-query-results-cache>`__
|
|
81
|
+
""" # noqa: E501
|
|
82
|
+
request = Request(method=Method.GET, endpoint="/_api/query-cache/entries")
|
|
83
|
+
|
|
84
|
+
def response_handler(resp: Response) -> Jsons:
|
|
85
|
+
if not resp.is_success:
|
|
86
|
+
raise AQLCacheEntriesError(resp, request)
|
|
87
|
+
return self.deserializer.loads_many(resp.raw_body)
|
|
88
|
+
|
|
89
|
+
return await self._executor.execute(request, response_handler)
|
|
90
|
+
|
|
91
|
+
async def plan_entries(self) -> Result[Jsons]:
|
|
92
|
+
"""Return a list of all AQL query plan cache entries.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
list: List of AQL query plan cache entries.
|
|
96
|
+
|
|
97
|
+
Raises:
|
|
98
|
+
AQLCacheEntriesError: If retrieval fails.
|
|
99
|
+
|
|
100
|
+
References:
|
|
101
|
+
- `list-the-entries-of-the-aql-query-plan-cache <https://docs.arangodb.com/stable/develop/http-api/queries/aql-query-plan-cache/#list-the-entries-of-the-aql-query-plan-cache>`__
|
|
102
|
+
""" # noqa: E501
|
|
103
|
+
request = Request(method=Method.GET, endpoint="/_api/query-plan-cache")
|
|
104
|
+
|
|
105
|
+
def response_handler(resp: Response) -> Jsons:
|
|
106
|
+
if not resp.is_success:
|
|
107
|
+
raise AQLCacheEntriesError(resp, request)
|
|
108
|
+
return self.deserializer.loads_many(resp.raw_body)
|
|
109
|
+
|
|
110
|
+
return await self._executor.execute(request, response_handler)
|
|
111
|
+
|
|
112
|
+
async def clear(self) -> Result[None]:
|
|
113
|
+
"""Clear the AQL query results cache.
|
|
114
|
+
|
|
115
|
+
Raises:
|
|
116
|
+
AQLCacheClearError: If clearing the cache fails.
|
|
117
|
+
|
|
118
|
+
References:
|
|
119
|
+
- `clear-the-aql-query-results-cache <https://docs.arangodb.com/stable/develop/http-api/queries/aql-query-results-cache/#clear-the-aql-query-results-cache>`__
|
|
120
|
+
""" # noqa: E501
|
|
121
|
+
request = Request(method=Method.DELETE, endpoint="/_api/query-cache")
|
|
122
|
+
|
|
123
|
+
def response_handler(resp: Response) -> None:
|
|
124
|
+
if not resp.is_success:
|
|
125
|
+
raise AQLCacheClearError(resp, request)
|
|
126
|
+
|
|
127
|
+
return await self._executor.execute(request, response_handler)
|
|
128
|
+
|
|
129
|
+
async def clear_plan(self) -> Result[None]:
|
|
130
|
+
"""Clear the AQL query plan cache.
|
|
131
|
+
|
|
132
|
+
Raises:
|
|
133
|
+
AQLCacheClearError: If clearing the cache fails.
|
|
134
|
+
|
|
135
|
+
References:
|
|
136
|
+
- `clear-the-aql-query-plan-cache <https://docs.arangodb.com/stable/develop/http-api/queries/aql-query-plan-cache/#clear-the-aql-query-plan-cache>`__
|
|
137
|
+
""" # noqa: E501
|
|
138
|
+
request = Request(method=Method.DELETE, endpoint="/_api/query-plan-cache")
|
|
139
|
+
|
|
140
|
+
def response_handler(resp: Response) -> None:
|
|
141
|
+
if not resp.is_success:
|
|
142
|
+
raise AQLCacheClearError(resp, request)
|
|
143
|
+
|
|
144
|
+
return await self._executor.execute(request, response_handler)
|
|
145
|
+
|
|
146
|
+
async def properties(self) -> Result[QueryCacheProperties]:
|
|
147
|
+
"""Return the current AQL query results cache configuration.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
QueryCacheProperties: Current AQL query cache properties.
|
|
151
|
+
|
|
152
|
+
Raises:
|
|
153
|
+
AQLCachePropertiesError: If retrieval fails.
|
|
154
|
+
|
|
155
|
+
References:
|
|
156
|
+
- `get-the-aql-query-results-cache-configuration <https://docs.arangodb.com/stable/develop/http-api/queries/aql-query-results-cache/#get-the-aql-query-results-cache-configuration>`__
|
|
157
|
+
""" # noqa: E501
|
|
158
|
+
request = Request(method=Method.GET, endpoint="/_api/query-cache/properties")
|
|
159
|
+
|
|
160
|
+
def response_handler(resp: Response) -> QueryCacheProperties:
|
|
161
|
+
if not resp.is_success:
|
|
162
|
+
raise AQLCachePropertiesError(resp, request)
|
|
163
|
+
return QueryCacheProperties(self.deserializer.loads(resp.raw_body))
|
|
164
|
+
|
|
165
|
+
return await self._executor.execute(request, response_handler)
|
|
166
|
+
|
|
167
|
+
async def configure(
|
|
168
|
+
self,
|
|
169
|
+
mode: Optional[str] = None,
|
|
170
|
+
max_results: Optional[int] = None,
|
|
171
|
+
max_results_size: Optional[int] = None,
|
|
172
|
+
max_entry_size: Optional[int] = None,
|
|
173
|
+
include_system: Optional[bool] = None,
|
|
174
|
+
) -> Result[QueryCacheProperties]:
|
|
175
|
+
"""Configure the AQL query results cache.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
mode (str | None): Cache mode. Allowed values are `"off"`, `"on"`,
|
|
179
|
+
and `"demand"`.
|
|
180
|
+
max_results (int | None): Max number of query results stored per
|
|
181
|
+
database-specific cache.
|
|
182
|
+
max_results_size (int | None): Max cumulative size of query results stored
|
|
183
|
+
per database-specific cache.
|
|
184
|
+
max_entry_size (int | None): Max entry size of each query result stored per
|
|
185
|
+
database-specific cache.
|
|
186
|
+
include_system (bool | None): Store results of queries in system collections.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
QueryCacheProperties: Updated AQL query cache properties.
|
|
190
|
+
|
|
191
|
+
Raises:
|
|
192
|
+
AQLCacheConfigureError: If setting the configuration fails.
|
|
193
|
+
|
|
194
|
+
References:
|
|
195
|
+
- `set-the-aql-query-results-cache-configuration <https://docs.arangodb.com/stable/develop/http-api/queries/aql-query-results-cache/#set-the-aql-query-results-cache-configuration>`__
|
|
196
|
+
""" # noqa: E501
|
|
197
|
+
data: Json = dict()
|
|
198
|
+
if mode is not None:
|
|
199
|
+
data["mode"] = mode
|
|
200
|
+
if max_results is not None:
|
|
201
|
+
data["maxResults"] = max_results
|
|
202
|
+
if max_results_size is not None:
|
|
203
|
+
data["maxResultsSize"] = max_results_size
|
|
204
|
+
if max_entry_size is not None:
|
|
205
|
+
data["maxEntrySize"] = max_entry_size
|
|
206
|
+
if include_system is not None:
|
|
207
|
+
data["includeSystem"] = include_system
|
|
208
|
+
|
|
209
|
+
request = Request(
|
|
210
|
+
method=Method.PUT,
|
|
211
|
+
endpoint="/_api/query-cache/properties",
|
|
212
|
+
data=self.serializer.dumps(data),
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
def response_handler(resp: Response) -> QueryCacheProperties:
|
|
216
|
+
if not resp.is_success:
|
|
217
|
+
raise AQLCacheConfigureError(resp, request)
|
|
218
|
+
return QueryCacheProperties(self.deserializer.loads(resp.raw_body))
|
|
219
|
+
|
|
220
|
+
return await self._executor.execute(request, response_handler)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class AQL:
|
|
224
|
+
"""AQL (ArangoDB Query Language) API wrapper.
|
|
225
|
+
|
|
226
|
+
Allows you to execute, track, kill, explain, and validate queries written
|
|
227
|
+
in ArangoDB’s query language.
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
executor: API executor. Required to execute the API requests.
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
def __init__(self, executor: ApiExecutor) -> None:
|
|
234
|
+
self._executor = executor
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def name(self) -> str:
|
|
238
|
+
"""Return the name of the current database."""
|
|
239
|
+
return self._executor.db_name
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def serializer(self) -> Serializer[Json]:
|
|
243
|
+
"""Return the serializer."""
|
|
244
|
+
return self._executor.serializer
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def deserializer(self) -> Deserializer[Json, Jsons]:
|
|
248
|
+
"""Return the deserializer."""
|
|
249
|
+
return self._executor.deserializer
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def cache(self) -> AQLQueryCache:
|
|
253
|
+
"""Return the AQL Query Cache API wrapper."""
|
|
254
|
+
return AQLQueryCache(self._executor)
|
|
255
|
+
|
|
256
|
+
def __repr__(self) -> str:
|
|
257
|
+
return f"<AQL in {self.name}>"
|
|
258
|
+
|
|
259
|
+
async def execute(
|
|
260
|
+
self,
|
|
261
|
+
query: str,
|
|
262
|
+
count: Optional[bool] = None,
|
|
263
|
+
batch_size: Optional[int] = None,
|
|
264
|
+
bind_vars: Optional[Json] = None,
|
|
265
|
+
cache: Optional[bool] = None,
|
|
266
|
+
memory_limit: Optional[int] = None,
|
|
267
|
+
ttl: Optional[int] = None,
|
|
268
|
+
allow_dirty_read: Optional[bool] = None,
|
|
269
|
+
options: Optional[QueryProperties | Json] = None,
|
|
270
|
+
) -> Result[Cursor]:
|
|
271
|
+
"""Execute the query and return the result cursor.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
query (str): Query string to be executed.
|
|
275
|
+
count (bool | None): If set to `True`, the total document count is
|
|
276
|
+
calculated and included in the result cursor.
|
|
277
|
+
batch_size (int | None): Maximum number of result documents to be
|
|
278
|
+
transferred from the server to the client in one roundtrip.
|
|
279
|
+
bind_vars (dict | None): An object with key/value pairs representing
|
|
280
|
+
the bind parameters.
|
|
281
|
+
cache (bool | None): Flag to determine whether the AQL query results
|
|
282
|
+
cache shall be used.
|
|
283
|
+
memory_limit (int | None): Maximum memory (in bytes) that the query is
|
|
284
|
+
allowed to use.
|
|
285
|
+
ttl (int | None): The time-to-live for the cursor (in seconds). The cursor
|
|
286
|
+
will be removed on the server automatically after the specified amount
|
|
287
|
+
of time.
|
|
288
|
+
allow_dirty_read (bool | None): Allow reads from followers in a cluster.
|
|
289
|
+
options (QueryProperties | dict | None): Extra options for the query.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
Cursor: Result cursor.
|
|
293
|
+
|
|
294
|
+
References:
|
|
295
|
+
- `create-a-cursor <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#create-a-cursor>`__
|
|
296
|
+
""" # noqa: E501
|
|
297
|
+
data: Json = dict(query=query)
|
|
298
|
+
if count is not None:
|
|
299
|
+
data["count"] = count
|
|
300
|
+
if batch_size is not None:
|
|
301
|
+
data["batchSize"] = batch_size
|
|
302
|
+
if bind_vars is not None:
|
|
303
|
+
data["bindVars"] = bind_vars
|
|
304
|
+
if cache is not None:
|
|
305
|
+
data["cache"] = cache
|
|
306
|
+
if memory_limit is not None:
|
|
307
|
+
data["memoryLimit"] = memory_limit
|
|
308
|
+
if ttl is not None:
|
|
309
|
+
data["ttl"] = ttl
|
|
310
|
+
if options is not None:
|
|
311
|
+
if isinstance(options, QueryProperties):
|
|
312
|
+
options = options.to_dict()
|
|
313
|
+
data["options"] = options
|
|
314
|
+
|
|
315
|
+
headers = dict()
|
|
316
|
+
if allow_dirty_read is not None:
|
|
317
|
+
headers["x-arango-allow-dirty-read"] = str(allow_dirty_read).lower()
|
|
318
|
+
|
|
319
|
+
request = Request(
|
|
320
|
+
method=Method.POST,
|
|
321
|
+
endpoint="/_api/cursor",
|
|
322
|
+
data=self.serializer.dumps(data),
|
|
323
|
+
headers=headers,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
def response_handler(resp: Response) -> Cursor:
|
|
327
|
+
if not resp.is_success:
|
|
328
|
+
raise AQLQueryExecuteError(resp, request)
|
|
329
|
+
if self._executor.context == "async":
|
|
330
|
+
# We cannot have a cursor giving back async jobs
|
|
331
|
+
executor: NonAsyncExecutor = DefaultApiExecutor(
|
|
332
|
+
self._executor.connection
|
|
333
|
+
)
|
|
334
|
+
else:
|
|
335
|
+
executor = cast(NonAsyncExecutor, self._executor)
|
|
336
|
+
return Cursor(executor, self.deserializer.loads(resp.raw_body))
|
|
337
|
+
|
|
338
|
+
return await self._executor.execute(request, response_handler)
|
|
339
|
+
|
|
340
|
+
async def tracking(self) -> Result[QueryTrackingConfiguration]:
|
|
341
|
+
"""Returns the current query tracking configuration.
|
|
342
|
+
|
|
343
|
+
Returns:
|
|
344
|
+
QueryTrackingConfiguration: Returns the current query tracking configuration.
|
|
345
|
+
|
|
346
|
+
Raises:
|
|
347
|
+
AQLQueryTrackingGetError: If retrieval fails.
|
|
348
|
+
|
|
349
|
+
References:
|
|
350
|
+
- `get-the-aql-query-tracking-configuration <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#get-the-aql-query-tracking-configuration>`__
|
|
351
|
+
""" # noqa: E501
|
|
352
|
+
request = Request(method=Method.GET, endpoint="/_api/query/properties")
|
|
353
|
+
|
|
354
|
+
def response_handler(resp: Response) -> QueryTrackingConfiguration:
|
|
355
|
+
if not resp.is_success:
|
|
356
|
+
raise AQLQueryTrackingGetError(resp, request)
|
|
357
|
+
return QueryTrackingConfiguration(self.deserializer.loads(resp.raw_body))
|
|
358
|
+
|
|
359
|
+
return await self._executor.execute(request, response_handler)
|
|
360
|
+
|
|
361
|
+
async def set_tracking(
|
|
362
|
+
self,
|
|
363
|
+
enabled: Optional[bool] = None,
|
|
364
|
+
max_slow_queries: Optional[int] = None,
|
|
365
|
+
slow_query_threshold: Optional[int] = None,
|
|
366
|
+
max_query_string_length: Optional[int] = None,
|
|
367
|
+
track_bind_vars: Optional[bool] = None,
|
|
368
|
+
track_slow_queries: Optional[int] = None,
|
|
369
|
+
) -> Result[QueryTrackingConfiguration]:
|
|
370
|
+
"""Configure AQL query tracking properties.
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
enabled (bool | None): If set to `True`, then queries will be tracked.
|
|
374
|
+
If set to `False`, neither queries nor slow queries will be tracked.
|
|
375
|
+
max_slow_queries (int | None): Maximum number of slow queries to track. Oldest
|
|
376
|
+
entries are discarded first.
|
|
377
|
+
slow_query_threshold (int | None): Runtime threshold (in seconds) for treating a
|
|
378
|
+
query as slow.
|
|
379
|
+
max_query_string_length (int | None): The maximum query string length (in bytes)
|
|
380
|
+
to keep in the list of queries.
|
|
381
|
+
track_bind_vars (bool | None): If set to `True`, track bind variables used in
|
|
382
|
+
queries.
|
|
383
|
+
track_slow_queries (int | None): If set to `True`, then slow queries will be
|
|
384
|
+
tracked in the list of slow queries if their runtime exceeds the
|
|
385
|
+
value set in `slowQueryThreshold`.
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
QueryTrackingConfiguration: Returns the updated query tracking configuration.
|
|
389
|
+
|
|
390
|
+
Raises:
|
|
391
|
+
AQLQueryTrackingSetError: If setting the configuration fails.
|
|
392
|
+
|
|
393
|
+
References:
|
|
394
|
+
- `update-the-aql-query-tracking-configuration <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#update-the-aql-query-tracking-configuration>`__
|
|
395
|
+
""" # noqa: E501
|
|
396
|
+
data: Json = dict()
|
|
397
|
+
|
|
398
|
+
if enabled is not None:
|
|
399
|
+
data["enabled"] = enabled
|
|
400
|
+
if max_slow_queries is not None:
|
|
401
|
+
data["maxSlowQueries"] = max_slow_queries
|
|
402
|
+
if max_query_string_length is not None:
|
|
403
|
+
data["maxQueryStringLength"] = max_query_string_length
|
|
404
|
+
if slow_query_threshold is not None:
|
|
405
|
+
data["slowQueryThreshold"] = slow_query_threshold
|
|
406
|
+
if track_bind_vars is not None:
|
|
407
|
+
data["trackBindVars"] = track_bind_vars
|
|
408
|
+
if track_slow_queries is not None:
|
|
409
|
+
data["trackSlowQueries"] = track_slow_queries
|
|
410
|
+
|
|
411
|
+
request = Request(
|
|
412
|
+
method=Method.PUT,
|
|
413
|
+
endpoint="/_api/query/properties",
|
|
414
|
+
data=self.serializer.dumps(data),
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
def response_handler(resp: Response) -> QueryTrackingConfiguration:
|
|
418
|
+
if not resp.is_success:
|
|
419
|
+
raise AQLQueryTrackingSetError(resp, request)
|
|
420
|
+
return QueryTrackingConfiguration(self.deserializer.loads(resp.raw_body))
|
|
421
|
+
|
|
422
|
+
return await self._executor.execute(request, response_handler)
|
|
423
|
+
|
|
424
|
+
async def queries(self, all_queries: bool = False) -> Result[Jsons]:
|
|
425
|
+
"""Return a list of currently running queries.
|
|
426
|
+
|
|
427
|
+
Args:
|
|
428
|
+
all_queries (bool): If set to `True`, will return the currently
|
|
429
|
+
running queries in all databases, not just the selected one.
|
|
430
|
+
Using the parameter is only allowed in the `_system` database
|
|
431
|
+
and with superuser privileges.
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
list: List of currently running queries and their properties.
|
|
435
|
+
|
|
436
|
+
Raises:
|
|
437
|
+
AQLQueryListError: If retrieval fails.
|
|
438
|
+
|
|
439
|
+
References:
|
|
440
|
+
- `list-the-running-queries <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#list-the-running-queries>`__
|
|
441
|
+
""" # noqa: E501
|
|
442
|
+
request = Request(
|
|
443
|
+
method=Method.GET,
|
|
444
|
+
endpoint="/_api/query/current",
|
|
445
|
+
params={"all": all_queries},
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
def response_handler(resp: Response) -> Jsons:
|
|
449
|
+
if not resp.is_success:
|
|
450
|
+
raise AQLQueryListError(resp, request)
|
|
451
|
+
return self.deserializer.loads_many(resp.raw_body)
|
|
452
|
+
|
|
453
|
+
return await self._executor.execute(request, response_handler)
|
|
454
|
+
|
|
455
|
+
async def slow_queries(self, all_queries: bool = False) -> Result[Jsons]:
|
|
456
|
+
"""Returns a list containing the last AQL queries that are finished and
|
|
457
|
+
have exceeded the slow query threshold in the selected database.
|
|
458
|
+
|
|
459
|
+
Args:
|
|
460
|
+
all_queries (bool): If set to `True`, will return the slow queries
|
|
461
|
+
in all databases, not just the selected one. Using the parameter
|
|
462
|
+
is only allowed in the `_system` database and with superuser privileges.
|
|
463
|
+
|
|
464
|
+
Returns:
|
|
465
|
+
list: List of slow queries.
|
|
466
|
+
|
|
467
|
+
Raises:
|
|
468
|
+
AQLQueryListError: If retrieval fails.
|
|
469
|
+
|
|
470
|
+
References:
|
|
471
|
+
- `list-the-slow-aql-queries <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#list-the-slow-aql-queries>`__
|
|
472
|
+
""" # noqa: E501
|
|
473
|
+
request = Request(
|
|
474
|
+
method=Method.GET,
|
|
475
|
+
endpoint="/_api/query/slow",
|
|
476
|
+
params={"all": all_queries},
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
def response_handler(resp: Response) -> Jsons:
|
|
480
|
+
if not resp.is_success:
|
|
481
|
+
raise AQLQueryListError(resp, request)
|
|
482
|
+
return self.deserializer.loads_many(resp.raw_body)
|
|
483
|
+
|
|
484
|
+
return await self._executor.execute(request, response_handler)
|
|
485
|
+
|
|
486
|
+
async def clear_slow_queries(self, all_queries: bool = False) -> Result[None]:
|
|
487
|
+
"""Clears the list of slow queries.
|
|
488
|
+
|
|
489
|
+
Args:
|
|
490
|
+
all_queries (bool): If set to `True`, will clear the slow queries
|
|
491
|
+
in all databases, not just the selected one. Using the parameter
|
|
492
|
+
is only allowed in the `_system` database and with superuser privileges.
|
|
493
|
+
|
|
494
|
+
Returns:
|
|
495
|
+
dict: Empty dictionary.
|
|
496
|
+
|
|
497
|
+
Raises:
|
|
498
|
+
AQLQueryClearError: If retrieval fails.
|
|
499
|
+
|
|
500
|
+
References:
|
|
501
|
+
- `clear-the-list-of-slow-aql-queries <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#clear-the-list-of-slow-aql-queries>`__
|
|
502
|
+
""" # noqa: E501
|
|
503
|
+
request = Request(
|
|
504
|
+
method=Method.DELETE,
|
|
505
|
+
endpoint="/_api/query/slow",
|
|
506
|
+
params={"all": all_queries},
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
def response_handler(resp: Response) -> None:
|
|
510
|
+
if not resp.is_success:
|
|
511
|
+
raise AQLQueryClearError(resp, request)
|
|
512
|
+
|
|
513
|
+
return await self._executor.execute(request, response_handler)
|
|
514
|
+
|
|
515
|
+
async def kill(
|
|
516
|
+
self,
|
|
517
|
+
query_id: str,
|
|
518
|
+
ignore_missing: bool = False,
|
|
519
|
+
all_queries: bool = False,
|
|
520
|
+
) -> Result[bool]:
|
|
521
|
+
"""Kill a running query.
|
|
522
|
+
|
|
523
|
+
Args:
|
|
524
|
+
query_id (str): Thea ID of the query to kill.
|
|
525
|
+
ignore_missing (bool): If set to `True`, will not raise an exception
|
|
526
|
+
if the query is not found.
|
|
527
|
+
all_queries (bool): If set to `True`, will kill the query in all databases,
|
|
528
|
+
not just the selected one. Using the parameter is only allowed in the
|
|
529
|
+
`_system` database and with superuser privileges.
|
|
530
|
+
|
|
531
|
+
Returns:
|
|
532
|
+
bool: `True` if the query was killed successfully.
|
|
533
|
+
|
|
534
|
+
Raises:
|
|
535
|
+
AQLQueryKillError: If killing the query fails.
|
|
536
|
+
|
|
537
|
+
References:
|
|
538
|
+
- `kill-a-running-aql-query <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#kill-a-running-aql-query>`__
|
|
539
|
+
""" # noqa: E501
|
|
540
|
+
request = Request(
|
|
541
|
+
method=Method.DELETE,
|
|
542
|
+
endpoint=f"/_api/query/{query_id}",
|
|
543
|
+
params={"all": all_queries},
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
def response_handler(resp: Response) -> bool:
|
|
547
|
+
if resp.is_success:
|
|
548
|
+
return True
|
|
549
|
+
if resp.status_code == HTTP_NOT_FOUND and ignore_missing:
|
|
550
|
+
return False
|
|
551
|
+
raise AQLQueryKillError(resp, request)
|
|
552
|
+
|
|
553
|
+
return await self._executor.execute(request, response_handler)
|
|
554
|
+
|
|
555
|
+
async def explain(
|
|
556
|
+
self,
|
|
557
|
+
query: str,
|
|
558
|
+
bind_vars: Optional[Json] = None,
|
|
559
|
+
options: Optional[QueryExplainOptions | Json] = None,
|
|
560
|
+
) -> Result[Json]:
|
|
561
|
+
"""Inspect the query and return its metadata without executing it.
|
|
562
|
+
|
|
563
|
+
Args:
|
|
564
|
+
query (str): Query string to be explained.
|
|
565
|
+
bind_vars (dict | None): An object with key/value pairs representing
|
|
566
|
+
the bind parameters.
|
|
567
|
+
options (QueryExplainOptions | dict | None): Extra options for the query.
|
|
568
|
+
|
|
569
|
+
Returns:
|
|
570
|
+
dict: Query execution plan.
|
|
571
|
+
|
|
572
|
+
Raises:
|
|
573
|
+
AQLQueryExplainError: If retrieval fails.
|
|
574
|
+
|
|
575
|
+
References:
|
|
576
|
+
- `explain-an-aql-query <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#explain-an-aql-query>`__
|
|
577
|
+
""" # noqa: E501
|
|
578
|
+
data: Json = dict(query=query)
|
|
579
|
+
if bind_vars is not None:
|
|
580
|
+
data["bindVars"] = bind_vars
|
|
581
|
+
if options is not None:
|
|
582
|
+
if isinstance(options, QueryExplainOptions):
|
|
583
|
+
options = options.to_dict()
|
|
584
|
+
data["options"] = options
|
|
585
|
+
|
|
586
|
+
request = Request(
|
|
587
|
+
method=Method.POST,
|
|
588
|
+
endpoint="/_api/explain",
|
|
589
|
+
data=self.serializer.dumps(data),
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
def response_handler(resp: Response) -> Json:
|
|
593
|
+
if not resp.is_success:
|
|
594
|
+
raise AQLQueryExplainError(resp, request)
|
|
595
|
+
return self.deserializer.loads(resp.raw_body)
|
|
596
|
+
|
|
597
|
+
return await self._executor.execute(request, response_handler)
|
|
598
|
+
|
|
599
|
+
async def validate(self, query: str) -> Result[Json]:
|
|
600
|
+
"""Parse and validate the query without executing it.
|
|
601
|
+
|
|
602
|
+
Args:
|
|
603
|
+
query (str): Query string to be validated.
|
|
604
|
+
|
|
605
|
+
Returns:
|
|
606
|
+
dict: Query information.
|
|
607
|
+
|
|
608
|
+
Raises:
|
|
609
|
+
AQLQueryValidateError: If validation fails.
|
|
610
|
+
|
|
611
|
+
References:
|
|
612
|
+
- `parse-an-aql-query <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#parse-an-aql-query>`__
|
|
613
|
+
""" # noqa: E501
|
|
614
|
+
request = Request(
|
|
615
|
+
method=Method.POST,
|
|
616
|
+
endpoint="/_api/query",
|
|
617
|
+
data=self.serializer.dumps(dict(query=query)),
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
def response_handler(resp: Response) -> Json:
|
|
621
|
+
if not resp.is_success:
|
|
622
|
+
raise AQLQueryValidateError(resp, request)
|
|
623
|
+
return self.deserializer.loads(resp.raw_body)
|
|
624
|
+
|
|
625
|
+
return await self._executor.execute(request, response_handler)
|
|
626
|
+
|
|
627
|
+
async def query_rules(self) -> Result[Jsons]:
|
|
628
|
+
"""A list of all optimizer rules and their properties.
|
|
629
|
+
|
|
630
|
+
Returns:
|
|
631
|
+
list: Available optimizer rules.
|
|
632
|
+
|
|
633
|
+
Raises:
|
|
634
|
+
AQLQueryRulesGetError: If retrieval fails.
|
|
635
|
+
|
|
636
|
+
References:
|
|
637
|
+
- `list-all-aql-optimizer-rules <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#list-all-aql-optimizer-rules>`__
|
|
638
|
+
""" # noqa: E501
|
|
639
|
+
request = Request(method=Method.GET, endpoint="/_api/query/rules")
|
|
640
|
+
|
|
641
|
+
def response_handler(resp: Response) -> Jsons:
|
|
642
|
+
if not resp.is_success:
|
|
643
|
+
raise AQLQueryRulesGetError(resp, request)
|
|
644
|
+
return self.deserializer.loads_many(resp.raw_body)
|
|
645
|
+
|
|
646
|
+
return await self._executor.execute(request, response_handler)
|
|
647
|
+
|
|
648
|
+
async def functions(self, namespace: Optional[str] = None) -> Result[Jsons]:
|
|
649
|
+
"""List the registered used-defined AQL functions.
|
|
650
|
+
|
|
651
|
+
Args:
|
|
652
|
+
namespace (str | None): Returns all registered AQL user functions from
|
|
653
|
+
the specified namespace.
|
|
654
|
+
|
|
655
|
+
Returns:
|
|
656
|
+
list: List of the AQL functions defined in the database.
|
|
657
|
+
|
|
658
|
+
Raises:
|
|
659
|
+
AQLFunctionListError: If retrieval fails.
|
|
660
|
+
|
|
661
|
+
References:
|
|
662
|
+
- `list-the-registered-user-defined-aql-functions <https://docs.arangodb.com/stable/develop/http-api/queries/user-defined-aql-functions/#list-the-registered-user-defined-aql-functions>`__
|
|
663
|
+
""" # noqa: E501
|
|
664
|
+
params: Json = dict()
|
|
665
|
+
if namespace is not None:
|
|
666
|
+
params["namespace"] = namespace
|
|
667
|
+
request = Request(
|
|
668
|
+
method=Method.GET,
|
|
669
|
+
endpoint="/_api/aqlfunction",
|
|
670
|
+
params=params,
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
def response_handler(resp: Response) -> Jsons:
|
|
674
|
+
if not resp.is_success:
|
|
675
|
+
raise AQLFunctionListError(resp, request)
|
|
676
|
+
result = cast(Jsons, self.deserializer.loads(resp.raw_body).get("result"))
|
|
677
|
+
if result is None:
|
|
678
|
+
raise AQLFunctionListError(resp, request)
|
|
679
|
+
return result
|
|
680
|
+
|
|
681
|
+
return await self._executor.execute(request, response_handler)
|
|
682
|
+
|
|
683
|
+
async def create_function(
|
|
684
|
+
self,
|
|
685
|
+
name: str,
|
|
686
|
+
code: str,
|
|
687
|
+
is_deterministic: Optional[bool] = None,
|
|
688
|
+
) -> Result[Json]:
|
|
689
|
+
"""Registers a user-defined AQL function (UDF) written in JavaScript.
|
|
690
|
+
|
|
691
|
+
Args:
|
|
692
|
+
name (str): Name of the function.
|
|
693
|
+
code (str): JavaScript code of the function.
|
|
694
|
+
is_deterministic (bool | None): If set to `True`, the function is
|
|
695
|
+
deterministic.
|
|
696
|
+
|
|
697
|
+
Returns:
|
|
698
|
+
dict: Information about the registered function.
|
|
699
|
+
|
|
700
|
+
Raises:
|
|
701
|
+
AQLFunctionCreateError: If registration fails.
|
|
702
|
+
|
|
703
|
+
References:
|
|
704
|
+
- `create-a-user-defined-aql-function <https://docs.arangodb.com/stable/develop/http-api/queries/user-defined-aql-functions/#create-a-user-defined-aql-function>`__
|
|
705
|
+
""" # noqa: E501
|
|
706
|
+
request = Request(
|
|
707
|
+
method=Method.POST,
|
|
708
|
+
endpoint="/_api/aqlfunction",
|
|
709
|
+
data=self.serializer.dumps(
|
|
710
|
+
dict(name=name, code=code, isDeterministic=is_deterministic)
|
|
711
|
+
),
|
|
712
|
+
)
|
|
713
|
+
|
|
714
|
+
def response_handler(resp: Response) -> Json:
|
|
715
|
+
if not resp.is_success:
|
|
716
|
+
raise AQLFunctionCreateError(resp, request)
|
|
717
|
+
return self.deserializer.loads(resp.raw_body)
|
|
718
|
+
|
|
719
|
+
return await self._executor.execute(request, response_handler)
|
|
720
|
+
|
|
721
|
+
async def delete_function(
|
|
722
|
+
self,
|
|
723
|
+
name: str,
|
|
724
|
+
group: Optional[bool] = None,
|
|
725
|
+
ignore_missing: bool = False,
|
|
726
|
+
) -> Result[Json]:
|
|
727
|
+
"""Remove a user-defined AQL function.
|
|
728
|
+
|
|
729
|
+
Args:
|
|
730
|
+
name (str): Name of the function.
|
|
731
|
+
group (bool | None): If set to `True`, the function name is treated
|
|
732
|
+
as a namespace prefix.
|
|
733
|
+
ignore_missing (bool): If set to `True`, will not raise an exception
|
|
734
|
+
if the function is not found.
|
|
735
|
+
|
|
736
|
+
Returns:
|
|
737
|
+
dict: Information about the removed functions (their count).
|
|
738
|
+
|
|
739
|
+
Raises:
|
|
740
|
+
AQLFunctionDeleteError: If removal fails.
|
|
741
|
+
|
|
742
|
+
References:
|
|
743
|
+
- `remove-a-user-defined-aql-function <https://docs.arangodb.com/stable/develop/http-api/queries/user-defined-aql-functions/#remove-a-user-defined-aql-function>`__
|
|
744
|
+
""" # noqa: E501
|
|
745
|
+
params: Json = dict()
|
|
746
|
+
if group is not None:
|
|
747
|
+
params["group"] = group
|
|
748
|
+
request = Request(
|
|
749
|
+
method=Method.DELETE,
|
|
750
|
+
endpoint=f"/_api/aqlfunction/{name}",
|
|
751
|
+
params=params,
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
def response_handler(resp: Response) -> Json:
|
|
755
|
+
if not resp.is_success:
|
|
756
|
+
if not (resp.status_code == HTTP_NOT_FOUND and ignore_missing):
|
|
757
|
+
raise AQLFunctionDeleteError(resp, request)
|
|
758
|
+
return self.deserializer.loads(resp.raw_body)
|
|
759
|
+
|
|
760
|
+
return await self._executor.execute(request, response_handler)
|