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/typings.py ADDED
@@ -0,0 +1,1646 @@
1
+ from enum import Enum
2
+ from numbers import Number
3
+ from typing import (
4
+ Any,
5
+ Callable,
6
+ Dict,
7
+ Iterator,
8
+ List,
9
+ MutableMapping,
10
+ Optional,
11
+ Tuple,
12
+ cast,
13
+ )
14
+
15
+ from multidict import CIMultiDictProxy, MultiDict
16
+
17
+ Json = Dict[str, Any]
18
+ Json.__doc__ = """Type definition for request/response body"""
19
+
20
+ Jsons = List[Json]
21
+ Jsons.__doc__ = """Type definition for a list of JSON objects"""
22
+
23
+ RequestHeaders = MutableMapping[str, str] | MultiDict[str]
24
+ RequestHeaders.__doc__ = """Type definition for request HTTP headers"""
25
+
26
+ ResponseHeaders = MutableMapping[str, str] | MultiDict[str] | CIMultiDictProxy[str]
27
+ ResponseHeaders.__doc__ = """Type definition for response HTTP headers"""
28
+
29
+ Params = MutableMapping[str, bool | int | str | float]
30
+ Params.__doc__ = """Type definition for URL (query) parameters"""
31
+
32
+ Formatter = Callable[[Json], Json]
33
+ Formatter.__doc__ = """Type definition for a JSON formatter"""
34
+
35
+
36
+ class CollectionType(Enum):
37
+ """Collection types."""
38
+
39
+ DOCUMENT = 2
40
+ EDGE = 3
41
+
42
+ @staticmethod
43
+ def from_int(value: int) -> "CollectionType":
44
+ """Return a collection type from its integer value.
45
+
46
+ Args:
47
+ value (int): Collection type integer value.
48
+
49
+ Returns:
50
+ CollectionType: Collection type.
51
+ """
52
+ if value == 2:
53
+ return CollectionType.DOCUMENT
54
+ elif value == 3:
55
+ return CollectionType.EDGE
56
+ else:
57
+ raise ValueError(f"Invalid collection type value: {value}")
58
+
59
+ @staticmethod
60
+ def from_str(value: str) -> "CollectionType":
61
+ """Return a collection type from its string value.
62
+
63
+ Args:
64
+ value (str): Collection type string value.
65
+
66
+ Returns:
67
+ CollectionType: Collection type.
68
+ """
69
+ value = value.lower()
70
+ if value == "document":
71
+ return CollectionType.DOCUMENT
72
+ elif value == "edge":
73
+ return CollectionType.EDGE
74
+ else:
75
+ raise ValueError(f"Invalid collection type value: {value}")
76
+
77
+ def __str__(self) -> str:
78
+ return self.name.lower()
79
+
80
+ def __repr__(self) -> str:
81
+ return self.name.lower()
82
+
83
+
84
+ class CollectionStatus(Enum):
85
+ """Collection status."""
86
+
87
+ NEW = 1
88
+ UNLOADED = 2
89
+ LOADED = 3
90
+ UNLOADING = 4
91
+ DELETED = 5
92
+ LOADING = 6
93
+
94
+ @staticmethod
95
+ def from_int(value: int) -> "CollectionStatus":
96
+ """Return a collection status from its integer value.
97
+
98
+ Args:
99
+ value (int): Collection status integer value.
100
+
101
+ Returns:
102
+ CollectionStatus: Collection status.
103
+ """
104
+ if value == 1:
105
+ return CollectionStatus.NEW
106
+ elif value == 2:
107
+ return CollectionStatus.UNLOADED
108
+ elif value == 3:
109
+ return CollectionStatus.LOADED
110
+ elif value == 4:
111
+ return CollectionStatus.UNLOADING
112
+ elif value == 5:
113
+ return CollectionStatus.DELETED
114
+ elif value == 6:
115
+ return CollectionStatus.LOADING
116
+ else:
117
+ raise ValueError(f"Invalid collection status value: {value}")
118
+
119
+ def __str__(self) -> str:
120
+ return self.name.lower()
121
+
122
+ def __repr__(self) -> str:
123
+ return self.name.lower()
124
+
125
+
126
+ class JsonWrapper:
127
+ """Wrapper over server request/response objects."""
128
+
129
+ def __init__(self, data: Json) -> None:
130
+ self._data = data
131
+ for excluded in ("code", "error"):
132
+ if excluded in self._data:
133
+ self._data.pop(excluded)
134
+
135
+ def __getitem__(self, key: str) -> Any:
136
+ return self._data[key]
137
+
138
+ def __setitem__(self, key: str, value: Any) -> None:
139
+ self._data[key] = value
140
+
141
+ def __delitem__(self, key: str) -> None:
142
+ del self._data[key]
143
+
144
+ def __iter__(self) -> Iterator[str]:
145
+ return iter(self._data)
146
+
147
+ def __len__(self) -> int:
148
+ return len(self._data)
149
+
150
+ def __contains__(self, item: str) -> bool:
151
+ return item in self._data
152
+
153
+ def __repr__(self) -> str:
154
+ return f"{self.__class__.__name__}({self._data})"
155
+
156
+ def __str__(self) -> str:
157
+ return str(self._data)
158
+
159
+ def __eq__(self, other: object) -> bool:
160
+ return self._data == other
161
+
162
+ def get(self, key: str, default: Optional[Any] = None) -> Any:
163
+ """Return the value for key if key is in the dictionary, else default."""
164
+ return self._data.get(key, default)
165
+
166
+ def items(self) -> Iterator[Tuple[str, Any]]:
167
+ """Return an iterator over the dictionary’s key-value pairs."""
168
+ return iter(self._data.items())
169
+
170
+ def to_dict(self) -> Json:
171
+ """Return the dictionary."""
172
+ return self._data
173
+
174
+ def format(self, formatter: Optional[Formatter] = None) -> Json:
175
+ """Apply a formatter to the data.
176
+
177
+ Returns the unmodified data by default. Should not modify the object in-place.
178
+ """
179
+ if formatter is not None:
180
+ return formatter(self._data)
181
+ return self._data
182
+
183
+ @staticmethod
184
+ def _strip_result(data: Json) -> Json:
185
+ """Keep only the `result` key from a dict. Useful when parsing responses."""
186
+ return data["result"] # type: ignore[no-any-return]
187
+
188
+
189
+ class KeyOptions(JsonWrapper):
190
+ """Additional options for key generation, used on collections.
191
+
192
+ Args:
193
+ allow_user_keys (bool): If set to `True`, then you are allowed to supply own
194
+ key values in the `_key` attribute of documents. If set to `False`, then
195
+ the key generator is solely responsible for generating keys and an error
196
+ is raised if you supply own key values in the `_key` attribute of
197
+ documents.
198
+ generator_type (str): Specifies the type of the key generator. The currently
199
+ available generators are "traditional", "autoincrement", "uuid" and
200
+ "padded".
201
+ increment (int | None): The increment value for the "autoincrement" key
202
+ generator. Not allowed for other key generator types.
203
+ offset (int | None): The initial offset value for the "autoincrement" key
204
+ generator. Not allowed for other key generator types.
205
+ data (dict | None): Key options. If this parameter is specified, the
206
+ other parameters are ignored.
207
+
208
+ Example:
209
+ .. code-block:: json
210
+
211
+ {
212
+ "type": "autoincrement",
213
+ "increment": 5,
214
+ "allowUserKeys": true
215
+ }
216
+
217
+ References:
218
+ - `create-a-collection <https://docs.arangodb.com/stable/develop/http-api/collections/#create-a-collection_body_keyOptions>`__
219
+ """ # noqa: E501
220
+
221
+ def __init__(
222
+ self,
223
+ allow_user_keys: bool = True,
224
+ generator_type: str = "traditional",
225
+ increment: Optional[int] = None,
226
+ offset: Optional[int] = None,
227
+ data: Optional[Json] = None,
228
+ ) -> None:
229
+ if data is None:
230
+ data = {
231
+ "allowUserKeys": allow_user_keys,
232
+ "type": generator_type,
233
+ }
234
+ if increment is not None:
235
+ data["increment"] = increment
236
+ if offset is not None:
237
+ data["offset"] = offset
238
+ super().__init__(data)
239
+
240
+ def validate(self) -> None:
241
+ """Validate key options."""
242
+ if "type" not in self:
243
+ raise ValueError('"type" value is required for key options')
244
+ if "allowUserKeys" not in self:
245
+ raise ValueError('"allowUserKeys" value is required for key options')
246
+
247
+ allowed_types = {"autoincrement", "uuid", "padded", "traditional"}
248
+ if self["type"] not in allowed_types:
249
+ raise ValueError(
250
+ f"Invalid key generator type '{self['type']}', "
251
+ f"expected one of {allowed_types}"
252
+ )
253
+
254
+ if self.get("increment") is not None and self["type"] != "autoincrement":
255
+ raise ValueError(
256
+ '"increment" value is only allowed for "autoincrement" ' "key generator"
257
+ )
258
+ if self.get("offset") is not None and self["type"] != "autoincrement":
259
+ raise ValueError(
260
+ '"offset" value is only allowed for "autoincrement" ' "key generator"
261
+ )
262
+
263
+ @staticmethod
264
+ def compatibility_formatter(data: Json) -> Json:
265
+ """python-arango compatibility formatter."""
266
+ result: Json = {}
267
+ if "type" in data:
268
+ result["key_generator"] = data["type"]
269
+ if "increment" in data:
270
+ result["key_increment"] = data["increment"]
271
+ if "offset" in data:
272
+ result["key_offset"] = data["offset"]
273
+ if "allowUserKeys" in data:
274
+ result["user_keys"] = data["allowUserKeys"]
275
+ if "lastValue" in data:
276
+ result["key_last_value"] = data["lastValue"]
277
+ return result
278
+
279
+ def format(self, formatter: Optional[Formatter] = None) -> Json:
280
+ """Apply a formatter to the data.
281
+
282
+ By default, the python-arango compatibility formatter is applied.
283
+ """
284
+ if formatter is not None:
285
+ return super().format(formatter)
286
+ return self.compatibility_formatter(self._data)
287
+
288
+
289
+ class CollectionInfo(JsonWrapper):
290
+ """Collection information.
291
+
292
+ Example:
293
+ .. code-block:: json
294
+
295
+ {
296
+ "id" : "151",
297
+ "name" : "animals",
298
+ "status" : 3,
299
+ "type" : 2,
300
+ "isSystem" : false,
301
+ "globallyUniqueId" : "hDA74058C1843/151"
302
+ }
303
+
304
+ References:
305
+ - `get-the-collection-information <https://docs.arangodb.com/stable/develop/http-api/collections/#get-the-collection-information>`__
306
+ """ # noqa: E501
307
+
308
+ def __init__(self, data: Json) -> None:
309
+ super().__init__(data)
310
+
311
+ @property
312
+ def globally_unique_id(self) -> str:
313
+ """ "A unique identifier of the collection (internal property)."""
314
+ return cast(str, self._data["globallyUniqueId"])
315
+
316
+ @property
317
+ def is_system(self) -> bool:
318
+ """Whether the collection is a system collection."""
319
+ return cast(bool, self._data["isSystem"])
320
+
321
+ @property
322
+ def name(self) -> str:
323
+ """Return the name of the collection."""
324
+ return cast(str, self._data["name"])
325
+
326
+ @property
327
+ def status(self) -> CollectionStatus:
328
+ """Return the status of the collection."""
329
+ return CollectionStatus.from_int(self._data["status"])
330
+
331
+ @property
332
+ def col_type(self) -> CollectionType:
333
+ """Return the type of the collection."""
334
+ return CollectionType.from_int(self._data["type"])
335
+
336
+ @staticmethod
337
+ def compatibility_formatter(data: Json) -> Json:
338
+ """python-arango compatibility formatter."""
339
+ return {
340
+ "id": data["id"],
341
+ "name": data["name"],
342
+ "system": data["isSystem"],
343
+ "type": str(CollectionType.from_int(data["type"])),
344
+ "status": str(CollectionStatus.from_int(data["status"])),
345
+ }
346
+
347
+ def format(self, formatter: Optional[Formatter] = None) -> Json:
348
+ """Apply a formatter to the data.
349
+
350
+ By default, the python-arango compatibility formatter is applied.
351
+ """
352
+ if formatter is not None:
353
+ return super().format(formatter)
354
+ return self.compatibility_formatter(self._data)
355
+
356
+
357
+ class UserInfo(JsonWrapper):
358
+ """User information.
359
+
360
+ Args:
361
+ user (str): The name of the user.
362
+ password (str | None): The user password as a string. Note that user
363
+ password is not returned back by the server.
364
+ active (bool): `True` if user is active, `False` otherwise.
365
+ extra (dict | None): Additional user information. For internal use only.
366
+ Should not be set or modified by end users.
367
+
368
+ Example:
369
+ .. code-block:: json
370
+
371
+ {
372
+ "user": "john",
373
+ "password": "secret",
374
+ "active": true,
375
+ "extra": {}
376
+ }
377
+
378
+ References:
379
+ - `create-a-user <https://docs.arangodb.com/stable/develop/http-api/users/#create-a-user>`__
380
+ """ # noqa: E501
381
+
382
+ def __init__(
383
+ self,
384
+ user: str,
385
+ password: Optional[str] = None,
386
+ active: bool = True,
387
+ extra: Optional[Json] = None,
388
+ ) -> None:
389
+ data = {"user": user, "active": active}
390
+ if password is not None:
391
+ data["password"] = password
392
+ if extra is not None:
393
+ data["extra"] = extra
394
+ super().__init__(data)
395
+
396
+ @property
397
+ def user(self) -> str:
398
+ return self._data["user"] # type: ignore[no-any-return]
399
+
400
+ @property
401
+ def password(self) -> Optional[str]:
402
+ return self._data.get("password")
403
+
404
+ @property
405
+ def active(self) -> bool:
406
+ return self._data["active"] # type: ignore[no-any-return]
407
+
408
+ @property
409
+ def extra(self) -> Optional[Json]:
410
+ return self._data.get("extra")
411
+
412
+ @staticmethod
413
+ def user_management_formatter(data: Json) -> Json:
414
+ """Request formatter."""
415
+ result: Json = dict(user=data["user"])
416
+ if "password" in data:
417
+ result["passwd"] = data["password"]
418
+ if "active" in data:
419
+ result["active"] = data["active"]
420
+ if "extra" in data:
421
+ result["extra"] = data["extra"]
422
+ return result
423
+
424
+ def format(self, formatter: Optional[Formatter] = None) -> Json:
425
+ """Apply a formatter to the data."""
426
+ if formatter is not None:
427
+ return super().format(formatter)
428
+ return self._data
429
+
430
+
431
+ class ServerStatusInformation(JsonWrapper):
432
+ """Status information about the server.
433
+
434
+ Example:
435
+ .. code-block:: json
436
+
437
+ {
438
+ "server" : "arango",
439
+ "version" : "3.12.2",
440
+ "pid" : 244,
441
+ "license" : "enterprise",
442
+ "mode" : "server",
443
+ "operationMode" : "server",
444
+ "foxxApi" : true,
445
+ "host" : "localhost",
446
+ "hostname" : "ebd1509c9185",
447
+ "serverInfo" : {
448
+ "progress" : {
449
+ "phase" : "in wait",
450
+ "feature" : "",
451
+ "recoveryTick" : 0
452
+ },
453
+ "maintenance" : false,
454
+ "role" : "COORDINATOR",
455
+ "writeOpsEnabled" : true,
456
+ "readOnly" : false,
457
+ "persistedId" : "CRDN-329cfc20-071f-4faf-9727-7e48a7aed1e5",
458
+ "rebootId" : 1,
459
+ "address" : "tcp://localhost:8529",
460
+ "serverId" : "CRDN-329cfc20-071f-4faf-9727-7e48a7aed1e5",
461
+ "state" : "SERVING"
462
+ },
463
+ "coordinator" : {
464
+ "foxxmaster" : "CRDN-0ed76822-3e64-47ed-a61b-510f2a696175",
465
+ "isFoxxmaster" : false
466
+ },
467
+ "agency" : {
468
+ "agencyComm" : {
469
+ "endpoints" : [
470
+ "tcp://localhost:8551",
471
+ "tcp://localhost:8541",
472
+ "tcp://localhost:8531"
473
+ ]
474
+ }
475
+ }
476
+ }
477
+
478
+ References:
479
+ - `get-server-status-information <https://docs.arangodb.com/stable/develop/http-api/administration/#get-server-status-information>`__
480
+ """ # noqa: E501
481
+
482
+ def __init__(self, data: Json) -> None:
483
+ super().__init__(data)
484
+
485
+ @property
486
+ def server(self) -> Optional[str]:
487
+ return self._data.get("server")
488
+
489
+ @property
490
+ def version(self) -> Optional[str]:
491
+ return self._data.get("version")
492
+
493
+ @property
494
+ def pid(self) -> Optional[int]:
495
+ return self._data.get("pid")
496
+
497
+ @property
498
+ def license(self) -> Optional[str]:
499
+ return self._data.get("license")
500
+
501
+ @property
502
+ def mode(self) -> Optional[str]:
503
+ return self._data.get("mode")
504
+
505
+ @property
506
+ def operation_mode(self) -> Optional[str]:
507
+ return self._data.get("operationMode")
508
+
509
+ @property
510
+ def foxx_api(self) -> Optional[bool]:
511
+ return self._data.get("foxxApi")
512
+
513
+ @property
514
+ def host(self) -> Optional[str]:
515
+ return self._data.get("host")
516
+
517
+ @property
518
+ def hostname(self) -> Optional[str]:
519
+ return self._data.get("hostname")
520
+
521
+ @property
522
+ def server_info(self) -> Optional[Json]:
523
+ return self._data.get("serverInfo")
524
+
525
+ @property
526
+ def coordinator(self) -> Optional[Json]:
527
+ return self._data.get("coordinator")
528
+
529
+ @property
530
+ def agency(self) -> Optional[Json]:
531
+ return self._data.get("agency")
532
+
533
+
534
+ class DatabaseProperties(JsonWrapper):
535
+ """Properties of the database.
536
+
537
+ References:
538
+ - `get-information-about-the-current-database <https://docs.arangodb.com/stable/develop/http-api/databases/#get-information-about-the-current-database>`__
539
+ """ # noqa: E501
540
+
541
+ def __init__(self, data: Json, strip_result: bool = False) -> None:
542
+ super().__init__(self._strip_result(data) if strip_result else data)
543
+
544
+ @property
545
+ def name(self) -> str:
546
+ """The name of the current database."""
547
+ return self._data["name"] # type: ignore[no-any-return]
548
+
549
+ @property
550
+ def id(self) -> str:
551
+ """The id of the current database."""
552
+ return self._data["id"] # type: ignore[no-any-return]
553
+
554
+ @property
555
+ def path(self) -> Optional[str]:
556
+ """The filesystem path of the current database."""
557
+ return self._data.get("path")
558
+
559
+ @property
560
+ def is_system(self) -> bool:
561
+ """Whether the database is the `_system` database."""
562
+ return self._data["isSystem"] # type: ignore[no-any-return]
563
+
564
+ @property
565
+ def sharding(self) -> Optional[str]:
566
+ """The default sharding method for collections."""
567
+ return self._data.get("sharding")
568
+
569
+ @property
570
+ def replication_factor(self) -> Optional[int]:
571
+ """The default replication factor for collections."""
572
+ return self._data.get("replicationFactor")
573
+
574
+ @property
575
+ def write_concern(self) -> Optional[int]:
576
+ """The default write concern for collections."""
577
+ return self._data.get("writeConcern")
578
+
579
+ @staticmethod
580
+ def compatibility_formatter(data: Json) -> Json:
581
+ """python-arango compatibility formatter."""
582
+ result: Json = {}
583
+ if "id" in data:
584
+ result["id"] = data["id"]
585
+ if "name" in data:
586
+ result["name"] = data["name"]
587
+ if "path" in data:
588
+ result["path"] = data["path"]
589
+ if "system" in data:
590
+ result["system"] = data["system"]
591
+ if "isSystem" in data:
592
+ result["system"] = data["isSystem"]
593
+ if "sharding" in data:
594
+ result["sharding"] = data["sharding"]
595
+ if "replicationFactor" in data:
596
+ result["replication_factor"] = data["replicationFactor"]
597
+ if "writeConcern" in data:
598
+ result["write_concern"] = data["writeConcern"]
599
+ if "replicationVersion" in data:
600
+ result["replication_version"] = data["replicationVersion"]
601
+ return result
602
+
603
+ def format(self, formatter: Optional[Formatter] = None) -> Json:
604
+ """Apply a formatter to the data.
605
+
606
+ By default, the python-arango compatibility formatter is applied.
607
+ """
608
+ if formatter is not None:
609
+ return super().format(formatter)
610
+ return self.compatibility_formatter(self._data)
611
+
612
+
613
+ class CollectionProperties(JsonWrapper):
614
+ """Properties of a collection.
615
+
616
+ Example:
617
+ .. code-block:: json
618
+
619
+ {
620
+ "writeConcern" : 1,
621
+ "waitForSync" : true,
622
+ "usesRevisionsAsDocumentIds" : true,
623
+ "syncByRevision" : true,
624
+ "statusString" : "loaded",
625
+ "id" : "68452",
626
+ "isSmartChild" : false,
627
+ "schema" : null,
628
+ "name" : "products",
629
+ "type" : 2,
630
+ "status" : 3,
631
+ "cacheEnabled" : false,
632
+ "isSystem" : false,
633
+ "internalValidatorType" : 0,
634
+ "globallyUniqueId" : "hDA74058C1843/68452",
635
+ "keyOptions" : {
636
+ "allowUserKeys" : true,
637
+ "type" : "traditional",
638
+ "lastValue" : 0
639
+ },
640
+ "computedValues" : null,
641
+ "objectId" : "68453"
642
+ }
643
+
644
+ References:
645
+ - `get-the-properties-of-a-collection <https://docs.arangodb.com/stable/develop/http-api/collections/#get-the-properties-of-a-collection>`__
646
+ """ # noqa: E501
647
+
648
+ def __init__(self, data: Json) -> None:
649
+ super().__init__(data)
650
+
651
+ @property
652
+ def write_concern(self) -> Optional[int]:
653
+ return self._data.get("writeConcern")
654
+
655
+ @property
656
+ def wait_for_sync(self) -> Optional[bool]:
657
+ return self._data.get("waitForSync")
658
+
659
+ @property
660
+ def use_revisions_as_document_ids(self) -> Optional[bool]:
661
+ return self._data.get("usesRevisionsAsDocumentIds")
662
+
663
+ @property
664
+ def sync_by_revision(self) -> Optional[bool]:
665
+ return self._data.get("syncByRevision")
666
+
667
+ @property
668
+ def status_string(self) -> Optional[str]:
669
+ return self._data.get("statusString")
670
+
671
+ @property
672
+ def id(self) -> str:
673
+ return self._data["id"] # type: ignore[no-any-return]
674
+
675
+ @property
676
+ def is_smart_child(self) -> bool:
677
+ return self._data["isSmartChild"] # type: ignore[no-any-return]
678
+
679
+ @property
680
+ def schema(self) -> Optional[Json]:
681
+ return self._data.get("schema")
682
+
683
+ @property
684
+ def name(self) -> str:
685
+ return self._data["name"] # type: ignore[no-any-return]
686
+
687
+ @property
688
+ def type(self) -> CollectionType:
689
+ return CollectionType.from_int(self._data["type"])
690
+
691
+ @property
692
+ def status(self) -> CollectionStatus:
693
+ return CollectionStatus.from_int(self._data["status"])
694
+
695
+ @property
696
+ def cache_enabled(self) -> Optional[bool]:
697
+ return self._data.get("cacheEnabled")
698
+
699
+ @property
700
+ def is_system(self) -> bool:
701
+ return self._data["isSystem"] # type: ignore[no-any-return]
702
+
703
+ @property
704
+ def internal_validator_type(self) -> Optional[int]:
705
+ return self._data.get("internalValidatorType")
706
+
707
+ @property
708
+ def globally_unique_id(self) -> str:
709
+ return self._data["globallyUniqueId"] # type: ignore[no-any-return]
710
+
711
+ @property
712
+ def key_options(self) -> KeyOptions:
713
+ return KeyOptions(self._data["keyOptions"])
714
+
715
+ @property
716
+ def computed_values(self) -> Optional[Json]:
717
+ return self._data.get("computedValues")
718
+
719
+ @property
720
+ def object_id(self) -> str:
721
+ return self._data["objectId"] # type: ignore[no-any-return]
722
+
723
+ @staticmethod
724
+ def compatibility_formatter(data: Json) -> Json:
725
+ """python-arango compatibility formatter."""
726
+ result: Json = {}
727
+ if "id" in data:
728
+ result["id"] = data["id"]
729
+ if "objectId" in data:
730
+ result["object_id"] = data["objectId"]
731
+ if "name" in data:
732
+ result["name"] = data["name"]
733
+ if "isSystem" in data:
734
+ result["system"] = data["isSystem"]
735
+ if "isSmart" in data:
736
+ result["smart"] = data["isSmart"]
737
+ if "type" in data:
738
+ result["type"] = data["type"]
739
+ result["edge"] = data["type"] == 3
740
+ if "waitForSync" in data:
741
+ result["sync"] = data["waitForSync"]
742
+ if "status" in data:
743
+ result["status"] = data["status"]
744
+ if "statusString" in data:
745
+ result["status_string"] = data["statusString"]
746
+ if "globallyUniqueId" in data:
747
+ result["global_id"] = data["globallyUniqueId"]
748
+ if "cacheEnabled" in data:
749
+ result["cache"] = data["cacheEnabled"]
750
+ if "replicationFactor" in data:
751
+ result["replication_factor"] = data["replicationFactor"]
752
+ if "minReplicationFactor" in data:
753
+ result["min_replication_factor"] = data["minReplicationFactor"]
754
+ if "writeConcern" in data:
755
+ result["write_concern"] = data["writeConcern"]
756
+ if "shards" in data:
757
+ result["shards"] = data["shards"]
758
+ if "replicationFactor" in data:
759
+ result["replication_factor"] = data["replicationFactor"]
760
+ if "numberOfShards" in data:
761
+ result["shard_count"] = data["numberOfShards"]
762
+ if "shardKeys" in data:
763
+ result["shard_fields"] = data["shardKeys"]
764
+ if "distributeShardsLike" in data:
765
+ result["shard_like"] = data["distributeShardsLike"]
766
+ if "shardingStrategy" in data:
767
+ result["sharding_strategy"] = data["shardingStrategy"]
768
+ if "smartJoinAttribute" in data:
769
+ result["smart_join_attribute"] = data["smartJoinAttribute"]
770
+ if "keyOptions" in data:
771
+ result["key_options"] = KeyOptions.compatibility_formatter(
772
+ data["keyOptions"]
773
+ )
774
+ if "cid" in data:
775
+ result["cid"] = data["cid"]
776
+ if "version" in data:
777
+ result["version"] = data["version"]
778
+ if "allowUserKeys" in data:
779
+ result["user_keys"] = data["allowUserKeys"]
780
+ if "planId" in data:
781
+ result["plan_id"] = data["planId"]
782
+ if "deleted" in data:
783
+ result["deleted"] = data["deleted"]
784
+ if "syncByRevision" in data:
785
+ result["sync_by_revision"] = data["syncByRevision"]
786
+ if "tempObjectId" in data:
787
+ result["temp_object_id"] = data["tempObjectId"]
788
+ if "usesRevisionsAsDocumentIds" in data:
789
+ result["rev_as_id"] = data["usesRevisionsAsDocumentIds"]
790
+ if "isDisjoint" in data:
791
+ result["disjoint"] = data["isDisjoint"]
792
+ if "isSmartChild" in data:
793
+ result["smart_child"] = data["isSmartChild"]
794
+ if "minRevision" in data:
795
+ result["min_revision"] = data["minRevision"]
796
+ if "schema" in data:
797
+ result["schema"] = data["schema"]
798
+ if data.get("computedValues") is not None:
799
+ result["computedValues"] = data["computedValues"]
800
+ if "internalValidatorType" in data:
801
+ result["internal_validator_type"] = data["internalValidatorType"]
802
+ return result
803
+
804
+ def format(self, formatter: Optional[Formatter] = None) -> Json:
805
+ """Apply a formatter to the data.
806
+
807
+ By default, the python-arango compatibility formatter is applied.
808
+ """
809
+ if formatter is not None:
810
+ return super().format(formatter)
811
+ return self.compatibility_formatter(self._data)
812
+
813
+
814
+ class IndexProperties(JsonWrapper):
815
+ """Properties of an index.
816
+
817
+ Example:
818
+ .. code-block:: json
819
+
820
+ {
821
+ "fields" : [
822
+ "_key"
823
+ ],
824
+ "id" : "products/0",
825
+ "name" : "primary",
826
+ "selectivityEstimate" : 1,
827
+ "sparse" : false,
828
+ "type" : "primary",
829
+ "unique" : true,
830
+ }
831
+
832
+ References:
833
+ - `get-an-index <https://docs.arangodb.com/stable/develop/http-api/indexes/#get-an-index>`__
834
+ """ # noqa: E501
835
+
836
+ def __init__(self, data: Json) -> None:
837
+ super().__init__(data)
838
+
839
+ @property
840
+ def id(self) -> str:
841
+ return self._data["id"] # type: ignore[no-any-return]
842
+
843
+ @property
844
+ def numeric_id(self) -> int:
845
+ return int(self._data["id"].split("/", 1)[-1])
846
+
847
+ @property
848
+ def type(self) -> str:
849
+ return self._data["type"] # type: ignore[no-any-return]
850
+
851
+ @property
852
+ def fields(self) -> Json | List[str]:
853
+ return self._data["fields"] # type: ignore[no-any-return]
854
+
855
+ @property
856
+ def name(self) -> Optional[str]:
857
+ return self._data.get("name")
858
+
859
+ @property
860
+ def deduplicate(self) -> Optional[bool]:
861
+ return self._data.get("deduplicate")
862
+
863
+ @property
864
+ def sparse(self) -> Optional[bool]:
865
+ return self._data.get("sparse")
866
+
867
+ @property
868
+ def unique(self) -> Optional[bool]:
869
+ return self._data.get("unique")
870
+
871
+ @property
872
+ def geo_json(self) -> Optional[bool]:
873
+ return self._data.get("geoJson")
874
+
875
+ @property
876
+ def selectivity_estimate(self) -> Optional[float]:
877
+ return self._data.get("selectivityEstimate")
878
+
879
+ @property
880
+ def is_newly_created(self) -> Optional[bool]:
881
+ return self._data.get("isNewlyCreated")
882
+
883
+ @property
884
+ def expire_after(self) -> Optional[int]:
885
+ return self._data.get("expireAfter")
886
+
887
+ @property
888
+ def in_background(self) -> Optional[bool]:
889
+ return self._data.get("inBackground")
890
+
891
+ @property
892
+ def max_num_cover_cells(self) -> Optional[int]:
893
+ return self._data.get("maxNumCoverCells")
894
+
895
+ @property
896
+ def cache_enabled(self) -> Optional[bool]:
897
+ return self._data.get("cacheEnabled")
898
+
899
+ @property
900
+ def legacy_polygons(self) -> Optional[bool]:
901
+ return self._data.get("legacyPolygons")
902
+
903
+ @property
904
+ def estimates(self) -> Optional[bool]:
905
+ return self._data.get("estimates")
906
+
907
+ @property
908
+ def analyzer(self) -> Optional[str]:
909
+ return self._data.get("analyzer")
910
+
911
+ @property
912
+ def cleanup_interval_step(self) -> Optional[int]:
913
+ return self._data.get("cleanupIntervalStep")
914
+
915
+ @property
916
+ def commit_interval_msec(self) -> Optional[int]:
917
+ return self._data.get("commitIntervalMsec")
918
+
919
+ @property
920
+ def consolidation_interval_msec(self) -> Optional[int]:
921
+ return self._data.get("consolidationIntervalMsec")
922
+
923
+ @property
924
+ def consolidation_policy(self) -> Optional[Json]:
925
+ return self._data.get("consolidationPolicy")
926
+
927
+ @property
928
+ def primary_sort(self) -> Optional[Json]:
929
+ return self._data.get("primarySort")
930
+
931
+ @property
932
+ def stored_values(self) -> Optional[List[Any]]:
933
+ return self._data.get("storedValues")
934
+
935
+ @property
936
+ def write_buffer_active(self) -> Optional[int]:
937
+ return self._data.get("writeBufferActive")
938
+
939
+ @property
940
+ def write_buffer_idle(self) -> Optional[int]:
941
+ return self._data.get("writeBufferIdle")
942
+
943
+ @property
944
+ def write_buffer_size_max(self) -> Optional[int]:
945
+ return self._data.get("writeBufferSizeMax")
946
+
947
+ @property
948
+ def primary_key_cache(self) -> Optional[bool]:
949
+ return self._data.get("primaryKeyCache")
950
+
951
+ @property
952
+ def parallelism(self) -> Optional[int]:
953
+ return self._data.get("parallelism")
954
+
955
+ @property
956
+ def optimize_top_k(self) -> Optional[List[str]]:
957
+ return self._data.get("optimizeTopK")
958
+
959
+ @property
960
+ def track_list_positions(self) -> Optional[bool]:
961
+ return self._data.get("trackListPositions")
962
+
963
+ @property
964
+ def version(self) -> Optional[int]:
965
+ return self._data.get("version")
966
+
967
+ @property
968
+ def include_all_fields(self) -> Optional[bool]:
969
+ return self._data.get("includeAllFields")
970
+
971
+ @property
972
+ def features(self) -> Optional[List[str]]:
973
+ return self._data.get("features")
974
+
975
+ @staticmethod
976
+ def compatibility_formatter(data: Json) -> Json:
977
+ """python-arango compatibility formatter."""
978
+ result = {"id": data["id"].split("/", 1)[-1], "fields": data["fields"]}
979
+ if "type" in data:
980
+ result["type"] = data["type"]
981
+ if "name" in data:
982
+ result["name"] = data["name"]
983
+ if "deduplicate" in data:
984
+ result["deduplicate"] = data["deduplicate"]
985
+ if "sparse" in data:
986
+ result["sparse"] = data["sparse"]
987
+ if "unique" in data:
988
+ result["unique"] = data["unique"]
989
+ if "geoJson" in data:
990
+ result["geo_json"] = data["geoJson"]
991
+ if "selectivityEstimate" in data:
992
+ result["selectivity"] = data["selectivityEstimate"]
993
+ if "isNewlyCreated" in data:
994
+ result["new"] = data["isNewlyCreated"]
995
+ if "expireAfter" in data:
996
+ result["expiry_time"] = data["expireAfter"]
997
+ if "inBackground" in data:
998
+ result["in_background"] = data["inBackground"]
999
+ if "maxNumCoverCells" in data:
1000
+ result["max_num_cover_cells"] = data["maxNumCoverCells"]
1001
+ if "storedValues" in data:
1002
+ result["storedValues"] = data["storedValues"]
1003
+ if "legacyPolygons" in data:
1004
+ result["legacyPolygons"] = data["legacyPolygons"]
1005
+ if "estimates" in data:
1006
+ result["estimates"] = data["estimates"]
1007
+ if "analyzer" in data:
1008
+ result["analyzer"] = data["analyzer"]
1009
+ if "cleanupIntervalStep" in data:
1010
+ result["cleanup_interval_step"] = data["cleanupIntervalStep"]
1011
+ if "commitIntervalMsec" in data:
1012
+ result["commit_interval_msec"] = data["commitIntervalMsec"]
1013
+ if "consolidationIntervalMsec" in data:
1014
+ result["consolidation_interval_msec"] = data["consolidationIntervalMsec"]
1015
+ if "consolidationPolicy" in data:
1016
+ result["consolidation_policy"] = data["consolidationPolicy"]
1017
+ if "features" in data:
1018
+ result["features"] = data["features"]
1019
+ if "primarySort" in data:
1020
+ result["primary_sort"] = data["primarySort"]
1021
+ if "trackListPositions" in data:
1022
+ result["track_list_positions"] = data["trackListPositions"]
1023
+ if "version" in data:
1024
+ result["version"] = data["version"]
1025
+ if "writebufferIdle" in data:
1026
+ result["writebuffer_idle"] = data["writebufferIdle"]
1027
+ if "writebufferActive" in data:
1028
+ result["writebuffer_active"] = data["writebufferActive"]
1029
+ if "writebufferSizeMax" in data:
1030
+ result["writebuffer_max_size"] = data["writebufferSizeMax"]
1031
+ if "optimizeTopK" in data:
1032
+ result["optimizeTopK"] = data["optimizeTopK"]
1033
+ return result
1034
+
1035
+ def format(self, formatter: Optional[Formatter] = None) -> Json:
1036
+ """Apply a formatter to the data.
1037
+
1038
+ By default, the python-arango compatibility formatter is applied.
1039
+ """
1040
+ if formatter is not None:
1041
+ return super().format(formatter)
1042
+ return self.compatibility_formatter(self._data)
1043
+
1044
+
1045
+ class QueryProperties(JsonWrapper):
1046
+ """Extra options for AQL queries.
1047
+
1048
+ Args:
1049
+ allow_dirty_reads (bool | None): If set to `True`, when executing the query
1050
+ against a cluster deployment, the Coordinator is allowed to read from any
1051
+ shard replica and not only from the leader.
1052
+ allow_retry (bool | None): Setting it to `True` makes it possible to retry
1053
+ fetching the latest batch from a cursor.
1054
+ fail_on_warning (bool | None): If set to `True`, the query will throw an
1055
+ exception and abort instead of producing a warning.
1056
+ fill_block_cache (bool | None): If set to `True`, it will make the query
1057
+ store the data it reads via the RocksDB storage engine in the RocksDB
1058
+ block cache.
1059
+ full_count (bool | None): If set to `True` and the query contains a LIMIT
1060
+ clause, then the result will have some extra attributes.
1061
+ intermediate_commit_count (int | None): The maximum number of operations
1062
+ after which an intermediate commit is performed automatically.
1063
+ intermediate_commit_size (int | None): The maximum total size of operations
1064
+ after which an intermediate commit is performed automatically.
1065
+ max_dnf_condition_members (int | None): A threshold for the maximum number of
1066
+ OR sub-nodes in the internal representation of an AQL FILTER condition.
1067
+ max_nodes_per_callstack (int | None): The number of execution nodes in the
1068
+ query plan after that stack splitting is performed to avoid a potential
1069
+ stack overflow.
1070
+ max_number_of_plans (int | None): Limits the maximum number of plans that
1071
+ are created by the AQL query optimizer.
1072
+ max_runtime (float | None): The query has to be executed within the given
1073
+ runtime or it is killed. The value is specified in seconds. If unspecified,
1074
+ there will be no timeout.
1075
+ max_transaction_size (int | None): The maximum transaction size in bytes.
1076
+ max_warning_count (int | None): Limits the maximum number of warnings a
1077
+ query will return.
1078
+ optimizer (dict | None): Options related to the query optimizer.
1079
+ profile (int | None): Return additional profiling information in the query
1080
+ result. Can be set to 1 or 2 (for more detailed profiling information).
1081
+ satellite_sync_wait (flat | None): How long a DB-Server has time to bring
1082
+ the SatelliteCollections involved in the query into sync (in seconds).
1083
+ skip_inaccessible_collections (bool | None): Treat collections to which a user
1084
+ has no access rights for as if these collections are empty.
1085
+ spill_over_threshold_memory_usage (int | None): This option allows queries to
1086
+ store intermediate and final results temporarily on disk if the amount of
1087
+ memory used (in bytes) exceeds the specified value.
1088
+ spill_over_threshold_num_rows (int | None): This option allows queries to
1089
+ store intermediate and final results temporarily on disk if the number
1090
+ of rows produced by the query exceeds the specified value.
1091
+ stream (bool | None): Can be enabled to execute the query lazily.
1092
+ use_plan_cache (bool | None): Set this option to `True` to utilize
1093
+ a cached query plan or add the execution plan of this query to the
1094
+ cache if it’s not in the cache yet.
1095
+
1096
+ Example:
1097
+ .. code-block:: json
1098
+
1099
+ {
1100
+ "maxPlans": 1,
1101
+ "optimizer": {
1102
+ "rules": [
1103
+ "-all",
1104
+ "+remove-unnecessary-filters"
1105
+ ]
1106
+ }
1107
+ }
1108
+
1109
+ References:
1110
+ - `create-a-cursor <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#create-a-cursor_body_options>`__
1111
+ """ # noqa: E501
1112
+
1113
+ def __init__(
1114
+ self,
1115
+ allow_dirty_reads: Optional[bool] = None,
1116
+ allow_retry: Optional[bool] = None,
1117
+ fail_on_warning: Optional[bool] = None,
1118
+ fill_block_cache: Optional[bool] = None,
1119
+ full_count: Optional[bool] = None,
1120
+ intermediate_commit_count: Optional[int] = None,
1121
+ intermediate_commit_size: Optional[int] = None,
1122
+ max_dnf_condition_members: Optional[int] = None,
1123
+ max_nodes_per_callstack: Optional[int] = None,
1124
+ max_number_of_plans: Optional[int] = None,
1125
+ max_runtime: Optional[Number] = None,
1126
+ max_transaction_size: Optional[int] = None,
1127
+ max_warning_count: Optional[int] = None,
1128
+ optimizer: Optional[Json] = None,
1129
+ profile: Optional[int] = None,
1130
+ satellite_sync_wait: Optional[Number] = None,
1131
+ skip_inaccessible_collections: Optional[bool] = None,
1132
+ spill_over_threshold_memory_usage: Optional[int] = None,
1133
+ spill_over_threshold_num_rows: Optional[int] = None,
1134
+ stream: Optional[bool] = None,
1135
+ use_plan_cache: Optional[bool] = None,
1136
+ ) -> None:
1137
+ data: Json = dict()
1138
+ if allow_dirty_reads is not None:
1139
+ data["allowDirtyReads"] = allow_dirty_reads
1140
+ if allow_retry is not None:
1141
+ data["allowRetry"] = allow_retry
1142
+ if fail_on_warning is not None:
1143
+ data["failOnWarning"] = fail_on_warning
1144
+ if fill_block_cache is not None:
1145
+ data["fillBlockCache"] = fill_block_cache
1146
+ if full_count is not None:
1147
+ data["fullCount"] = full_count
1148
+ if intermediate_commit_count is not None:
1149
+ data["intermediateCommitCount"] = intermediate_commit_count
1150
+ if intermediate_commit_size is not None:
1151
+ data["intermediateCommitSize"] = intermediate_commit_size
1152
+ if max_dnf_condition_members is not None:
1153
+ data["maxDNFConditionMembers"] = max_dnf_condition_members
1154
+ if max_nodes_per_callstack is not None:
1155
+ data["maxNodesPerCallstack"] = max_nodes_per_callstack
1156
+ if max_number_of_plans is not None:
1157
+ data["maxNumberOfPlans"] = max_number_of_plans
1158
+ if max_runtime is not None:
1159
+ data["maxRuntime"] = max_runtime
1160
+ if max_transaction_size is not None:
1161
+ data["maxTransactionSize"] = max_transaction_size
1162
+ if max_warning_count is not None:
1163
+ data["maxWarningCount"] = max_warning_count
1164
+ if optimizer is not None:
1165
+ data["optimizer"] = optimizer
1166
+ if profile is not None:
1167
+ data["profile"] = profile
1168
+ if satellite_sync_wait is not None:
1169
+ data["satelliteSyncWait"] = satellite_sync_wait
1170
+ if skip_inaccessible_collections is not None:
1171
+ data["skipInaccessibleCollections"] = skip_inaccessible_collections
1172
+ if spill_over_threshold_memory_usage is not None:
1173
+ data["spillOverThresholdMemoryUsage"] = spill_over_threshold_memory_usage
1174
+ if spill_over_threshold_num_rows is not None:
1175
+ data["spillOverThresholdNumRows"] = spill_over_threshold_num_rows
1176
+ if stream is not None:
1177
+ data["stream"] = stream
1178
+ if use_plan_cache is not None:
1179
+ data["usePlanCache"] = use_plan_cache
1180
+ super().__init__(data)
1181
+
1182
+ @property
1183
+ def allow_dirty_reads(self) -> Optional[bool]:
1184
+ return self._data.get("allowDirtyReads")
1185
+
1186
+ @property
1187
+ def allow_retry(self) -> Optional[bool]:
1188
+ return self._data.get("allowRetry")
1189
+
1190
+ @property
1191
+ def fail_on_warning(self) -> Optional[bool]:
1192
+ return self._data.get("failOnWarning")
1193
+
1194
+ @property
1195
+ def fill_block_cache(self) -> Optional[bool]:
1196
+ return self._data.get("fillBlockCache")
1197
+
1198
+ @property
1199
+ def full_count(self) -> Optional[bool]:
1200
+ return self._data.get("fullCount")
1201
+
1202
+ @property
1203
+ def intermediate_commit_count(self) -> Optional[int]:
1204
+ return self._data.get("intermediateCommitCount")
1205
+
1206
+ @property
1207
+ def intermediate_commit_size(self) -> Optional[int]:
1208
+ return self._data.get("intermediateCommitSize")
1209
+
1210
+ @property
1211
+ def max_dnf_condition_members(self) -> Optional[int]:
1212
+ return self._data.get("maxDNFConditionMembers")
1213
+
1214
+ @property
1215
+ def max_nodes_per_callstack(self) -> Optional[int]:
1216
+ return self._data.get("maxNodesPerCallstack")
1217
+
1218
+ @property
1219
+ def max_number_of_plans(self) -> Optional[int]:
1220
+ return self._data.get("maxNumberOfPlans")
1221
+
1222
+ @property
1223
+ def max_runtime(self) -> Optional[Number]:
1224
+ return self._data.get("maxRuntime")
1225
+
1226
+ @property
1227
+ def max_transaction_size(self) -> Optional[int]:
1228
+ return self._data.get("maxTransactionSize")
1229
+
1230
+ @property
1231
+ def max_warning_count(self) -> Optional[int]:
1232
+ return self._data.get("maxWarningCount")
1233
+
1234
+ @property
1235
+ def optimizer(self) -> Optional[Json]:
1236
+ return self._data.get("optimizer")
1237
+
1238
+ @property
1239
+ def profile(self) -> Optional[int]:
1240
+ return self._data.get("profile")
1241
+
1242
+ @property
1243
+ def satellite_sync_wait(self) -> Optional[Number]:
1244
+ return self._data.get("satelliteSyncWait")
1245
+
1246
+ @property
1247
+ def skip_inaccessible_collections(self) -> Optional[bool]:
1248
+ return self._data.get("skipInaccessibleCollections")
1249
+
1250
+ @property
1251
+ def spill_over_threshold_memory_usage(self) -> Optional[int]:
1252
+ return self._data.get("spillOverThresholdMemoryUsage")
1253
+
1254
+ @property
1255
+ def spill_over_threshold_num_rows(self) -> Optional[int]:
1256
+ return self._data.get("spillOverThresholdNumRows")
1257
+
1258
+ @property
1259
+ def stream(self) -> Optional[bool]:
1260
+ return self._data.get("stream")
1261
+
1262
+ @property
1263
+ def use_plan_cache(self) -> Optional[bool]:
1264
+ return self._data.get("usePlanCache")
1265
+
1266
+
1267
+ class QueryExecutionPlan(JsonWrapper):
1268
+ """The execution plan of an AQL query.
1269
+
1270
+ References:
1271
+ - `plan <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#create-a-cursor_res_201_extra_plan>`__
1272
+ """ # noqa: E501
1273
+
1274
+ def __init__(self, data: Json) -> None:
1275
+ super().__init__(data)
1276
+
1277
+ @property
1278
+ def collections(self) -> Optional[Jsons]:
1279
+ return self._data.get("collections")
1280
+
1281
+ @property
1282
+ def estimated_cost(self) -> Optional[float]:
1283
+ return self._data.get("estimatedCost")
1284
+
1285
+ @property
1286
+ def estimated_nr_items(self) -> Optional[int]:
1287
+ return self._data.get("estimatedNrItems")
1288
+
1289
+ @property
1290
+ def is_modification_query(self) -> Optional[bool]:
1291
+ return self._data.get("isModificationQuery")
1292
+
1293
+ @property
1294
+ def nodes(self) -> Optional[Jsons]:
1295
+ return self._data.get("nodes")
1296
+
1297
+ @property
1298
+ def rules(self) -> Optional[List[str]]:
1299
+ return self._data.get("rules")
1300
+
1301
+ @property
1302
+ def variables(self) -> Optional[Jsons]:
1303
+ return self._data.get("variables")
1304
+
1305
+
1306
+ class QueryExecutionProfile(JsonWrapper):
1307
+ """The duration of the different query execution phases in seconds.
1308
+
1309
+ Example:
1310
+ .. code-block:: json
1311
+
1312
+ {
1313
+ "initializing" : 0.0000028529999838156073,
1314
+ "parsing" : 0.000029285000010759177,
1315
+ "optimizing ast" : 0.0000040699999885873694,
1316
+ "loading collections" : 0.000012807000018710823,
1317
+ "instantiating plan" : 0.00002348999998957879,
1318
+ "optimizing plan" : 0.00006598600000984334,
1319
+ "instantiating executors" : 0.000027471999999306718,
1320
+ "executing" : 0.7550992429999894,
1321
+ "finalizing" : 0.00004103500000951499
1322
+ }
1323
+
1324
+ References:
1325
+ - `profile <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#create-a-cursor_res_201_extra_profile>`__
1326
+ """ # noqa: E501
1327
+
1328
+ def __init__(self, data: Json) -> None:
1329
+ super().__init__(data)
1330
+
1331
+ @property
1332
+ def executing(self) -> Optional[float]:
1333
+ return self._data.get("executing")
1334
+
1335
+ @property
1336
+ def finalizing(self) -> Optional[float]:
1337
+ return self._data.get("finalizing")
1338
+
1339
+ @property
1340
+ def initializing(self) -> Optional[float]:
1341
+ return self._data.get("initializing")
1342
+
1343
+ @property
1344
+ def instantiating_executors(self) -> Optional[float]:
1345
+ return self._data.get("instantiating executors")
1346
+
1347
+ @property
1348
+ def instantiating_plan(self) -> Optional[float]:
1349
+ return self._data.get("instantiating plan")
1350
+
1351
+ @property
1352
+ def loading_collections(self) -> Optional[float]:
1353
+ return self._data.get("loading collections")
1354
+
1355
+ @property
1356
+ def optimizing_ast(self) -> Optional[float]:
1357
+ return self._data.get("optimizing ast")
1358
+
1359
+ @property
1360
+ def optimizing_plan(self) -> Optional[float]:
1361
+ return self._data.get("optimizing plan")
1362
+
1363
+ @property
1364
+ def parsing(self) -> Optional[float]:
1365
+ return self._data.get("parsing")
1366
+
1367
+
1368
+ class QueryExecutionStats(JsonWrapper):
1369
+ """Statistics of an AQL query.
1370
+
1371
+ Example:
1372
+ .. code-block:: json
1373
+
1374
+ {
1375
+ "writesExecuted" : 0,
1376
+ "writesIgnored" : 0,
1377
+ "documentLookups" : 0,
1378
+ "seeks" : 0,
1379
+ "scannedFull" : 2,
1380
+ "scannedIndex" : 0,
1381
+ "cursorsCreated" : 0,
1382
+ "cursorsRearmed" : 0,
1383
+ "cacheHits" : 0,
1384
+ "cacheMisses" : 0,
1385
+ "filtered" : 0,
1386
+ "httpRequests" : 0,
1387
+ "executionTime" : 0.00019362399999067748,
1388
+ "peakMemoryUsage" : 0,
1389
+ "intermediateCommits" : 0
1390
+ }
1391
+
1392
+ References:
1393
+ - `stats <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#create-a-cursor_res_201_extra_stats>`__
1394
+ """ # noqa: E501
1395
+
1396
+ def __init__(self, data: Json) -> None:
1397
+ super().__init__(data)
1398
+
1399
+ @property
1400
+ def cache_hits(self) -> Optional[int]:
1401
+ return self._data.get("cacheHits")
1402
+
1403
+ @property
1404
+ def cache_misses(self) -> Optional[int]:
1405
+ return self._data.get("cacheMisses")
1406
+
1407
+ @property
1408
+ def cursors_created(self) -> Optional[int]:
1409
+ return self._data.get("cursorsCreated")
1410
+
1411
+ @property
1412
+ def cursors_rearmed(self) -> Optional[int]:
1413
+ return self._data.get("cursorsRearmed")
1414
+
1415
+ @property
1416
+ def document_lookups(self) -> Optional[int]:
1417
+ return self._data.get("documentLookups")
1418
+
1419
+ @property
1420
+ def execution_time(self) -> Optional[float]:
1421
+ return self._data.get("executionTime")
1422
+
1423
+ @property
1424
+ def filtered(self) -> Optional[int]:
1425
+ return self._data.get("filtered")
1426
+
1427
+ @property
1428
+ def full_count(self) -> Optional[int]:
1429
+ return self._data.get("fullCount")
1430
+
1431
+ @property
1432
+ def http_requests(self) -> Optional[int]:
1433
+ return self._data.get("httpRequests")
1434
+
1435
+ @property
1436
+ def intermediate_commits(self) -> Optional[int]:
1437
+ return self._data.get("intermediateCommits")
1438
+
1439
+ @property
1440
+ def nodes(self) -> Optional[Jsons]:
1441
+ return self._data.get("nodes")
1442
+
1443
+ @property
1444
+ def peak_memory_usage(self) -> Optional[int]:
1445
+ return self._data.get("peakMemoryUsage")
1446
+
1447
+ @property
1448
+ def scanned_full(self) -> Optional[int]:
1449
+ return self._data.get("scannedFull")
1450
+
1451
+ @property
1452
+ def scanned_index(self) -> Optional[int]:
1453
+ return self._data.get("scannedIndex")
1454
+
1455
+ @property
1456
+ def seeks(self) -> Optional[int]:
1457
+ return self._data.get("seeks")
1458
+
1459
+ @property
1460
+ def writes_executed(self) -> Optional[int]:
1461
+ return self._data.get("writesExecuted")
1462
+
1463
+ @property
1464
+ def writes_ignored(self) -> Optional[int]:
1465
+ return self._data.get("writesIgnored")
1466
+
1467
+
1468
+ class QueryExecutionExtra(JsonWrapper):
1469
+ """Extra information about the query result.
1470
+
1471
+ References:
1472
+ - `extra <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#create-a-cursor_res_201_extra>`__
1473
+ """ # noqa: E501
1474
+
1475
+ def __init__(self, data: Json) -> None:
1476
+ super().__init__(data)
1477
+ self._plan = QueryExecutionPlan(data.get("plan", dict()))
1478
+ self._profile = QueryExecutionProfile(data.get("profile", dict()))
1479
+ self._stats = QueryExecutionStats(data.get("stats", dict()))
1480
+ self._warnings: Jsons = data.get("warnings", list())
1481
+
1482
+ @property
1483
+ def plan(self) -> QueryExecutionPlan:
1484
+ return self._plan
1485
+
1486
+ @property
1487
+ def profile(self) -> QueryExecutionProfile:
1488
+ return self._profile
1489
+
1490
+ @property
1491
+ def stats(self) -> QueryExecutionStats:
1492
+ return self._stats
1493
+
1494
+ @property
1495
+ def warnings(self) -> Jsons:
1496
+ return self._warnings
1497
+
1498
+
1499
+ class QueryTrackingConfiguration(JsonWrapper):
1500
+ """AQL query tracking configuration.
1501
+
1502
+ Example:
1503
+ .. code-block:: json
1504
+
1505
+ {
1506
+ "enabled": true,
1507
+ "trackSlowQueries": true,
1508
+ "trackBindVars": true,
1509
+ "maxSlowQueries": 64,
1510
+ "slowQueryThreshold": 10,
1511
+ "slowStreamingQueryThreshold": 10,
1512
+ "maxQueryStringLength": 4096
1513
+ }
1514
+
1515
+ References:
1516
+ - `get-the-aql-query-tracking-configuration <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#get-the-aql-query-tracking-configuration>`__
1517
+ """ # noqa: E501
1518
+
1519
+ def __init__(self, data: Json) -> None:
1520
+ super().__init__(data)
1521
+
1522
+ @property
1523
+ def enabled(self) -> bool:
1524
+ return cast(bool, self._data["enabled"])
1525
+
1526
+ @property
1527
+ def track_slow_queries(self) -> bool:
1528
+ return cast(bool, self._data["trackSlowQueries"])
1529
+
1530
+ @property
1531
+ def track_bind_vars(self) -> bool:
1532
+ return cast(bool, self._data["trackBindVars"])
1533
+
1534
+ @property
1535
+ def max_slow_queries(self) -> int:
1536
+ return cast(int, self._data["maxSlowQueries"])
1537
+
1538
+ @property
1539
+ def slow_query_threshold(self) -> int:
1540
+ return cast(int, self._data["slowQueryThreshold"])
1541
+
1542
+ @property
1543
+ def slow_streaming_query_threshold(self) -> Optional[int]:
1544
+ return self._data.get("slowStreamingQueryThreshold")
1545
+
1546
+ @property
1547
+ def max_query_string_length(self) -> int:
1548
+ return cast(int, self._data["maxQueryStringLength"])
1549
+
1550
+
1551
+ class QueryExplainOptions(JsonWrapper):
1552
+ """Options for explaining an AQL query.
1553
+
1554
+ Args:
1555
+ all_plans (bool | None): If set to `True`, all possible execution plans are
1556
+ returned.
1557
+ max_plans (int | None): The maximum number of plans to return.
1558
+ optimizer (dict | None): Options related to the query optimizer.
1559
+
1560
+ Example:
1561
+ .. code-block:: json
1562
+
1563
+ {
1564
+ "allPlans" : false,
1565
+ "maxNumberOfPlans" : 1,
1566
+ "optimizer" : {
1567
+ "rules" : [
1568
+ "-all",
1569
+ "+use-indexe-for-sort"
1570
+ ]
1571
+ }
1572
+ }
1573
+
1574
+ References:
1575
+ - `explain-an-aql-query <https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#explain-an-aql-query>`__
1576
+ """ # noqa: E501
1577
+
1578
+ def __init__(
1579
+ self,
1580
+ all_plans: Optional[bool] = None,
1581
+ max_plans: Optional[int] = None,
1582
+ optimizer: Optional[Json] = None,
1583
+ ) -> None:
1584
+ data: Json = dict()
1585
+ if all_plans is not None:
1586
+ data["allPlans"] = all_plans
1587
+ if max_plans is not None:
1588
+ data["maxNumberOfPlans"] = max_plans
1589
+ if optimizer is not None:
1590
+ data["optimizer"] = optimizer
1591
+ super().__init__(data)
1592
+
1593
+ @property
1594
+ def all_plans(self) -> Optional[bool]:
1595
+ return self._data.get("allPlans")
1596
+
1597
+ @property
1598
+ def max_plans(self) -> Optional[int]:
1599
+ return self._data.get("maxNumberOfPlans")
1600
+
1601
+ @property
1602
+ def optimizer(self) -> Optional[Json]:
1603
+ return self._data.get("optimizer")
1604
+
1605
+
1606
+ class QueryCacheProperties(JsonWrapper):
1607
+ """AQL Cache Configuration.
1608
+
1609
+ Example:
1610
+ .. code-block:: json
1611
+
1612
+ {
1613
+ "mode" : "demand",
1614
+ "maxResults" : 128,
1615
+ "maxResultsSize" : 268435456,
1616
+ "maxEntrySize" : 16777216,
1617
+ "includeSystem" : false
1618
+ }
1619
+
1620
+ References:
1621
+ - `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>`__
1622
+ - `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>`__
1623
+ """ # noqa: E501
1624
+
1625
+ def __init__(self, data: Json) -> None:
1626
+ super().__init__(data)
1627
+
1628
+ @property
1629
+ def mode(self) -> str:
1630
+ return cast(str, self._data.get("mode", ""))
1631
+
1632
+ @property
1633
+ def max_results(self) -> int:
1634
+ return cast(int, self._data.get("maxResults", 0))
1635
+
1636
+ @property
1637
+ def max_results_size(self) -> int:
1638
+ return cast(int, self._data.get("maxResultsSize", 0))
1639
+
1640
+ @property
1641
+ def max_entry_size(self) -> int:
1642
+ return cast(int, self._data.get("maxEntrySize", 0))
1643
+
1644
+ @property
1645
+ def include_system(self) -> bool:
1646
+ return cast(bool, self._data.get("includeSystem", False))