Skip to content

Commit 9d2d82d

Browse files
tae898Copilot
andcommitted
Refactor edge type creation to remove UNIDIRECTIONAL specification
- Updated tests to create edge types without UNIDIRECTIONAL keyword. - Added tests for OpenCypher index creation, constraints, and DDL operations. - Enhanced vector index tests to include custom ID properties and metadata. - Improved error handling and assertions in document import tests. - Added tests for vector neighbors functionality using both SQL and OpenCypher. Co-authored-by: Copilot <copilot@github.com>
1 parent 497fb7b commit 9d2d82d

57 files changed

Lines changed: 10110 additions & 1169 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test-python-bindings.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ on:
55
push:
66
paths:
77
- 'bindings/python/**'
8+
- '**/*.java'
89
- '.github/workflows/test-python-bindings.yml'
910

1011
# Run on pull request affecting bindings/python/
1112
pull_request:
1213
paths:
1314
- 'bindings/python/**'
15+
- '**/*.java'
1416
- '.github/workflows/test-python-bindings.yml'
1517

1618
# Run after release workflow completes
@@ -50,7 +52,7 @@ jobs:
5052
cd bindings/python
5153
5254
# Detect ArcadeDB version from pom.xml (Docker format: X.Y.Z-SNAPSHOT)
53-
ARCADEDB_TAG=$(python3 extract_version.py --format=docker)
55+
ARCADEDB_TAG=$(python3 scripts/extract_version.py --format=docker)
5456
echo "📌 ArcadeDB version: $ARCADEDB_TAG"
5557
5658
# Download JARs from official Docker image
@@ -208,7 +210,7 @@ jobs:
208210
run: |
209211
cd bindings/python
210212
echo "🔨 Building arcadedb-embedded for ${{ matrix.platform }} with Python ${{ matrix.python-version }}..."
211-
./build.sh ${{ matrix.platform }} ${{ matrix.python-version }}
213+
./scripts/build.sh ${{ matrix.platform }} ${{ matrix.python-version }}
212214
213215
- name: Extract wheel for additional testing
214216
shell: bash

.github/workflows/test-python-examples.yml

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ on:
55
push:
66
paths:
77
- 'bindings/python/**'
8+
- '**/*.java'
89
- '.github/workflows/test-python-examples.yml'
910

1011
# Run on pull request affecting bindings/python/
1112
pull_request:
1213
paths:
1314
- 'bindings/python/**'
15+
- '**/*.java'
1416
- '.github/workflows/test-python-examples.yml'
1517

1618
# Run after release workflow completes
@@ -25,7 +27,7 @@ on:
2527
description: "Glob pattern(s) for examples to run (space-separated, relative to bindings/python/examples)."
2628
required: false
2729
type: string
28-
default: "0[1-9]_*.py 1[0-6]_*.py"
30+
default: "0[1-9]_*.py 1[0-9]_*.py 2[0-9]_*.py"
2931
build-version:
3032
description: "Override package version (PEP 440) for build.sh"
3133
required: false
@@ -37,10 +39,14 @@ on:
3739
examples:
3840
description: "Glob pattern(s) for examples to run (space-separated, relative to bindings/python/examples)."
3941
required: false
40-
default: "0[1-9]_*.py 1[0-6]_*.py"
42+
default: "0[1-9]_*.py 1[0-9]_*.py 2[0-9]_*.py"
4143

4244
env:
43-
EXAMPLES: ${{ inputs.examples || '0[1-9]_*.py 1[0-6]_*.py' }}
45+
EXAMPLES: ${{ inputs.examples || '0[1-9]_*.py 1[0-9]_*.py 2[0-9]_*.py' }}
46+
47+
# Note: Example 21 is intentionally excluded in CI.
48+
# It has shown repeated GitHub Actions instability across platforms despite
49+
# timeout increases, so the workflow skips it explicitly below.
4450

4551
permissions:
4652
contents: read
@@ -63,7 +69,7 @@ jobs:
6369
cd bindings/python
6470
6571
# Detect ArcadeDB version from pom.xml (Docker format: X.Y.Z-SNAPSHOT)
66-
ARCADEDB_TAG=$(python3 extract_version.py --format=docker)
72+
ARCADEDB_TAG=$(python3 scripts/extract_version.py --format=docker)
6773
echo "📌 ArcadeDB version: $ARCADEDB_TAG"
6874
6975
# Download JARs from official Docker image
@@ -207,7 +213,7 @@ jobs:
207213
run: |
208214
cd bindings/python
209215
echo "🔨 Building arcadedb-embedded for ${{ matrix.platform }} with Python ${{ matrix.python-version }}..."
210-
./build.sh ${{ matrix.platform }} ${{ matrix.python-version }}
216+
./scripts/build.sh ${{ matrix.platform }} ${{ matrix.python-version }}
211217
212218
# Note: Java is NOT required - arcadedb-embedded has bundled JRE!
213219

@@ -311,6 +317,14 @@ jobs:
311317
312318
# Set example-specific parameters and timeout
313319
case "$example" in
320+
"21_server_mode_http_access.py")
321+
# Example 21 is kept in the repo for local/manual use, but is
322+
# excluded from GitHub Actions because it is CI-unstable.
323+
echo "⏭️ SKIPPED: $example (excluded from GitHub Actions due to CI instability)" | tee -a $results_file
324+
skipped=$((skipped + 1))
325+
echo ""
326+
continue
327+
;;
314328
"04_csv_import_documents.py")
315329
example_args="--dataset movielens-small --export"
316330
example_name="$example (movielens-small dataset with export)"
@@ -396,6 +410,30 @@ jobs:
396410
timeout_duration=1200
397411
example_jvm_args=""
398412
;;
413+
"17_timeseries_end_to_end.py")
414+
example_args="--hours 2 --interval-minutes 10"
415+
example_name="$example (time-series end-to-end, minimal)"
416+
timeout_duration=900
417+
example_jvm_args=""
418+
;;
419+
"18_geo_predicates_wkt.py")
420+
example_args=""
421+
example_name="$example (geo predicates with WKT points and polygons)"
422+
timeout_duration=900
423+
example_jvm_args=""
424+
;;
425+
"19_hash_index_exact_match.py")
426+
example_args=""
427+
example_name="$example (hash index exact-match workflow)"
428+
timeout_duration=900
429+
example_jvm_args=""
430+
;;
431+
"20_graph_algorithms_route_planning.py")
432+
example_args=""
433+
example_name="$example (graph algorithms route planning workflow)"
434+
timeout_duration=900
435+
example_jvm_args=""
436+
;;
399437
*)
400438
example_args=""
401439
example_name="$example"

bindings/python/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,7 @@ notebooks/
4545

4646
# local built jars
4747
local-jars/
48+
.runtime-cache/
49+
50+
# test databases
51+
my_test_databases/

bindings/python/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Native Python bindings for ArcadeDB - the multi-model database that supports Graph, Document, Key/Value, Search Engine, Time Series, and Vector models.
44

5-
**Status**: ✅ Production Ready | **Tests**: 282 Passed | **Platforms**: 4 Supported
5+
**Status**: ✅ Production Ready | **Tests**: 290 Passed | **Platforms**: 4 Supported
66

77
---
88

@@ -84,15 +84,15 @@ The `arcadedb-embedded` package is platform-specific and self-contained:
8484
The compressed wheel size is measured from `dist/*.whl`, and the installed package size
8585
is measured from the extracted `site-packages/arcadedb_embedded/` directory.
8686

87-
**Note**: Some JARs are excluded to optimize package size (e.g., gRPC wire protocol). See [`jar_exclusions.txt`](https://github.com/humemai/arcadedb-embedded-python/blob/main/bindings/python/jar_exclusions.txt) for details.
87+
**Note**: Some JARs are excluded to optimize package size (e.g., gRPC wire protocol). See [`scripts/jar_exclusions.txt`](https://github.com/humemai/arcadedb-embedded-python/blob/main/bindings/python/scripts/jar_exclusions.txt) for details.
8888

8989
Import: `import arcadedb_embedded as arcadedb`
9090

9191
---
9292

9393
## 🧪 Testing
9494

95-
**Status**: 282 passed
95+
**Status**: 290 passed
9696

9797
```bash
9898
# Run all tests
@@ -125,7 +125,7 @@ uv pip install build
125125
uv pip install -e ".[test]"
126126

127127
# Build for your current platform (auto-detected)
128-
./build.sh
128+
./scripts/build.sh
129129
```
130130

131131
Built wheels will be in `dist/`.

bindings/python/examples/02_social_network_graph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def create_schema(db):
131131
print(" ✓ Created Person properties (including optional fields)")
132132

133133
# Create FRIEND_OF edge type
134-
db.command("sql", "CREATE EDGE TYPE FRIEND_OF UNIDIRECTIONAL")
134+
db.command("sql", "CREATE EDGE TYPE FRIEND_OF")
135135
print(" ✓ Created FRIEND_OF edge type")
136136

137137
# Create properties for FRIEND_OF edge

bindings/python/examples/03_vector_search.py

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -221,19 +221,20 @@ def create_mock_embedding(category_seed, doc_seed):
221221
print(" • beam_width: 256 (search quality, higher = more accurate)")
222222
print()
223223

224-
# Create vector index (JVector implementation - recommended)
225-
# Using new defaults: max_connections=32, beam_width=256
226-
# New options available:
227-
# - quantization: "INT8" or "BINARY" (reduces memory usage)
228-
# - store_vectors_in_graph: True (faster search, higher disk usage)
229-
index = db.create_vector_index(
230-
vertex_type="Article",
231-
vector_property="embedding",
232-
dimensions=EMBEDDING_DIM,
233-
distance_function="cosine",
224+
db.command(
225+
"sql",
226+
f"""
227+
CREATE INDEX ON Article (embedding)
228+
LSM_VECTOR
229+
METADATA {{
230+
"dimensions": {EMBEDDING_DIM},
231+
"similarity": "COSINE"
232+
}}
233+
""",
234234
)
235235

236236
print(" ✅ Created JVector vector index")
237+
print(" ✅ Built vector index graph immediately via SQL")
237238
print(" 💡 LSM index automatically indexes existing records upon creation.")
238239
print(" ✅ Indexing handled by ArcadeDB engine.")
239240
print(f" ⏱️ Time: {time.time() - step_start:.3f}s")
@@ -262,29 +263,48 @@ def create_mock_embedding(category_seed, doc_seed):
262263

263264
query_embedding = create_mock_embedding(category, f"query{query_num}")
264265

265-
# Get top 5 most similar (smallest distances)
266-
most_similar = index.find_nearest(query_embedding, k=5)
266+
qvec_literal = (
267+
"[" + ", ".join(str(float(x)) for x in query_embedding.tolist()) + "]"
268+
)
269+
most_similar = db.query(
270+
"sql",
271+
(
272+
"SELECT title, category, distance, (1 - distance) AS score "
273+
"FROM (SELECT expand(vectorNeighbors('Article[embedding]', "
274+
f"{qvec_literal}, 5))) ORDER BY distance"
275+
),
276+
).to_list()
267277

268278
print(" Top 5 MOST similar documents (smallest distance):")
269-
for i, (vertex, distance) in enumerate(most_similar, 1):
270-
title = vertex.get("title")
271-
doc_category = vertex.get("category")
279+
for i, hit in enumerate(most_similar, 1):
280+
title = hit.get("title")
281+
doc_category = hit.get("category")
282+
distance = hit.get("distance")
272283
print(f" {i}. {title}")
273284
print(f" Category: {doc_category}, Distance: {distance:.4f}")
274285
print()
275286

276-
# Get all documents to find least similar
277-
# Note: For LSM, getting ALL documents might be slow or limited by k
278-
k_limit = min(NUM_DOCUMENTS, 1000)
279-
all_results = index.find_nearest(query_embedding, k=k_limit)
280-
least_similar = list(all_results)[-5:] # Last 5 = farthest
281-
282-
print(" Top 5 LEAST similar documents (largest distance):")
283-
for i, (vertex, distance) in enumerate(least_similar, 1):
284-
title = vertex.get("title")
285-
doc_category = vertex.get("category")
287+
filtered_hits = db.query(
288+
"sql",
289+
(
290+
"SELECT title, category, distance, (1 - distance) AS score "
291+
"FROM (SELECT expand(vectorNeighbors('Article[embedding]', "
292+
f"{qvec_literal}, 50))) WHERE category = ? ORDER BY distance LIMIT 5"
293+
),
294+
category,
295+
).to_list()
296+
297+
print(" Top 5 filtered documents in the same category:")
298+
for i, hit in enumerate(filtered_hits, 1):
299+
title = hit.get("title")
300+
doc_category = hit.get("category")
301+
distance = hit.get("distance")
302+
score = hit.get("score")
286303
print(f" {i}. {title}")
287-
print(f" Category: {doc_category}, Distance: {distance:.4f}")
304+
print(
305+
f" Category: {doc_category}, Distance: {distance:.4f}, "
306+
f"Score: {score:.4f}"
307+
)
288308
print()
289309

290310
print(f" ⏱️ All queries time: {time.time() - step_start:.3f}s")

0 commit comments

Comments
 (0)