python-arango-async 1.2.2__tar.gz → 1.2.4__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 (115) hide show
  1. python_arango_async-1.2.4/.circleci/config.yml +200 -0
  2. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/.github/workflows/codeql.yaml +3 -3
  3. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/.github/workflows/docs.yaml +2 -2
  4. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/.github/workflows/pypi.yaml +4 -4
  5. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/PKG-INFO +3 -3
  6. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/README.md +1 -1
  7. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/aql.py +9 -0
  8. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/cluster.py +4 -0
  9. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/collection.py +62 -20
  10. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/database.py +26 -2
  11. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/foxx.py +5 -1
  12. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/replication.py +19 -3
  13. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/typings.py +6 -1
  14. python_arango_async-1.2.4/arangoasync/version.py +1 -0
  15. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/aql.rst +4 -0
  16. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/cluster.rst +0 -4
  17. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/foxx.rst +4 -0
  18. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/graph.rst +1 -1
  19. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/overview.rst +1 -1
  20. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/task.rst +4 -0
  21. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/pyproject.toml +1 -1
  22. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/python_arango_async.egg-info/PKG-INFO +3 -3
  23. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/python_arango_async.egg-info/SOURCES.txt +6 -1
  24. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/python_arango_async.egg-info/requires.txt +1 -1
  25. python_arango_async-1.2.4/python_arango_async.egg-info/scm_file_list.json +108 -0
  26. python_arango_async-1.2.4/python_arango_async.egg-info/scm_version.json +8 -0
  27. python_arango_async-1.2.4/starter.sh +84 -0
  28. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/conftest.py +25 -11
  29. python_arango_async-1.2.4/tests/static/cluster-4.0.conf +15 -0
  30. python_arango_async-1.2.4/tests/static/single-4.0.conf +14 -0
  31. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_aql.py +15 -6
  32. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_cluster.py +6 -4
  33. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_database.py +16 -29
  34. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_document.py +68 -0
  35. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_foxx.py +5 -1
  36. python_arango_async-1.2.4/tests/test_imports.py +21 -0
  37. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_task.py +5 -1
  38. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_transaction.py +5 -1
  39. python_arango_async-1.2.2/.circleci/config.yml +0 -101
  40. python_arango_async-1.2.2/arangoasync/version.py +0 -1
  41. python_arango_async-1.2.2/starter.sh +0 -60
  42. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/.gitignore +0 -0
  43. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/.pre-commit-config.yaml +0 -0
  44. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/.readthedocs.yaml +0 -0
  45. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/CONTRIBUTING.md +0 -0
  46. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/LICENSE +0 -0
  47. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/__init__.py +0 -0
  48. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/auth.py +0 -0
  49. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/backup.py +0 -0
  50. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/client.py +0 -0
  51. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/compression.py +0 -0
  52. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/connection.py +0 -0
  53. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/cursor.py +0 -0
  54. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/errno.py +0 -0
  55. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/exceptions.py +0 -0
  56. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/executor.py +0 -0
  57. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/graph.py +0 -0
  58. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/http.py +0 -0
  59. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/job.py +0 -0
  60. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/logger.py +0 -0
  61. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/request.py +0 -0
  62. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/resolver.py +0 -0
  63. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/response.py +0 -0
  64. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/result.py +0 -0
  65. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/arangoasync/serialization.py +0 -0
  66. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/admin.rst +0 -0
  67. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/analyzer.rst +0 -0
  68. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/async.rst +0 -0
  69. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/authentication.rst +0 -0
  70. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/backup.rst +0 -0
  71. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/certificates.rst +0 -0
  72. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/collection.rst +0 -0
  73. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/compression.rst +0 -0
  74. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/conf.py +0 -0
  75. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/cursor.rst +0 -0
  76. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/database.rst +0 -0
  77. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/document.rst +0 -0
  78. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/errno.rst +0 -0
  79. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/errors.rst +0 -0
  80. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/helpers.rst +0 -0
  81. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/http.rst +0 -0
  82. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/index.rst +0 -0
  83. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/indexes.rst +0 -0
  84. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/logging.rst +0 -0
  85. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/migration.rst +0 -0
  86. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/serialization.rst +0 -0
  87. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/specs.rst +0 -0
  88. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/static/logo.png +0 -0
  89. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/transaction.rst +0 -0
  90. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/user.rst +0 -0
  91. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/docs/view.rst +0 -0
  92. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/python_arango_async.egg-info/dependency_links.txt +0 -0
  93. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/python_arango_async.egg-info/top_level.txt +0 -0
  94. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/setup.cfg +0 -0
  95. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/setup.py +0 -0
  96. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/__init__.py +0 -0
  97. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/helpers.py +0 -0
  98. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/static/cluster-3.12.conf +0 -0
  99. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/static/keyfile +0 -0
  100. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/static/service.zip +0 -0
  101. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/static/single-3.12.conf +0 -0
  102. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_analyzer.py +0 -0
  103. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_async.py +0 -0
  104. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_backup.py +0 -0
  105. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_client.py +0 -0
  106. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_collection.py +0 -0
  107. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_compression.py +0 -0
  108. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_connection.py +0 -0
  109. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_cursor.py +0 -0
  110. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_graph.py +0 -0
  111. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_http.py +0 -0
  112. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_resolver.py +0 -0
  113. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_typings.py +0 -0
  114. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_user.py +0 -0
  115. {python_arango_async-1.2.2 → python_arango_async-1.2.4}/tests/test_view.py +0 -0
@@ -0,0 +1,200 @@
1
+ version: 2.1
2
+
3
+ executors:
4
+ python-container: # used by lint and import-test jobs
5
+ parameters:
6
+ python_version:
7
+ type: string
8
+ default: "3.14"
9
+ docker:
10
+ - image: cimg/python:<< parameters.python_version >>
11
+ resource_class: arangodb/small-amd64
12
+ arangodb-container: # runs integration tests
13
+ parameters:
14
+ arangodb_image:
15
+ type: string
16
+ docker:
17
+ - image: << parameters.arangodb_image >>
18
+ entrypoint: /bin/sh
19
+ command: -c "while true; do sleep 10; done"
20
+ user: root
21
+ resource_class: arangodb/medium-amd64
22
+
23
+ workflows:
24
+ ci:
25
+ jobs:
26
+ - lint
27
+ - import-test:
28
+ name: Imports (Python << matrix.python_version >>)
29
+ matrix:
30
+ parameters:
31
+ python_version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
32
+ - integration-test:
33
+ name: ArangoDB (enterprise, 3.12 << matrix.arangodb_config >>)
34
+ matrix:
35
+ parameters:
36
+ arangodb_config: ["single", "cluster"]
37
+ arangodb_image: ["arangodb/enterprise:3.12"]
38
+ arangodb_conf_version: ["3.12"]
39
+ - integration-test:
40
+ name: ArangoDB (enterprise-preview, 4.0-nightly << matrix.arangodb_config >>)
41
+ matrix:
42
+ parameters:
43
+ arangodb_config: ["single", "cluster"]
44
+ arangodb_image: ["arangodb/enterprise-preview:4.0-nightly"]
45
+ arangodb_conf_version: ["4.0"]
46
+
47
+ jobs:
48
+ lint:
49
+ executor: python-container
50
+ steps:
51
+ - checkout
52
+ - run:
53
+ name: Install Dependencies
54
+ command: python -m pip install .[dev]
55
+ - run:
56
+ name: Run black
57
+ command: black --check --verbose --diff --color --config=pyproject.toml ./arangoasync ./tests/
58
+ - run:
59
+ name: Run flake8
60
+ command: flake8 ./arangoasync ./tests
61
+ - run:
62
+ name: Run isort
63
+ command: isort --check ./arangoasync ./tests
64
+ - run:
65
+ name: Run mypy
66
+ command: mypy ./arangoasync
67
+ import-test:
68
+ parameters:
69
+ python_version:
70
+ type: string
71
+ executor:
72
+ name: python-container
73
+ python_version: << parameters.python_version >>
74
+ steps:
75
+ - checkout
76
+ - run:
77
+ name: Install Dependencies
78
+ command: |
79
+ python --version
80
+ python -m pip install .[dev]
81
+ - run:
82
+ name: Run Import Tests
83
+ command: python -m pytest tests/test_imports.py --skip-arango-setup --color=yes --code-highlight=yes
84
+ integration-test:
85
+ parameters:
86
+ arangodb_config:
87
+ type: string
88
+ arangodb_image:
89
+ type: string
90
+ arangodb_conf_version:
91
+ type: string
92
+ executor:
93
+ name: arangodb-container
94
+ arangodb_image: << parameters.arangodb_image >>
95
+ steps:
96
+ - run:
97
+ name: Bootstrap CI Tools
98
+ command: |
99
+ apk add --no-cache \
100
+ bash \
101
+ build-base \
102
+ ca-certificates \
103
+ curl \
104
+ git \
105
+ jq \
106
+ openssh-client \
107
+ openssl-dev \
108
+ py3-pip \
109
+ py3-virtualenv \
110
+ python3 \
111
+ python3-dev
112
+ - checkout
113
+ - run:
114
+ name: Setup ArangoDB
115
+ command: |
116
+ mkdir -p /tests
117
+ if [ ! -e /tests/static ]; then
118
+ ln -s "$PWD/tests/static" /tests/static
119
+ fi
120
+
121
+ conf_file="/tests/static/<< parameters.arangodb_config >>-<< parameters.arangodb_conf_version >>.conf"
122
+ if [ ! -f "$conf_file" ]; then
123
+ echo "Missing configuration file: $conf_file"
124
+ exit 1
125
+ fi
126
+
127
+ arangodb --configuration="$conf_file" > arangodb.log 2>&1 &
128
+ echo "$!" > arangodb.pid
129
+
130
+ ports="8529"
131
+ if [ << parameters.arangodb_config >> = "cluster" ]; then
132
+ ports="$ports 8539 8549"
133
+ fi
134
+
135
+ for port in $ports; do
136
+ echo "Waiting for ArangoDB at http://localhost:$port/_api/version"
137
+ for attempt in $(seq 1 120); do
138
+ if curl --fail --silent --show-error \
139
+ --user root:passwd \
140
+ "http://localhost:$port/_api/version" | jq; then
141
+ break
142
+ fi
143
+
144
+ if ! kill -0 "$(cat arangodb.pid)" 2>/dev/null; then
145
+ echo "ArangoDB process exited before port $port became ready"
146
+ exit 1
147
+ fi
148
+
149
+ if [ "$attempt" -eq 120 ]; then
150
+ echo "Timed out waiting for ArangoDB on port $port"
151
+ exit 1
152
+ fi
153
+
154
+ sleep 1
155
+ done
156
+ done
157
+ - run:
158
+ name: Show ArangoDB Logs
159
+ command: tail -n 1000 arangodb.log
160
+ when: always
161
+ - run:
162
+ name: Setup Python
163
+ shell: /bin/bash -eo pipefail
164
+ command: |
165
+ python3 --version
166
+ python3 -m virtualenv .venv
167
+ source .venv/bin/activate
168
+ python --version
169
+ python -m pip --version
170
+ - run:
171
+ name: Install Dependencies
172
+ shell: /bin/bash -eo pipefail
173
+ command: |
174
+ source .venv/bin/activate
175
+ python -m pip install -e .[dev]
176
+ - run:
177
+ name: Run pytest
178
+ shell: /bin/bash -eo pipefail
179
+ command: |
180
+ mkdir test-results
181
+ mkdir htmlcov
182
+
183
+ source .venv/bin/activate
184
+
185
+ args=("--junitxml=test-results/junit.xml" "--log-cli-level=DEBUG" "--host" "localhost" "--port=8529")
186
+ if [ << parameters.arangodb_config >> = "cluster" ]; then
187
+ args+=("--cluster" "--port=8539" "--port=8549")
188
+ fi
189
+
190
+ echo "Running pytest with args: ${args[@]}"
191
+ pytest tests --cov=arangoasync --cov-report=html:htmlcov --color=yes --code-highlight=yes "${args[@]}"
192
+ - store_artifacts:
193
+ path: htmlcov
194
+ destination: coverage-report
195
+ - store_artifacts:
196
+ path: test-results
197
+ - store_artifacts:
198
+ path: arangodb.log
199
+ - store_test_results:
200
+ path: test-results
@@ -14,10 +14,10 @@ jobs:
14
14
 
15
15
  steps:
16
16
  - name: Checkout repository
17
- uses: actions/checkout@v3
17
+ uses: actions/checkout@v7
18
18
 
19
19
  - name: Initialize CodeQL
20
- uses: github/codeql-action/init@v2
20
+ uses: github/codeql-action/init@v4
21
21
 
22
22
  - name: Perform CodeQL Analysis
23
- uses: github/codeql-action/analyze@v2
23
+ uses: github/codeql-action/analyze@v4
@@ -11,13 +11,13 @@ jobs:
11
11
 
12
12
  steps:
13
13
  - name: Checkout repository
14
- uses: actions/checkout@v4
14
+ uses: actions/checkout@v7
15
15
 
16
16
  - name: Fetch all tags and branches
17
17
  run: git fetch --prune --unshallow
18
18
 
19
19
  - name: Set up Python
20
- uses: actions/setup-python@v4
20
+ uses: actions/setup-python@v7
21
21
  with:
22
22
  python-version: '3.12'
23
23
 
@@ -10,12 +10,12 @@ jobs:
10
10
 
11
11
  steps:
12
12
  - name: Checkout repository
13
- uses: actions/checkout@v3
13
+ uses: actions/checkout@v7
14
14
  with:
15
15
  fetch-depth: 0
16
16
  fetch-tags: true
17
17
 
18
- - uses: actions/setup-python@v4
18
+ - uses: actions/setup-python@v7
19
19
  with:
20
20
  python-version: "3.12"
21
21
 
@@ -31,10 +31,10 @@ jobs:
31
31
  env:
32
32
  TWINE_USERNAME: __token__
33
33
  TWINE_PASSWORD: ${{ secrets.PYPI_TEST_TOKEN }}
34
- run: twine upload --repository testpypi dist/*
34
+ run: twine upload --verbose --repository testpypi dist/*
35
35
 
36
36
  - name: Publish to PyPI
37
37
  env:
38
38
  TWINE_USERNAME: __token__
39
39
  TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
40
- run: twine upload --repository pypi dist/*
40
+ run: twine upload --verbose --repository pypi dist/*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-arango-async
3
- Version: 1.2.2
3
+ Version: 1.2.4
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.1.0; extra == "dev"
29
+ Requires-Dist: black==26.3.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"
@@ -169,7 +169,7 @@ async def main():
169
169
  # Traverse the graph in outbound direction, breath-first.
170
170
  query = """
171
171
  FOR v, e, p IN 1..3 OUTBOUND 'students/01' GRAPH 'school'
172
- OPTIONS { bfs: true, uniqueVertices: 'global' }
172
+ OPTIONS { order: 'bfs', uniqueVertices: 'global' }
173
173
  RETURN {vertex: v, edge: e, path: p}
174
174
  """
175
175
 
@@ -127,7 +127,7 @@ async def main():
127
127
  # Traverse the graph in outbound direction, breath-first.
128
128
  query = """
129
129
  FOR v, e, p IN 1..3 OUTBOUND 'students/01' GRAPH 'school'
130
- OPTIONS { bfs: true, uniqueVertices: 'global' }
130
+ OPTIONS { order: 'bfs', uniqueVertices: 'global' }
131
131
  RETURN {vertex: v, edge: e, path: p}
132
132
  """
133
133
 
@@ -678,6 +678,9 @@ class AQL:
678
678
  async def functions(self, namespace: Optional[str] = None) -> Result[Jsons]:
679
679
  """List the registered used-defined AQL functions.
680
680
 
681
+ Warning:
682
+ AQL User Functions are no longer available in ArangoDB 4.0.
683
+
681
684
  Args:
682
685
  namespace (str | None): Returns all registered AQL user functions from
683
686
  the specified namespace.
@@ -718,6 +721,9 @@ class AQL:
718
721
  ) -> Result[Json]:
719
722
  """Registers a user-defined AQL function (UDF) written in JavaScript.
720
723
 
724
+ Warning:
725
+ AQL User Functions are no longer available in ArangoDB 4.0.
726
+
721
727
  Args:
722
728
  name (str): Name of the function.
723
729
  code (str): JavaScript code of the function.
@@ -756,6 +762,9 @@ class AQL:
756
762
  ) -> Result[Json]:
757
763
  """Remove a user-defined AQL function.
758
764
 
765
+ Warning:
766
+ AQL User Functions are no longer available in ArangoDB 4.0.
767
+
759
768
  Args:
760
769
  name (str): Name of the function.
761
770
  group (bool | None): If set to `True`, the function name is treated
@@ -64,6 +64,10 @@ class Cluster:
64
64
  async def statistics(self, db_server: str) -> Result[Json]:
65
65
  """Queries the statistics of the given DB-Server.
66
66
 
67
+ Warning:
68
+ DB-Server statistics are no longer available in ArangoDB 4.0.
69
+ Use :meth:`arangoasync.database.Database.metrics` instead.
70
+
67
71
  Args:
68
72
  db_server (str): The ID of the DB-Server.
69
73
 
@@ -194,24 +194,49 @@ class Collection(Generic[T, U, V]):
194
194
 
195
195
  return doc_id
196
196
 
197
- def _build_filter_conditions(self, filters: Optional[Json]) -> str:
197
+ @staticmethod
198
+ def _build_attribute_expression(field: str, prefix: str, bind_vars: Json) -> str:
199
+ """Build a bind-safe AQL document attribute expression."""
200
+ bind_vars[prefix] = field
201
+ field_access = f"doc[@{prefix}]"
202
+
203
+ if "." not in field:
204
+ return field_access
205
+
206
+ nested_access = "doc"
207
+ for field_index, field_part in enumerate(field.split(".")):
208
+ field_var = f"{prefix}_{field_index}"
209
+ bind_vars[field_var] = field_part
210
+ nested_access += f"[@{field_var}]"
211
+
212
+ return f"(HAS(doc, @{prefix}) ? {field_access} : {nested_access})"
213
+
214
+ def _build_filter_conditions(self, filters: Optional[Json]) -> tuple[str, Json]:
198
215
  """Build filter conditions for an AQL query.
199
216
 
200
217
  Args:
201
218
  filters (dict | None): Document filters.
202
219
 
203
220
  Returns:
204
- str: The complete AQL filter condition.
221
+ tuple: The complete AQL filter condition and its bind variables.
205
222
  """
206
223
  if not filters:
207
- return ""
224
+ return "", {}
208
225
 
209
226
  conditions = []
210
- for k, v in filters.items():
211
- field = k if "." in k else f"`{k}`"
212
- conditions.append(f"doc.{field} == {self.serializer.dumps(v)}")
227
+ bind_vars: Json = {}
228
+ for filter_index, (field, value) in enumerate(filters.items()):
229
+ field_access = self._build_attribute_expression(
230
+ field,
231
+ f"filter_field_{filter_index}",
232
+ bind_vars,
233
+ )
213
234
 
214
- return "FILTER " + " AND ".join(conditions)
235
+ value_var = f"filter_value_{filter_index}"
236
+ bind_vars[value_var] = value
237
+ conditions.append(f"{field_access} == @{value_var}")
238
+
239
+ return "FILTER " + " AND ".join(conditions), bind_vars
215
240
 
216
241
  @staticmethod
217
242
  def _is_none_or_int(obj: Any) -> bool:
@@ -259,24 +284,30 @@ class Collection(Generic[T, U, V]):
259
284
  raise SortValidationError("'sort_order' must be either 'ASC' or 'DESC'")
260
285
 
261
286
  @staticmethod
262
- def _build_sort_expression(sort: Optional[Jsons]) -> str:
287
+ def _build_sort_expression(sort: Optional[Jsons]) -> tuple[str, Json]:
263
288
  """Build a sort condition for an AQL query.
264
289
 
265
290
  Args:
266
291
  sort (list | None): Document sort parameters.
267
292
 
268
293
  Returns:
269
- str: The complete AQL sort condition.
294
+ tuple: The complete AQL sort condition and its bind variables.
270
295
  """
271
296
  if not sort:
272
- return ""
297
+ return "", {}
273
298
 
274
299
  sort_chunks = []
275
- for sort_param in sort:
276
- chunk = f"doc.{sort_param['sort_by']} {sort_param['sort_order']}"
300
+ bind_vars: Json = {}
301
+ for sort_index, sort_param in enumerate(sort):
302
+ field_access = Collection._build_attribute_expression(
303
+ sort_param["sort_by"],
304
+ f"sort_field_{sort_index}",
305
+ bind_vars,
306
+ )
307
+ chunk = f"{field_access} {sort_param['sort_order'].upper()}"
277
308
  sort_chunks.append(chunk)
278
309
 
279
- return "SORT " + ", ".join(sort_chunks)
310
+ return "SORT " + ", ".join(sort_chunks), bind_vars
280
311
 
281
312
  @property
282
313
  def name(self) -> str:
@@ -1025,14 +1056,20 @@ class Collection(Generic[T, U, V]):
1025
1056
 
1026
1057
  skip = skip if skip is not None else 0
1027
1058
  limit = limit if limit is not None else "null"
1059
+ filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
1060
+ sort_expression, sort_bind_vars = self._build_sort_expression(sort)
1028
1061
  query = f"""
1029
1062
  FOR doc IN @@collection
1030
- {self._build_filter_conditions(filters)}
1063
+ {filter_conditions}
1031
1064
  LIMIT {skip}, {limit}
1032
- {self._build_sort_expression(sort)}
1065
+ {sort_expression}
1033
1066
  RETURN doc
1034
1067
  """
1035
- bind_vars = {"@collection": self.name}
1068
+ bind_vars = {
1069
+ "@collection": self.name,
1070
+ **filter_bind_vars,
1071
+ **sort_bind_vars,
1072
+ }
1036
1073
  data: Json = {"query": query, "bindVars": bind_vars, "count": True}
1037
1074
  headers: RequestHeaders = {}
1038
1075
  if allow_dirty_read is not None:
@@ -1095,9 +1132,10 @@ class Collection(Generic[T, U, V]):
1095
1132
  raise ValueError("limit parameter must be a non-negative int")
1096
1133
 
1097
1134
  sync = f", waitForSync: {wait_for_sync}" if wait_for_sync is not None else ""
1135
+ filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
1098
1136
  query = f"""
1099
1137
  FOR doc IN @@collection
1100
- {self._build_filter_conditions(filters)}
1138
+ {filter_conditions}
1101
1139
  {f"LIMIT {limit}" if limit is not None else ""}
1102
1140
  UPDATE doc WITH @body IN @@collection
1103
1141
  OPTIONS {{ keepNull: @keep_none, mergeObjects: @merge {sync} }}
@@ -1107,6 +1145,7 @@ class Collection(Generic[T, U, V]):
1107
1145
  "body": body,
1108
1146
  "keep_none": keep_none,
1109
1147
  "merge": merge_objects,
1148
+ **filter_bind_vars,
1110
1149
  }
1111
1150
  data = {"query": query, "bindVars": bind_vars}
1112
1151
 
@@ -1151,9 +1190,10 @@ class Collection(Generic[T, U, V]):
1151
1190
  raise ValueError("limit parameter must be a non-negative int")
1152
1191
 
1153
1192
  sync = f"waitForSync: {wait_for_sync}" if wait_for_sync is not None else ""
1193
+ filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
1154
1194
  query = f"""
1155
1195
  FOR doc IN @@collection
1156
- {self._build_filter_conditions(filters)}
1196
+ {filter_conditions}
1157
1197
  {f"LIMIT {limit}" if limit is not None else ""}
1158
1198
  REPLACE doc WITH @body IN @@collection
1159
1199
  {f"OPTIONS {{ {sync} }}" if sync else ""}
@@ -1161,6 +1201,7 @@ class Collection(Generic[T, U, V]):
1161
1201
  bind_vars = {
1162
1202
  "@collection": self.name,
1163
1203
  "body": body,
1204
+ **filter_bind_vars,
1164
1205
  }
1165
1206
  data = {"query": query, "bindVars": bind_vars}
1166
1207
 
@@ -1203,14 +1244,15 @@ class Collection(Generic[T, U, V]):
1203
1244
  raise ValueError("limit parameter must be a non-negative int")
1204
1245
 
1205
1246
  sync = f"waitForSync: {wait_for_sync}" if wait_for_sync is not None else ""
1247
+ filter_conditions, filter_bind_vars = self._build_filter_conditions(filters)
1206
1248
  query = f"""
1207
1249
  FOR doc IN @@collection
1208
- {self._build_filter_conditions(filters)}
1250
+ {filter_conditions}
1209
1251
  {f"LIMIT {limit}" if limit is not None else ""}
1210
1252
  REMOVE doc IN @@collection
1211
1253
  {f"OPTIONS {{ {sync} }}" if sync else ""}
1212
1254
  """ # noqa: E201 E202
1213
- bind_vars = {"@collection": self.name}
1255
+ bind_vars = {"@collection": self.name, **filter_bind_vars}
1214
1256
  data = {"query": query, "bindVars": bind_vars}
1215
1257
 
1216
1258
  request = Request(
@@ -234,6 +234,9 @@ class Database:
234
234
  def foxx(self) -> Foxx:
235
235
  """Return Foxx API wrapper.
236
236
 
237
+ Warning:
238
+ Foxx microservice features are no longer available in ArangoDB 4.0.
239
+
237
240
  Returns:
238
241
  arangoasync.foxx.Foxx: Foxx API wrapper.
239
242
  """
@@ -2429,6 +2432,9 @@ class Database:
2429
2432
  async def tasks(self) -> Result[Jsons]:
2430
2433
  """Fetches all existing tasks from the server.
2431
2434
 
2435
+ Warning:
2436
+ Tasks are no longer available in ArangoDB 4.0.
2437
+
2432
2438
  Returns:
2433
2439
  list: List of currently active server tasks.
2434
2440
 
@@ -2451,6 +2457,9 @@ class Database:
2451
2457
  async def task(self, task_id: str) -> Result[Json]:
2452
2458
  """Return the details of an active server task.
2453
2459
 
2460
+ Warning:
2461
+ Tasks are no longer available in ArangoDB 4.0.
2462
+
2454
2463
  Args:
2455
2464
  task_id (str) -> Server task ID.
2456
2465
 
@@ -2484,6 +2493,9 @@ class Database:
2484
2493
  ) -> Result[Json]:
2485
2494
  """Create a new task.
2486
2495
 
2496
+ Warning:
2497
+ Tasks are no longer available in ArangoDB 4.0.
2498
+
2487
2499
  Args:
2488
2500
  command (str): The JavaScript code to be executed.
2489
2501
  task_id (str | None): Optional task ID. If not provided, the server will
@@ -2542,6 +2554,9 @@ class Database:
2542
2554
  ) -> Result[bool]:
2543
2555
  """Delete a server task.
2544
2556
 
2557
+ Warning:
2558
+ Tasks are no longer available in ArangoDB 4.0.
2559
+
2545
2560
  Args:
2546
2561
  task_id (str): Task ID.
2547
2562
  ignore_missing (bool): If `True`, do not raise an exception if the
@@ -2909,6 +2924,9 @@ class Database:
2909
2924
  async def reload_routing(self) -> None:
2910
2925
  """Reload the routing information.
2911
2926
 
2927
+ Warning:
2928
+ Route reloading is no longer available in ArangoDB 4.0.
2929
+
2912
2930
  Raises:
2913
2931
  ServerReloadRoutingError: If the operation fails.
2914
2932
 
@@ -2926,6 +2944,9 @@ class Database:
2926
2944
  async def echo(self, body: Optional[Json] = None) -> Result[Json]:
2927
2945
  """Return an object with the servers request information.
2928
2946
 
2947
+ Warning:
2948
+ Request echoing is no longer available in ArangoDB 4.0.
2949
+
2929
2950
  Args:
2930
2951
  body (dict | None): Optional body of the request.
2931
2952
 
@@ -2952,6 +2973,9 @@ class Database:
2952
2973
  async def execute(self, command: str) -> Result[Any]:
2953
2974
  """Execute raw Javascript command on the server.
2954
2975
 
2976
+ Warning:
2977
+ Javascript command execution is no longer available in ArangoDB 4.0.
2978
+
2955
2979
  Args:
2956
2980
  command (str): Javascript command to execute.
2957
2981
 
@@ -3004,7 +3028,7 @@ class Database:
3004
3028
  ServerMetricsError: If the operation fails.
3005
3029
 
3006
3030
  References:
3007
- - `metrics-api-v2 <https://docs.arango.ai/arangodb/stable/develop/http-api/monitoring/metrics/#metrics-api-v2>`__
3031
+ - `metrics-api <https://docs.arango.ai/arangodb/stable/develop/http-api/monitoring/metrics/#metrics-api>`__
3008
3032
  """ # noqa: E501
3009
3033
  params: Params = {}
3010
3034
  if server_id is not None:
@@ -3012,7 +3036,7 @@ class Database:
3012
3036
 
3013
3037
  request = Request(
3014
3038
  method=Method.GET,
3015
- endpoint="/_admin/metrics/v2",
3039
+ endpoint="/_admin/metrics",
3016
3040
  params=params,
3017
3041
  )
3018
3042
 
@@ -34,7 +34,11 @@ from arangoasync.typings import Json, Jsons, Params, RequestHeaders
34
34
 
35
35
 
36
36
  class Foxx:
37
- """Foxx API wrapper."""
37
+ """Foxx API wrapper.
38
+
39
+ Warning:
40
+ Foxx microservice features are no longer available in ArangoDB 4.0.
41
+ """
38
42
 
39
43
  def __init__(self, executor: ApiExecutor) -> None:
40
44
  self._executor = executor