python-arango-async 1.2.4__tar.gz → 1.2.5__tar.gz

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.
Files changed (114) hide show
  1. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/.circleci/config.yml +10 -3
  2. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/PKG-INFO +2 -2
  3. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/typings.py +12 -0
  4. python_arango_async-1.2.5/arangoasync/version.py +1 -0
  5. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/indexes.rst +39 -0
  6. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/pyproject.toml +1 -1
  7. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/python_arango_async.egg-info/PKG-INFO +2 -2
  8. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/python_arango_async.egg-info/requires.txt +1 -1
  9. python_arango_async-1.2.5/python_arango_async.egg-info/scm_version.json +8 -0
  10. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_collection.py +120 -8
  11. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_typings.py +26 -0
  12. python_arango_async-1.2.4/arangoasync/version.py +0 -1
  13. python_arango_async-1.2.4/python_arango_async.egg-info/scm_version.json +0 -8
  14. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/.github/workflows/codeql.yaml +0 -0
  15. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/.github/workflows/docs.yaml +0 -0
  16. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/.github/workflows/pypi.yaml +0 -0
  17. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/.gitignore +0 -0
  18. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/.pre-commit-config.yaml +0 -0
  19. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/.readthedocs.yaml +0 -0
  20. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/CONTRIBUTING.md +0 -0
  21. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/LICENSE +0 -0
  22. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/README.md +0 -0
  23. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/__init__.py +0 -0
  24. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/aql.py +0 -0
  25. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/auth.py +0 -0
  26. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/backup.py +0 -0
  27. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/client.py +0 -0
  28. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/cluster.py +0 -0
  29. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/collection.py +0 -0
  30. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/compression.py +0 -0
  31. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/connection.py +0 -0
  32. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/cursor.py +0 -0
  33. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/database.py +0 -0
  34. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/errno.py +0 -0
  35. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/exceptions.py +0 -0
  36. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/executor.py +0 -0
  37. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/foxx.py +0 -0
  38. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/graph.py +0 -0
  39. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/http.py +0 -0
  40. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/job.py +0 -0
  41. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/logger.py +0 -0
  42. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/replication.py +0 -0
  43. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/request.py +0 -0
  44. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/resolver.py +0 -0
  45. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/response.py +0 -0
  46. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/result.py +0 -0
  47. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/arangoasync/serialization.py +0 -0
  48. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/admin.rst +0 -0
  49. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/analyzer.rst +0 -0
  50. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/aql.rst +0 -0
  51. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/async.rst +0 -0
  52. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/authentication.rst +0 -0
  53. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/backup.rst +0 -0
  54. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/certificates.rst +0 -0
  55. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/cluster.rst +0 -0
  56. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/collection.rst +0 -0
  57. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/compression.rst +0 -0
  58. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/conf.py +0 -0
  59. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/cursor.rst +0 -0
  60. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/database.rst +0 -0
  61. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/document.rst +0 -0
  62. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/errno.rst +0 -0
  63. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/errors.rst +0 -0
  64. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/foxx.rst +0 -0
  65. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/graph.rst +0 -0
  66. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/helpers.rst +0 -0
  67. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/http.rst +0 -0
  68. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/index.rst +0 -0
  69. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/logging.rst +0 -0
  70. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/migration.rst +0 -0
  71. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/overview.rst +0 -0
  72. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/serialization.rst +0 -0
  73. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/specs.rst +0 -0
  74. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/static/logo.png +0 -0
  75. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/task.rst +0 -0
  76. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/transaction.rst +0 -0
  77. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/user.rst +0 -0
  78. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/docs/view.rst +0 -0
  79. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/python_arango_async.egg-info/SOURCES.txt +0 -0
  80. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/python_arango_async.egg-info/dependency_links.txt +0 -0
  81. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/python_arango_async.egg-info/scm_file_list.json +0 -0
  82. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/python_arango_async.egg-info/top_level.txt +0 -0
  83. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/setup.cfg +0 -0
  84. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/setup.py +0 -0
  85. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/starter.sh +0 -0
  86. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/__init__.py +0 -0
  87. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/conftest.py +0 -0
  88. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/helpers.py +0 -0
  89. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/static/cluster-3.12.conf +0 -0
  90. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/static/cluster-4.0.conf +0 -0
  91. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/static/keyfile +0 -0
  92. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/static/service.zip +0 -0
  93. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/static/single-3.12.conf +0 -0
  94. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/static/single-4.0.conf +0 -0
  95. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_analyzer.py +0 -0
  96. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_aql.py +0 -0
  97. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_async.py +0 -0
  98. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_backup.py +0 -0
  99. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_client.py +0 -0
  100. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_cluster.py +0 -0
  101. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_compression.py +0 -0
  102. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_connection.py +0 -0
  103. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_cursor.py +0 -0
  104. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_database.py +0 -0
  105. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_document.py +0 -0
  106. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_foxx.py +0 -0
  107. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_graph.py +0 -0
  108. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_http.py +0 -0
  109. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_imports.py +0 -0
  110. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_resolver.py +0 -0
  111. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_task.py +0 -0
  112. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_transaction.py +0 -0
  113. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_user.py +0 -0
  114. {python_arango_async-1.2.4 → python_arango_async-1.2.5}/tests/test_view.py +0 -0
@@ -37,12 +37,19 @@ workflows:
37
37
  arangodb_image: ["arangodb/enterprise:3.12"]
38
38
  arangodb_conf_version: ["3.12"]
39
39
  - integration-test:
40
- name: ArangoDB (enterprise-preview, 4.0-nightly << matrix.arangodb_config >>)
40
+ name: ArangoDB (core-preview, 4.0-nightly << matrix.arangodb_config >>)
41
+ matrix:
42
+ parameters:
43
+ arangodb_config: [ "single", "cluster" ]
44
+ arangodb_image: [ "arangodb/core-preview:4.0-nightly" ]
45
+ arangodb_conf_version: [ "4.0" ]
46
+ - integration-test:
47
+ name: ArangoDB (enterprise-preview, 3.12-nightly << matrix.arangodb_config >>)
41
48
  matrix:
42
49
  parameters:
43
50
  arangodb_config: ["single", "cluster"]
44
- arangodb_image: ["arangodb/enterprise-preview:4.0-nightly"]
45
- arangodb_conf_version: ["4.0"]
51
+ arangodb_image: ["arangodb/enterprise-preview:3.12-nightly"]
52
+ arangodb_conf_version: ["3.12"]
46
53
 
47
54
  jobs:
48
55
  lint:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-arango-async
3
- Version: 1.2.4
3
+ Version: 1.2.5
4
4
  Summary: Async Python Driver for ArangoDB
5
5
  Author-email: Alexandru Petenchea <alexandru.petenchea@arangodb.com>, Anthony Mahanna <anthony.mahanna@arangodb.com>
6
6
  Maintainer-email: Alexandru Petenchea <alexandru.petenchea@arangodb.com>, Anthony Mahanna <anthony.mahanna@arangodb.com>
@@ -26,7 +26,7 @@ Requires-Dist: multidict>=6.0
26
26
  Requires-Dist: pyjwt>=2.10.0
27
27
  Provides-Extra: dev
28
28
  Requires-Dist: aiofiles>=24.1.0; extra == "dev"
29
- Requires-Dist: black==26.3.1; extra == "dev"
29
+ Requires-Dist: black==26.5.1; extra == "dev"
30
30
  Requires-Dist: flake8==7.3.0; extra == "dev"
31
31
  Requires-Dist: isort>=5.10.1; extra == "dev"
32
32
  Requires-Dist: mypy==1.15.0; extra == "dev"
@@ -1060,6 +1060,10 @@ class IndexProperties(JsonWrapper):
1060
1060
  def legacy_polygons(self) -> Optional[bool]:
1061
1061
  return self._data.get("legacyPolygons")
1062
1062
 
1063
+ @property
1064
+ def figures(self) -> Optional[Json]:
1065
+ return self._data.get("figures")
1066
+
1063
1067
  @property
1064
1068
  def estimates(self) -> Optional[bool]:
1065
1069
  return self._data.get("estimates")
@@ -1140,6 +1144,10 @@ class IndexProperties(JsonWrapper):
1140
1144
  def training_state(self) -> Optional[str]:
1141
1145
  return self._data.get("trainingState")
1142
1146
 
1147
+ @property
1148
+ def shards(self) -> Optional[Json]:
1149
+ return self._data.get("shards")
1150
+
1143
1151
  @staticmethod
1144
1152
  def compatibility_formatter(data: Json) -> Json:
1145
1153
  """python-arango compatibility formatter."""
@@ -1170,6 +1178,8 @@ class IndexProperties(JsonWrapper):
1170
1178
  result["storedValues"] = data["storedValues"]
1171
1179
  if "legacyPolygons" in data:
1172
1180
  result["legacyPolygons"] = data["legacyPolygons"]
1181
+ if "figures" in data:
1182
+ result["figures"] = data["figures"]
1173
1183
  if "estimates" in data:
1174
1184
  result["estimates"] = data["estimates"]
1175
1185
  if "analyzer" in data:
@@ -1202,6 +1212,8 @@ class IndexProperties(JsonWrapper):
1202
1212
  result["error_message"] = data["errorMessage"]
1203
1213
  if "trainingState" in data:
1204
1214
  result["training_state"] = data["trainingState"]
1215
+ if "shards" in data:
1216
+ result["shards"] = data["shards"]
1205
1217
  return result
1206
1218
 
1207
1219
  def format(self, formatter: Optional[Formatter] = None) -> Json:
@@ -0,0 +1 @@
1
+ __version__ = "1.2.5"
@@ -50,4 +50,43 @@ on fields ``_from`` and ``_to``. For more information on indexes, refer to
50
50
  # Delete the last index from the collection.
51
51
  await cities.delete_index(index["id"])
52
52
 
53
+ # Insert documents with vector embeddings.
54
+ await cities.insert_many([
55
+ {
56
+ "_key": f"city{i}",
57
+ "continent": f"continent{i}",
58
+ "country": f"country{i}",
59
+ "population": i,
60
+ "coordinates": [float(i % 180), float(i % 90)],
61
+ "embedding": [float(i), float(i % 7), float(i % 11), 1.0],
62
+ }
63
+ for i in range(100)
64
+ ])
65
+
66
+ # Let ArangoDB determine the number of vector-index centroids.
67
+ vector_index = await cities.add_index(
68
+ type="vector",
69
+ fields=["embedding"],
70
+ options={
71
+ "name": "vector_index",
72
+ "params": {
73
+ "metric": "cosine",
74
+ "dimension": 4,
75
+ },
76
+ },
77
+ )
78
+
79
+ # Index creation may succeed even if vector training fails.
80
+ if vector_index.training_state != "ready":
81
+ raise RuntimeError(
82
+ vector_index.error_message or "Vector index is not ready"
83
+ )
84
+
85
+ Omitted or scaling-object ``nLists``, ``numberOfDocsPerCentroid``, factory
86
+ placeholders such as ``IVF{},Flat``, and successful-but-unusable creation
87
+ behavior require ArangoDB 3.12.10 or later. A successful creation response
88
+ means that the index exists, but callers should check ``training_state`` before
89
+ using it. If training fails permanently, the state is ``"unusable"`` and
90
+ ``error_message`` describes the failure.
91
+
53
92
  See :class:`arangoasync.collection.StandardCollection` for API specification.
@@ -49,7 +49,7 @@ version = { attr = "arangoasync.version.__version__" }
49
49
  [project.optional-dependencies]
50
50
  dev = [
51
51
  "aiofiles>=24.1.0",
52
- "black==26.3.1",
52
+ "black==26.5.1",
53
53
  "flake8==7.3.0",
54
54
  "isort>=5.10.1",
55
55
  "mypy==1.15.0",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-arango-async
3
- Version: 1.2.4
3
+ Version: 1.2.5
4
4
  Summary: Async Python Driver for ArangoDB
5
5
  Author-email: Alexandru Petenchea <alexandru.petenchea@arangodb.com>, Anthony Mahanna <anthony.mahanna@arangodb.com>
6
6
  Maintainer-email: Alexandru Petenchea <alexandru.petenchea@arangodb.com>, Anthony Mahanna <anthony.mahanna@arangodb.com>
@@ -26,7 +26,7 @@ Requires-Dist: multidict>=6.0
26
26
  Requires-Dist: pyjwt>=2.10.0
27
27
  Provides-Extra: dev
28
28
  Requires-Dist: aiofiles>=24.1.0; extra == "dev"
29
- Requires-Dist: black==26.3.1; extra == "dev"
29
+ Requires-Dist: black==26.5.1; extra == "dev"
30
30
  Requires-Dist: flake8==7.3.0; extra == "dev"
31
31
  Requires-Dist: isort>=5.10.1; extra == "dev"
32
32
  Requires-Dist: mypy==1.15.0; extra == "dev"
@@ -5,7 +5,7 @@ pyjwt>=2.10.0
5
5
 
6
6
  [dev]
7
7
  aiofiles>=24.1.0
8
- black==26.3.1
8
+ black==26.5.1
9
9
  flake8==7.3.0
10
10
  isort>=5.10.1
11
11
  mypy==1.15.0
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.2.5",
3
+ "distance": 0,
4
+ "node": "g7efe263be99ae30c006413fc1b608b286d7021c1",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-08-31"
8
+ }
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
 
3
3
  import pytest
4
+ from packaging import version
4
5
 
5
6
  from arangoasync.errno import DATA_SOURCE_NOT_FOUND, INDEX_NOT_FOUND
6
7
  from arangoasync.exceptions import (
@@ -113,11 +114,11 @@ async def test_collection_rename(cluster, db, bad_col, docs):
113
114
  doc = await col.insert(docs[0])
114
115
  assert col.get_col_name(doc) == new_name
115
116
  finally:
116
- db.delete_collection(new_name, ignore_missing=True)
117
+ await db.delete_collection(new_name, ignore_missing=True)
117
118
 
118
119
 
119
120
  @pytest.mark.asyncio
120
- async def test_collection_index(doc_col, bad_col, cluster):
121
+ async def test_collection_index(doc_col, bad_col, cluster, db_version):
121
122
  # Create indexes
122
123
  idx1 = await doc_col.add_index(
123
124
  type="persistent",
@@ -228,16 +229,22 @@ async def test_collection_index(doc_col, bad_col, cluster):
228
229
  await bad_col.load_indexes()
229
230
  assert err.value.error_code == DATA_SOURCE_NOT_FOUND
230
231
 
231
- # Create a vector index
232
+ # Create vector indexes using the fixed nLists format supported by older servers.
232
233
  docs = []
233
234
  for key in range(100):
234
- docs.append({"_key": f"key_{key}", "embedding": [1] * 128})
235
+ docs.append(
236
+ {
237
+ "_key": f"key_{key}",
238
+ "embedding1": [1] * 128,
239
+ "embedding2": [1] * 128,
240
+ }
241
+ )
235
242
  await doc_col.insert_many(docs)
236
243
  idx4 = await doc_col.add_index(
237
244
  "vector",
238
- ["embedding"],
245
+ ["embedding1"],
239
246
  {
240
- "name": "vector_index",
247
+ "name": "vector_index_1",
241
248
  "params": {
242
249
  "metric": "cosine",
243
250
  "dimension": 128,
@@ -245,19 +252,124 @@ async def test_collection_index(doc_col, bad_col, cluster):
245
252
  },
246
253
  },
247
254
  )
248
- assert idx4.name == "vector_index"
255
+ idx5 = await doc_col.add_index(
256
+ "vector",
257
+ ["embedding2"],
258
+ {
259
+ "name": "vector_index_2",
260
+ "params": {
261
+ "metric": "cosine",
262
+ "dimension": 128,
263
+ "nLists": 3,
264
+ },
265
+ },
266
+ )
267
+ assert idx4.name == "vector_index_1"
268
+ assert idx5.name == "vector_index_2"
269
+
270
+ if db_version >= version.parse("3.12.10"):
271
+ # Hidden listing details expose resolved vector-index settings per shard.
272
+ indexes = {idx.id: idx for idx in await doc_col.indexes(with_hidden=True)}
273
+ for index in (idx4, idx5):
274
+ shards = indexes[index.id].shards
275
+ assert shards is not None
276
+ for status in shards.values():
277
+ assert {
278
+ "trainingState",
279
+ "error",
280
+ "resolvedNLists",
281
+ } <= status.keys()
282
+ assert isinstance(status["resolvedNLists"], int)
249
283
 
250
284
  # Delete indexes
251
- del1, del2, del3, del4 = await asyncio.gather(
285
+ del1, del2, del3, del4, del5 = await asyncio.gather(
252
286
  doc_col.delete_index(idx1.id),
253
287
  doc_col.delete_index(idx2.numeric_id),
254
288
  doc_col.delete_index(str(idx3.numeric_id)),
255
289
  doc_col.delete_index(idx4.id),
290
+ doc_col.delete_index(idx5.id),
256
291
  )
257
292
  assert del1 is True
258
293
  assert del2 is True
259
294
  assert del3 is True
260
295
  assert del4 is True
296
+ assert del5 is True
297
+
298
+ if db_version >= version.parse("3.12.10"):
299
+ # Let the server choose nLists, then supply an explicit scaling object.
300
+ scaling_n_lists = {
301
+ "strategy": "autoSqrt",
302
+ "multiplier": 1,
303
+ "minNLists": 2,
304
+ "tiers": [],
305
+ }
306
+ default_index = await doc_col.add_index(
307
+ "vector",
308
+ ["embedding1"],
309
+ {
310
+ "name": "vector_index_default",
311
+ "params": {"metric": "cosine", "dimension": 128},
312
+ },
313
+ )
314
+ scaling_index = await doc_col.add_index(
315
+ "vector",
316
+ ["embedding2"],
317
+ {
318
+ "name": "vector_index_scaling",
319
+ "params": {
320
+ "metric": "cosine",
321
+ "dimension": 128,
322
+ "nLists": scaling_n_lists,
323
+ "numberOfDocsPerCentroid": 10,
324
+ "factory": "IVF{},Flat",
325
+ },
326
+ },
327
+ )
328
+
329
+ default_n_lists = default_index["params"]["nLists"]
330
+ assert default_n_lists["strategy"] == "autoSqrt"
331
+ assert default_n_lists["multiplier"] == 4
332
+ assert default_n_lists["minNLists"] == 2
333
+ assert scaling_index["params"]["nLists"] == scaling_n_lists
334
+ assert scaling_index["params"]["numberOfDocsPerCentroid"] == 10
335
+ assert scaling_index["params"]["factory"] == "IVF{},Flat"
336
+
337
+ await doc_col.delete_index(default_index.id)
338
+ await doc_col.delete_index(scaling_index.id)
339
+
340
+ # A permanent training failure still creates an unusable index.
341
+ unusable_index = await doc_col.add_index(
342
+ "vector",
343
+ ["embedding1"],
344
+ {
345
+ "name": "vector_index_unusable",
346
+ "params": {
347
+ "metric": "cosine",
348
+ "dimension": 128,
349
+ "nLists": 2,
350
+ "factory": "IVF3,Flat",
351
+ },
352
+ },
353
+ )
354
+ assert unusable_index.training_state == "unusable"
355
+ assert unusable_index.error_message
356
+ await doc_col.delete_index(unusable_index.id)
357
+
358
+ # Invalid requests continue to fail at the HTTP layer.
359
+ with pytest.raises(IndexCreateError) as err:
360
+ await doc_col.add_index(
361
+ "vector",
362
+ ["embedding1"],
363
+ {
364
+ "name": "vector_index_invalid",
365
+ "params": {
366
+ "metric": "cosine",
367
+ "dimension": 128,
368
+ "nLists": 0,
369
+ },
370
+ },
371
+ )
372
+ assert err.value.http_code == 400
261
373
 
262
374
  # Now, the indexes should be gone
263
375
  with pytest.raises(IndexDeleteError) as err:
@@ -9,6 +9,7 @@ from arangoasync.typings import (
9
9
  EdgeDefinitionOptions,
10
10
  GraphOptions,
11
11
  GraphProperties,
12
+ IndexProperties,
12
13
  JsonWrapper,
13
14
  KeyOptions,
14
15
  QueryCacheProperties,
@@ -449,6 +450,31 @@ def test_CollectionStatistics():
449
450
  assert stats.object_id == "69124"
450
451
 
451
452
 
453
+ def test_IndexProperties_hidden_details():
454
+ shards = {
455
+ "s1001": {
456
+ "trainingState": "ready",
457
+ "error": False,
458
+ "resolvedNLists": 4,
459
+ }
460
+ }
461
+ figures = {"memory": 4096}
462
+ properties = IndexProperties(
463
+ {
464
+ "id": "products/123",
465
+ "fields": ["embedding"],
466
+ "type": "vector",
467
+ "figures": figures,
468
+ "shards": shards,
469
+ }
470
+ )
471
+
472
+ assert properties.figures == figures
473
+ assert properties.shards == shards
474
+ assert properties.format()["figures"] == figures
475
+ assert properties.format()["shards"] == shards
476
+
477
+
452
478
  def test_AccessToken():
453
479
  data = {
454
480
  "active": True,
@@ -1 +0,0 @@
1
- __version__ = "1.2.4"
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "1.2.4",
3
- "distance": 0,
4
- "node": "gd2c85b0dbb7f6071b7b8711c42d4d26898ffff1f",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-08-25"
8
- }