Skip to content

Python functions in SQL and openCypher, record events, Document.save()/delete() errors (#19) - #29

Merged
tae898 merged 4 commits into
mainfrom
port/functions-events
Oct 25, 2026
Merged

tae898 merged 4 commits into
mainfrom
port/functions-events

Conversation

@tae898

@tae898 tae898 commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator

Part of #19 (Features group, 1 of 2). Ported by hand from humemai/arcadedb-embedded-python#391 (Python functions in SQL and openCypher, record events) with the later fixes to the same files: humemai#438 (a Ctrl-C that makes JPype fail with "Fatal error occurred" is a KeyboardInterrupt) and humemai#454 (the JPype proxy classes are defined once, under a lock). Formatted with black 26.10.1 and isort 9.0.2 --profile black, Bandit clean with the CI invocation from CLAUDE.md.

Depends on #27. This branch is based on port/runtime-fixes, so the diff shows only this PR. It needs #27 for the read-only open and the serialized start_jvm() (the proxy lock builds on it); GitHub retargets the PR to main once #27 merges. It does not need #26: test_python_function_interrupt.py passes with and without it (checked below).

What is in it

  • Database.register_function() / unregister_function(): a Python callable usable from SQL (SELECT and WHERE) and, as py.<name>, from openCypher; an exception in the function is a query error, and a Ctrl-C during the statement is a KeyboardInterrupt. New module callbacks.py.
  • Database.on() / off(): record event callbacks (before_create, after_create, before_update, after_update, before_delete, after_delete); a before_* callback that returns False vetoes the write.
  • Document.save() and Document.delete() (graph.py) raise ArcadeDBError instead of the raw Java exception (a read-only database, a duplicate key, a vetoed write). The Python runtime fixes in src: serialized start_jvm(), heap default, log directory, XML limits, read-only open, async docs #27 test test_read_only_begin_is_not_refused_the_write_and_the_commit_are changes to expect that.
  • Example 28_python_functions_and_record_events.py and its entry in examples/README.md.
  • Tests: test_python_callbacks.py, test_python_function_interrupt.py (not collected on Windows, in conftest.py).

Java glue and what the wheel must contain

Two new classes, src/java/com/arcadedb/python/PythonFunctions.java and PythonRecordEvents.java. No build change is needed: scripts/Dockerfile.build and scripts/build-native.sh already compile every .java file under src/java into arcadedb-python-bridge.jar. The wheel must therefore contain PythonFunctions, PythonFunctions$Callback, PythonRecordEvents and PythonRecordEvents$Callback in arcadedb_embedded/jars/arcadedb-python-bridge.jar (the overlay below has 17 classes in that jar, 11 before). The existing test_jar_provenance.py and payload tests need no change.

Tests run

The tests ran on the Python and Java sources of this branch overlaid on an unpacked linux/amd64 wheel (engine 26.11.1-SNAPSHOT), with the bridge jar recompiled from src/java (javac 21) and put in place of the wheel's; a full wheel build was not needed. Python 3.12, JPype latest.

Run Files Result
this branch test_python_callbacks, test_python_function_interrupt, test_open_read_only, test_core, test_graph, test_graph_api, test_cypher, test_free_threading 139 passed, 1 skipped (pandas not installed in that environment)
this branch plus #26 merged test_python_function_interrupt, test_sigint, test_python_callbacks 48 passed

Example 28 also ran to completion against the overlay. CI of this PR has not been looked at yet when this was written.

Not included

🤖 Generated with Claude Code

…allbacks (#19)

Ported from humemai/arcadedb-embedded-python #391, with the later fixes to the same
files (#438 JPype race with Ctrl-C is a KeyboardInterrupt, #454 proxy classes defined once under a lock):
- Database.register_function() / unregister_function(), callable from SQL and as py.<name> from openCypher
- Database.on() / off() record event callbacks (before_* may veto a write)
- Document.save() and delete() raise ArcadeDBError instead of the raw Java exception
- new Java glue: PythonFunctions.java and PythonRecordEvents.java (compiled into the
  existing arcadedb-python-bridge.jar by the build that already compiles src/java)
- example 28

Based on port/runtime-fixes (#27).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The only conflict was examples/README.md: this branch adds the entry for example
28 and main (through runtime-fixes) the entry for example 29 at the same spot.
Kept both, in numeric order.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@tae898
tae898 changed the base branch from port/runtime-fixes to main October 24, 2026 20:15
@tae898
tae898 merged commit 4660ad3 into main Oct 25, 2026
66 of 68 checks passed
tae898 added a commit that referenced this pull request Oct 25, 2026
Bridge: float vectors cross as one binary buffer, not as JSON text or one JPype call per element (stacked on #29)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant