python-arango-async 0.0.2__py3-none-any.whl → 1.0.4__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/aql.py +48 -23
- arangoasync/auth.py +2 -2
- arangoasync/backup.py +295 -0
- arangoasync/client.py +9 -3
- arangoasync/cluster.py +451 -0
- arangoasync/collection.py +2146 -787
- arangoasync/connection.py +10 -2
- arangoasync/cursor.py +3 -3
- arangoasync/database.py +2496 -399
- arangoasync/exceptions.py +442 -2
- arangoasync/foxx.py +829 -0
- arangoasync/graph.py +1050 -0
- arangoasync/http.py +22 -0
- arangoasync/job.py +5 -5
- arangoasync/replication.py +270 -0
- arangoasync/request.py +10 -5
- arangoasync/response.py +15 -1
- arangoasync/typings.py +455 -23
- arangoasync/version.py +1 -1
- {python_arango_async-0.0.2.dist-info → python_arango_async-1.0.4.dist-info}/METADATA +71 -31
- python_arango_async-1.0.4.dist-info/RECORD +32 -0
- {python_arango_async-0.0.2.dist-info → python_arango_async-1.0.4.dist-info}/WHEEL +1 -1
- python_arango_async-0.0.2.dist-info/RECORD +0 -27
- {python_arango_async-0.0.2.dist-info → python_arango_async-1.0.4.dist-info}/licenses/LICENSE +0 -0
- {python_arango_async-0.0.2.dist-info → python_arango_async-1.0.4.dist-info}/top_level.txt +0 -0
arangoasync/aql.py
CHANGED
|
@@ -16,6 +16,7 @@ from arangoasync.exceptions import (
|
|
|
16
16
|
AQLQueryClearError,
|
|
17
17
|
AQLQueryExecuteError,
|
|
18
18
|
AQLQueryExplainError,
|
|
19
|
+
AQLQueryHistoryError,
|
|
19
20
|
AQLQueryKillError,
|
|
20
21
|
AQLQueryListError,
|
|
21
22
|
AQLQueryRulesGetError,
|
|
@@ -77,7 +78,7 @@ class AQLQueryCache:
|
|
|
77
78
|
AQLCacheEntriesError: If retrieval fails.
|
|
78
79
|
|
|
79
80
|
References:
|
|
80
|
-
- `list-the-entries-of-the-aql-query-results-cache <https://docs.
|
|
81
|
+
- `list-the-entries-of-the-aql-query-results-cache <https://docs.arango.ai/stable/develop/http-api/queries/aql-query-results-cache/#list-the-entries-of-the-aql-query-results-cache>`__
|
|
81
82
|
""" # noqa: E501
|
|
82
83
|
request = Request(method=Method.GET, endpoint="/_api/query-cache/entries")
|
|
83
84
|
|
|
@@ -98,7 +99,7 @@ class AQLQueryCache:
|
|
|
98
99
|
AQLCacheEntriesError: If retrieval fails.
|
|
99
100
|
|
|
100
101
|
References:
|
|
101
|
-
- `list-the-entries-of-the-aql-query-plan-cache <https://docs.
|
|
102
|
+
- `list-the-entries-of-the-aql-query-plan-cache <https://docs.arango.ai/stable/develop/http-api/queries/aql-query-plan-cache/#list-the-entries-of-the-aql-query-plan-cache>`__
|
|
102
103
|
""" # noqa: E501
|
|
103
104
|
request = Request(method=Method.GET, endpoint="/_api/query-plan-cache")
|
|
104
105
|
|
|
@@ -116,7 +117,7 @@ class AQLQueryCache:
|
|
|
116
117
|
AQLCacheClearError: If clearing the cache fails.
|
|
117
118
|
|
|
118
119
|
References:
|
|
119
|
-
- `clear-the-aql-query-results-cache <https://docs.
|
|
120
|
+
- `clear-the-aql-query-results-cache <https://docs.arango.ai/stable/develop/http-api/queries/aql-query-results-cache/#clear-the-aql-query-results-cache>`__
|
|
120
121
|
""" # noqa: E501
|
|
121
122
|
request = Request(method=Method.DELETE, endpoint="/_api/query-cache")
|
|
122
123
|
|
|
@@ -133,7 +134,7 @@ class AQLQueryCache:
|
|
|
133
134
|
AQLCacheClearError: If clearing the cache fails.
|
|
134
135
|
|
|
135
136
|
References:
|
|
136
|
-
- `clear-the-aql-query-plan-cache <https://docs.
|
|
137
|
+
- `clear-the-aql-query-plan-cache <https://docs.arango.ai/stable/develop/http-api/queries/aql-query-plan-cache/#clear-the-aql-query-plan-cache>`__
|
|
137
138
|
""" # noqa: E501
|
|
138
139
|
request = Request(method=Method.DELETE, endpoint="/_api/query-plan-cache")
|
|
139
140
|
|
|
@@ -153,7 +154,7 @@ class AQLQueryCache:
|
|
|
153
154
|
AQLCachePropertiesError: If retrieval fails.
|
|
154
155
|
|
|
155
156
|
References:
|
|
156
|
-
- `get-the-aql-query-results-cache-configuration <https://docs.
|
|
157
|
+
- `get-the-aql-query-results-cache-configuration <https://docs.arango.ai/stable/develop/http-api/queries/aql-query-results-cache/#get-the-aql-query-results-cache-configuration>`__
|
|
157
158
|
""" # noqa: E501
|
|
158
159
|
request = Request(method=Method.GET, endpoint="/_api/query-cache/properties")
|
|
159
160
|
|
|
@@ -192,7 +193,7 @@ class AQLQueryCache:
|
|
|
192
193
|
AQLCacheConfigureError: If setting the configuration fails.
|
|
193
194
|
|
|
194
195
|
References:
|
|
195
|
-
- `set-the-aql-query-results-cache-configuration <https://docs.
|
|
196
|
+
- `set-the-aql-query-results-cache-configuration <https://docs.arango.ai/stable/develop/http-api/queries/aql-query-results-cache/#set-the-aql-query-results-cache-configuration>`__
|
|
196
197
|
""" # noqa: E501
|
|
197
198
|
data: Json = dict()
|
|
198
199
|
if mode is not None:
|
|
@@ -238,6 +239,11 @@ class AQL:
|
|
|
238
239
|
"""Return the name of the current database."""
|
|
239
240
|
return self._executor.db_name
|
|
240
241
|
|
|
242
|
+
@property
|
|
243
|
+
def context(self) -> str:
|
|
244
|
+
"""Return the current API execution context."""
|
|
245
|
+
return self._executor.context
|
|
246
|
+
|
|
241
247
|
@property
|
|
242
248
|
def serializer(self) -> Serializer[Json]:
|
|
243
249
|
"""Return the serializer."""
|
|
@@ -292,7 +298,7 @@ class AQL:
|
|
|
292
298
|
Cursor: Result cursor.
|
|
293
299
|
|
|
294
300
|
References:
|
|
295
|
-
- `create-a-cursor <https://docs.
|
|
301
|
+
- `create-a-cursor <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#create-a-cursor>`__
|
|
296
302
|
""" # noqa: E501
|
|
297
303
|
data: Json = dict(query=query)
|
|
298
304
|
if count is not None:
|
|
@@ -347,7 +353,7 @@ class AQL:
|
|
|
347
353
|
AQLQueryTrackingGetError: If retrieval fails.
|
|
348
354
|
|
|
349
355
|
References:
|
|
350
|
-
- `get-the-aql-query-tracking-configuration <https://docs.
|
|
356
|
+
- `get-the-aql-query-tracking-configuration <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#get-the-aql-query-tracking-configuration>`__
|
|
351
357
|
""" # noqa: E501
|
|
352
358
|
request = Request(method=Method.GET, endpoint="/_api/query/properties")
|
|
353
359
|
|
|
@@ -391,7 +397,7 @@ class AQL:
|
|
|
391
397
|
AQLQueryTrackingSetError: If setting the configuration fails.
|
|
392
398
|
|
|
393
399
|
References:
|
|
394
|
-
- `update-the-aql-query-tracking-configuration <https://docs.
|
|
400
|
+
- `update-the-aql-query-tracking-configuration <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#update-the-aql-query-tracking-configuration>`__
|
|
395
401
|
""" # noqa: E501
|
|
396
402
|
data: Json = dict()
|
|
397
403
|
|
|
@@ -421,6 +427,25 @@ class AQL:
|
|
|
421
427
|
|
|
422
428
|
return await self._executor.execute(request, response_handler)
|
|
423
429
|
|
|
430
|
+
async def history(self) -> Result[Json]:
|
|
431
|
+
"""Return recently executed AQL queries (admin only).
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
dict: AQL query history.
|
|
435
|
+
|
|
436
|
+
Raises:
|
|
437
|
+
AQLQueryHistoryError: If retrieval fails.
|
|
438
|
+
"""
|
|
439
|
+
request = Request(method=Method.GET, endpoint="/_admin/server/aql-queries")
|
|
440
|
+
|
|
441
|
+
def response_handler(resp: Response) -> Json:
|
|
442
|
+
if not resp.is_success:
|
|
443
|
+
raise AQLQueryHistoryError(resp, request)
|
|
444
|
+
result: Json = self.deserializer.loads(resp.raw_body)
|
|
445
|
+
return cast(Json, result["result"])
|
|
446
|
+
|
|
447
|
+
return await self._executor.execute(request, response_handler)
|
|
448
|
+
|
|
424
449
|
async def queries(self, all_queries: bool = False) -> Result[Jsons]:
|
|
425
450
|
"""Return a list of currently running queries.
|
|
426
451
|
|
|
@@ -437,7 +462,7 @@ class AQL:
|
|
|
437
462
|
AQLQueryListError: If retrieval fails.
|
|
438
463
|
|
|
439
464
|
References:
|
|
440
|
-
- `list-the-running-queries <https://docs.
|
|
465
|
+
- `list-the-running-queries <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#list-the-running-queries>`__
|
|
441
466
|
""" # noqa: E501
|
|
442
467
|
request = Request(
|
|
443
468
|
method=Method.GET,
|
|
@@ -468,7 +493,7 @@ class AQL:
|
|
|
468
493
|
AQLQueryListError: If retrieval fails.
|
|
469
494
|
|
|
470
495
|
References:
|
|
471
|
-
- `list-the-slow-aql-queries <https://docs.
|
|
496
|
+
- `list-the-slow-aql-queries <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#list-the-slow-aql-queries>`__
|
|
472
497
|
""" # noqa: E501
|
|
473
498
|
request = Request(
|
|
474
499
|
method=Method.GET,
|
|
@@ -498,7 +523,7 @@ class AQL:
|
|
|
498
523
|
AQLQueryClearError: If retrieval fails.
|
|
499
524
|
|
|
500
525
|
References:
|
|
501
|
-
- `clear-the-list-of-slow-aql-queries <https://docs.
|
|
526
|
+
- `clear-the-list-of-slow-aql-queries <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#clear-the-list-of-slow-aql-queries>`__
|
|
502
527
|
""" # noqa: E501
|
|
503
528
|
request = Request(
|
|
504
529
|
method=Method.DELETE,
|
|
@@ -535,7 +560,7 @@ class AQL:
|
|
|
535
560
|
AQLQueryKillError: If killing the query fails.
|
|
536
561
|
|
|
537
562
|
References:
|
|
538
|
-
- `kill-a-running-aql-query <https://docs.
|
|
563
|
+
- `kill-a-running-aql-query <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#kill-a-running-aql-query>`__
|
|
539
564
|
""" # noqa: E501
|
|
540
565
|
request = Request(
|
|
541
566
|
method=Method.DELETE,
|
|
@@ -573,7 +598,7 @@ class AQL:
|
|
|
573
598
|
AQLQueryExplainError: If retrieval fails.
|
|
574
599
|
|
|
575
600
|
References:
|
|
576
|
-
- `explain-an-aql-query <https://docs.
|
|
601
|
+
- `explain-an-aql-query <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#explain-an-aql-query>`__
|
|
577
602
|
""" # noqa: E501
|
|
578
603
|
data: Json = dict(query=query)
|
|
579
604
|
if bind_vars is not None:
|
|
@@ -592,7 +617,7 @@ class AQL:
|
|
|
592
617
|
def response_handler(resp: Response) -> Json:
|
|
593
618
|
if not resp.is_success:
|
|
594
619
|
raise AQLQueryExplainError(resp, request)
|
|
595
|
-
return self.deserializer.loads(resp.raw_body)
|
|
620
|
+
return Response.format_body(self.deserializer.loads(resp.raw_body))
|
|
596
621
|
|
|
597
622
|
return await self._executor.execute(request, response_handler)
|
|
598
623
|
|
|
@@ -609,7 +634,7 @@ class AQL:
|
|
|
609
634
|
AQLQueryValidateError: If validation fails.
|
|
610
635
|
|
|
611
636
|
References:
|
|
612
|
-
- `parse-an-aql-query <https://docs.
|
|
637
|
+
- `parse-an-aql-query <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#parse-an-aql-query>`__
|
|
613
638
|
""" # noqa: E501
|
|
614
639
|
request = Request(
|
|
615
640
|
method=Method.POST,
|
|
@@ -620,7 +645,7 @@ class AQL:
|
|
|
620
645
|
def response_handler(resp: Response) -> Json:
|
|
621
646
|
if not resp.is_success:
|
|
622
647
|
raise AQLQueryValidateError(resp, request)
|
|
623
|
-
return self.deserializer.loads(resp.raw_body)
|
|
648
|
+
return Response.format_body(self.deserializer.loads(resp.raw_body))
|
|
624
649
|
|
|
625
650
|
return await self._executor.execute(request, response_handler)
|
|
626
651
|
|
|
@@ -634,7 +659,7 @@ class AQL:
|
|
|
634
659
|
AQLQueryRulesGetError: If retrieval fails.
|
|
635
660
|
|
|
636
661
|
References:
|
|
637
|
-
- `list-all-aql-optimizer-rules <https://docs.
|
|
662
|
+
- `list-all-aql-optimizer-rules <https://docs.arango.ai/stable/develop/http-api/queries/aql-queries/#list-all-aql-optimizer-rules>`__
|
|
638
663
|
""" # noqa: E501
|
|
639
664
|
request = Request(method=Method.GET, endpoint="/_api/query/rules")
|
|
640
665
|
|
|
@@ -659,7 +684,7 @@ class AQL:
|
|
|
659
684
|
AQLFunctionListError: If retrieval fails.
|
|
660
685
|
|
|
661
686
|
References:
|
|
662
|
-
- `list-the-registered-user-defined-aql-functions <https://docs.
|
|
687
|
+
- `list-the-registered-user-defined-aql-functions <https://docs.arango.ai/stable/develop/http-api/queries/user-defined-aql-functions/#list-the-registered-user-defined-aql-functions>`__
|
|
663
688
|
""" # noqa: E501
|
|
664
689
|
params: Json = dict()
|
|
665
690
|
if namespace is not None:
|
|
@@ -701,7 +726,7 @@ class AQL:
|
|
|
701
726
|
AQLFunctionCreateError: If registration fails.
|
|
702
727
|
|
|
703
728
|
References:
|
|
704
|
-
- `create-a-user-defined-aql-function <https://docs.
|
|
729
|
+
- `create-a-user-defined-aql-function <https://docs.arango.ai/stable/develop/http-api/queries/user-defined-aql-functions/#create-a-user-defined-aql-function>`__
|
|
705
730
|
""" # noqa: E501
|
|
706
731
|
request = Request(
|
|
707
732
|
method=Method.POST,
|
|
@@ -714,7 +739,7 @@ class AQL:
|
|
|
714
739
|
def response_handler(resp: Response) -> Json:
|
|
715
740
|
if not resp.is_success:
|
|
716
741
|
raise AQLFunctionCreateError(resp, request)
|
|
717
|
-
return self.deserializer.loads(resp.raw_body)
|
|
742
|
+
return Response.format_body(self.deserializer.loads(resp.raw_body))
|
|
718
743
|
|
|
719
744
|
return await self._executor.execute(request, response_handler)
|
|
720
745
|
|
|
@@ -740,7 +765,7 @@ class AQL:
|
|
|
740
765
|
AQLFunctionDeleteError: If removal fails.
|
|
741
766
|
|
|
742
767
|
References:
|
|
743
|
-
- `remove-a-user-defined-aql-function <https://docs.
|
|
768
|
+
- `remove-a-user-defined-aql-function <https://docs.arango.ai/stable/develop/http-api/queries/user-defined-aql-functions/#remove-a-user-defined-aql-function>`__
|
|
744
769
|
""" # noqa: E501
|
|
745
770
|
params: Json = dict()
|
|
746
771
|
if group is not None:
|
|
@@ -755,6 +780,6 @@ class AQL:
|
|
|
755
780
|
if not resp.is_success:
|
|
756
781
|
if not (resp.status_code == HTTP_NOT_FOUND and ignore_missing):
|
|
757
782
|
raise AQLFunctionDeleteError(resp, request)
|
|
758
|
-
return self.deserializer.loads(resp.raw_body)
|
|
783
|
+
return Response.format_body(self.deserializer.loads(resp.raw_body))
|
|
759
784
|
|
|
760
785
|
return await self._executor.execute(request, response_handler)
|
arangoasync/auth.py
CHANGED
arangoasync/backup.py
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
__all__ = ["Backup"]
|
|
2
|
+
|
|
3
|
+
from numbers import Number
|
|
4
|
+
from typing import Optional, cast
|
|
5
|
+
|
|
6
|
+
from arangoasync.exceptions import (
|
|
7
|
+
BackupCreateError,
|
|
8
|
+
BackupDeleteError,
|
|
9
|
+
BackupDownloadError,
|
|
10
|
+
BackupGetError,
|
|
11
|
+
BackupRestoreError,
|
|
12
|
+
BackupUploadError,
|
|
13
|
+
)
|
|
14
|
+
from arangoasync.executor import ApiExecutor
|
|
15
|
+
from arangoasync.request import Method, Request
|
|
16
|
+
from arangoasync.response import Response
|
|
17
|
+
from arangoasync.result import Result
|
|
18
|
+
from arangoasync.serialization import Deserializer, Serializer
|
|
19
|
+
from arangoasync.typings import Json, Jsons
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Backup:
|
|
23
|
+
"""Backup API wrapper."""
|
|
24
|
+
|
|
25
|
+
def __init__(self, executor: ApiExecutor) -> None:
|
|
26
|
+
self._executor = executor
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def serializer(self) -> Serializer[Json]:
|
|
30
|
+
"""Return the serializer."""
|
|
31
|
+
return self._executor.serializer
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def deserializer(self) -> Deserializer[Json, Jsons]:
|
|
35
|
+
"""Return the deserializer."""
|
|
36
|
+
return self._executor.deserializer
|
|
37
|
+
|
|
38
|
+
async def get(self, backup_id: Optional[str] = None) -> Result[Json]:
|
|
39
|
+
"""Return backup details.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
backup_id (str | None): If set, the returned list is restricted to the
|
|
43
|
+
backup with the given id.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
dict: Backup details.
|
|
47
|
+
|
|
48
|
+
Raises:
|
|
49
|
+
BackupGetError: If the operation fails.
|
|
50
|
+
|
|
51
|
+
References:
|
|
52
|
+
- `list-backups <https://docs.arango.ai/stable/develop/http-api/hot-backups/#list-all-backups>`__
|
|
53
|
+
""" # noqa: E501
|
|
54
|
+
data: Json = {}
|
|
55
|
+
if backup_id is not None:
|
|
56
|
+
data["id"] = backup_id
|
|
57
|
+
|
|
58
|
+
request = Request(
|
|
59
|
+
method=Method.POST,
|
|
60
|
+
endpoint="/_admin/backup/list",
|
|
61
|
+
data=self.serializer.dumps(data) if data else None,
|
|
62
|
+
prefix_needed=False,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def response_handler(resp: Response) -> Json:
|
|
66
|
+
if not resp.is_success:
|
|
67
|
+
raise BackupGetError(resp, request)
|
|
68
|
+
result: Json = self.deserializer.loads(resp.raw_body)
|
|
69
|
+
return cast(Json, result["result"])
|
|
70
|
+
|
|
71
|
+
return await self._executor.execute(request, response_handler)
|
|
72
|
+
|
|
73
|
+
async def create(
|
|
74
|
+
self,
|
|
75
|
+
label: Optional[str] = None,
|
|
76
|
+
allow_inconsistent: Optional[bool] = None,
|
|
77
|
+
force: Optional[bool] = None,
|
|
78
|
+
timeout: Optional[Number] = None,
|
|
79
|
+
) -> Result[Json]:
|
|
80
|
+
"""Create a backup when the global write lock can be obtained.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
label (str | None): Label for this backup. If not specified, a UUID is used.
|
|
84
|
+
allow_inconsistent (bool | None): Allow inconsistent backup when the global
|
|
85
|
+
transaction lock cannot be acquired before timeout.
|
|
86
|
+
force (bool | None): Forcefully abort all running transactions to ensure a
|
|
87
|
+
consistent backup when the global transaction lock cannot be
|
|
88
|
+
acquired before timeout. Default (and highly recommended) value
|
|
89
|
+
is `False`.
|
|
90
|
+
timeout (float | None): The time in seconds that the operation tries to
|
|
91
|
+
get a consistent snapshot.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
dict: Backup information.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
BackupCreateError: If the backup creation fails.
|
|
98
|
+
|
|
99
|
+
References:
|
|
100
|
+
- `create-backup <https://docs.arango.ai/stable/develop/http-api/hot-backups/#create-a-backup>`__
|
|
101
|
+
""" # noqa: E501
|
|
102
|
+
data: Json = {}
|
|
103
|
+
if label is not None:
|
|
104
|
+
data["label"] = label
|
|
105
|
+
if allow_inconsistent is not None:
|
|
106
|
+
data["allowInconsistent"] = allow_inconsistent
|
|
107
|
+
if force is not None:
|
|
108
|
+
data["force"] = force
|
|
109
|
+
if timeout is not None:
|
|
110
|
+
data["timeout"] = timeout
|
|
111
|
+
|
|
112
|
+
request = Request(
|
|
113
|
+
method=Method.POST,
|
|
114
|
+
endpoint="/_admin/backup/create",
|
|
115
|
+
data=self.serializer.dumps(data),
|
|
116
|
+
prefix_needed=False,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
def response_handler(resp: Response) -> Json:
|
|
120
|
+
if not resp.is_success:
|
|
121
|
+
raise BackupCreateError(resp, request)
|
|
122
|
+
result: Json = self.deserializer.loads(resp.raw_body)
|
|
123
|
+
return cast(Json, result["result"])
|
|
124
|
+
|
|
125
|
+
return await self._executor.execute(request, response_handler)
|
|
126
|
+
|
|
127
|
+
async def restore(self, backup_id: str) -> Result[Json]:
|
|
128
|
+
"""Restore a local backup.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
backup_id (str): Backup ID.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
dict: Result of the restore operation.
|
|
135
|
+
|
|
136
|
+
Raises:
|
|
137
|
+
BackupRestoreError: If the restore operation fails.
|
|
138
|
+
|
|
139
|
+
References:
|
|
140
|
+
- `restore-backup <https://docs.arango.ai/stable/develop/http-api/hot-backups/#restore-a-backup>`__
|
|
141
|
+
""" # noqa: E501
|
|
142
|
+
data: Json = {"id": backup_id}
|
|
143
|
+
request = Request(
|
|
144
|
+
method=Method.POST,
|
|
145
|
+
endpoint="/_admin/backup/restore",
|
|
146
|
+
data=self.serializer.dumps(data),
|
|
147
|
+
prefix_needed=False,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def response_handler(resp: Response) -> Json:
|
|
151
|
+
if not resp.is_success:
|
|
152
|
+
raise BackupRestoreError(resp, request)
|
|
153
|
+
result: Json = self.deserializer.loads(resp.raw_body)
|
|
154
|
+
return cast(Json, result["result"])
|
|
155
|
+
|
|
156
|
+
return await self._executor.execute(request, response_handler)
|
|
157
|
+
|
|
158
|
+
async def delete(self, backup_id: str) -> None:
|
|
159
|
+
"""Delete a backup.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
backup_id (str): Backup ID.
|
|
163
|
+
|
|
164
|
+
Raises:
|
|
165
|
+
BackupDeleteError: If the delete operation fails.
|
|
166
|
+
|
|
167
|
+
References:
|
|
168
|
+
- `delete-backup <https://docs.arango.ai/stable/develop/http-api/hot-backups/#delete-a-backup>`__
|
|
169
|
+
""" # noqa: E501
|
|
170
|
+
data: Json = {"id": backup_id}
|
|
171
|
+
request = Request(
|
|
172
|
+
method=Method.POST,
|
|
173
|
+
endpoint="/_admin/backup/delete",
|
|
174
|
+
data=self.serializer.dumps(data),
|
|
175
|
+
prefix_needed=False,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
def response_handler(resp: Response) -> None:
|
|
179
|
+
if not resp.is_success:
|
|
180
|
+
raise BackupDeleteError(resp, request)
|
|
181
|
+
|
|
182
|
+
await self._executor.execute(request, response_handler)
|
|
183
|
+
|
|
184
|
+
async def upload(
|
|
185
|
+
self,
|
|
186
|
+
backup_id: Optional[str] = None,
|
|
187
|
+
repository: Optional[str] = None,
|
|
188
|
+
abort: Optional[bool] = None,
|
|
189
|
+
config: Optional[Json] = None,
|
|
190
|
+
upload_id: Optional[str] = None,
|
|
191
|
+
) -> Result[Json]:
|
|
192
|
+
"""Manage backup uploads.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
backup_id (str | None): Backup ID used for scheduling an upload. Mutually
|
|
196
|
+
exclusive with parameter **upload_id**.
|
|
197
|
+
repository (str | None): Remote repository URL(e.g. "local://tmp/backups").
|
|
198
|
+
abort (str | None): If set to `True`, running upload is aborted. Used with
|
|
199
|
+
parameter **upload_id**.
|
|
200
|
+
config (dict | None): Remote repository configuration. Required for scheduling
|
|
201
|
+
an upload and mutually exclusive with parameter **upload_id**.
|
|
202
|
+
upload_id (str | None): Upload ID. Mutually exclusive with parameters
|
|
203
|
+
**backup_id**, **repository**, and **config**.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
dict: Upload details.
|
|
207
|
+
|
|
208
|
+
Raises:
|
|
209
|
+
BackupUploadError: If upload operation fails.
|
|
210
|
+
|
|
211
|
+
References:
|
|
212
|
+
- `upload-a-backup-to-a-remote-repository <https://docs.arango.ai/stable/develop/http-api/hot-backups/#upload-a-backup-to-a-remote-repository>`__
|
|
213
|
+
""" # noqa: E501
|
|
214
|
+
data: Json = {}
|
|
215
|
+
if upload_id is not None:
|
|
216
|
+
data["uploadId"] = upload_id
|
|
217
|
+
if backup_id is not None:
|
|
218
|
+
data["id"] = backup_id
|
|
219
|
+
if repository is not None:
|
|
220
|
+
data["remoteRepository"] = repository
|
|
221
|
+
if abort is not None:
|
|
222
|
+
data["abort"] = abort
|
|
223
|
+
if config is not None:
|
|
224
|
+
data["config"] = config
|
|
225
|
+
|
|
226
|
+
request = Request(
|
|
227
|
+
method=Method.POST,
|
|
228
|
+
endpoint="/_admin/backup/upload",
|
|
229
|
+
data=self.serializer.dumps(data),
|
|
230
|
+
prefix_needed=False,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
def response_handler(resp: Response) -> Json:
|
|
234
|
+
if not resp.is_success:
|
|
235
|
+
raise BackupUploadError(resp, request)
|
|
236
|
+
result: Json = self.deserializer.loads(resp.raw_body)
|
|
237
|
+
return cast(Json, result["result"])
|
|
238
|
+
|
|
239
|
+
return await self._executor.execute(request, response_handler)
|
|
240
|
+
|
|
241
|
+
async def download(
|
|
242
|
+
self,
|
|
243
|
+
backup_id: Optional[str] = None,
|
|
244
|
+
repository: Optional[str] = None,
|
|
245
|
+
abort: Optional[bool] = None,
|
|
246
|
+
config: Optional[Json] = None,
|
|
247
|
+
download_id: Optional[str] = None,
|
|
248
|
+
) -> Result[Json]:
|
|
249
|
+
"""Manage backup downloads.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
backup_id (str | None): Backup ID used for scheduling a download. Mutually
|
|
253
|
+
exclusive with parameter **download_id**.
|
|
254
|
+
repository (str | None): Remote repository URL (e.g. "local://tmp/backups").
|
|
255
|
+
abort (bool | None): If set to `True`, running download is aborted.
|
|
256
|
+
config (dict | None): Remote repository configuration. Required for scheduling
|
|
257
|
+
a download and mutually exclusive with parameter **download_id**.
|
|
258
|
+
download_id (str | None): Download ID. Mutually exclusive with parameters
|
|
259
|
+
**backup_id**, **repository**, and **config**.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
dict: Download details.
|
|
263
|
+
|
|
264
|
+
Raises:
|
|
265
|
+
BackupDownloadError: If the download operation fails.
|
|
266
|
+
|
|
267
|
+
References:
|
|
268
|
+
- `download-a-backup-from-a-remote-repository <https://docs.arango.ai/stable/develop/http-api/hot-backups/#download-a-backup-from-a-remote-repository>`__
|
|
269
|
+
""" # noqa: E501
|
|
270
|
+
data: Json = {}
|
|
271
|
+
if download_id is not None:
|
|
272
|
+
data["downloadId"] = download_id
|
|
273
|
+
if backup_id is not None:
|
|
274
|
+
data["id"] = backup_id
|
|
275
|
+
if repository is not None:
|
|
276
|
+
data["remoteRepository"] = repository
|
|
277
|
+
if abort is not None:
|
|
278
|
+
data["abort"] = abort
|
|
279
|
+
if config is not None:
|
|
280
|
+
data["config"] = config
|
|
281
|
+
|
|
282
|
+
request = Request(
|
|
283
|
+
method=Method.POST,
|
|
284
|
+
endpoint="/_admin/backup/download",
|
|
285
|
+
data=self.serializer.dumps(data),
|
|
286
|
+
prefix_needed=False,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
def response_handler(resp: Response) -> Json:
|
|
290
|
+
if not resp.is_success:
|
|
291
|
+
raise BackupDownloadError(resp, request)
|
|
292
|
+
result: Json = self.deserializer.loads(resp.raw_body)
|
|
293
|
+
return cast(Json, result["result"])
|
|
294
|
+
|
|
295
|
+
return await self._executor.execute(request, response_handler)
|
arangoasync/client.py
CHANGED
|
@@ -139,13 +139,15 @@ class ArangoClient:
|
|
|
139
139
|
|
|
140
140
|
async def close(self) -> None:
|
|
141
141
|
"""Close HTTP sessions."""
|
|
142
|
-
await asyncio.gather(
|
|
142
|
+
await asyncio.gather(
|
|
143
|
+
*(self._http_client.close_session(session) for session in self._sessions)
|
|
144
|
+
)
|
|
143
145
|
|
|
144
146
|
async def db(
|
|
145
147
|
self,
|
|
146
148
|
name: str,
|
|
147
149
|
auth_method: str = "basic",
|
|
148
|
-
auth: Optional[Auth] = None,
|
|
150
|
+
auth: Optional[Auth | str] = None,
|
|
149
151
|
token: Optional[JwtToken] = None,
|
|
150
152
|
verify: bool = False,
|
|
151
153
|
compression: Optional[CompressionManager] = None,
|
|
@@ -167,7 +169,8 @@ class ArangoClient:
|
|
|
167
169
|
and client are synchronized.
|
|
168
170
|
- "superuser": Superuser JWT authentication.
|
|
169
171
|
The `token` parameter is required. The `auth` parameter is ignored.
|
|
170
|
-
auth (Auth | None): Login information
|
|
172
|
+
auth (Auth | None): Login information (username and password) or
|
|
173
|
+
access token.
|
|
171
174
|
token (JwtToken | None): JWT token.
|
|
172
175
|
verify (bool): Verify the connection by sending a test request.
|
|
173
176
|
compression (CompressionManager | None): If set, supersedes the
|
|
@@ -186,6 +189,9 @@ class ArangoClient:
|
|
|
186
189
|
"""
|
|
187
190
|
connection: Connection
|
|
188
191
|
|
|
192
|
+
if isinstance(auth, str):
|
|
193
|
+
auth = Auth(password=auth)
|
|
194
|
+
|
|
189
195
|
if auth_method == "basic":
|
|
190
196
|
if auth is None:
|
|
191
197
|
raise ValueError("Basic authentication requires the `auth` parameter")
|