Skip to main content

OpenCyVer

OpenCyVer
Syntax, Schema And Property Access Validation of Cypher queries

LicensePythonDocumentationCite

OpenCyVer is a Python library designed to validate Cypher queries against a given Knowledge Graph schema in FalkorDB. It ensures correctness in terms of syntax, schema validity, and property access.

Looking for Neo4j? This version of OpenCyVer targets FalkorDB only. Neo4j is supported by CyVer 2.0.x (pip install "CyVer==2.0.2").

Features

  • Syntax Validation: Validates Cypher queries for correct syntax and detects conflicting labels in nodes and relationships.
  • Schema Validation: Checks query alignment with a predefined KG schema structure.
  • Property Validation: Ensures property accesses are correct based on the predefined KG schema structure.

New Feature in release v2.x:

  • Validators Metadata Reporting: Alongside validation results, OpenCyVer returns detailed metadata describing each detected issue in a Cypher query — including the type of error, its location, and suggestions for how to fix it.

📖 Documentation

For documentation read the demo notebooks.

📋 Requirements

Before installing, make sure you have the following Python packages installed, with Python version >= 3.10:

  • regex>=2024.11.6
  • falkordb>=1.8.0
  • pandas>=2.2.3

📦 Installation

To install the latest stable version from PyPI, run:

pip install OpenCyVer

Alternatively, if you prefer to install the latest development version, you can install it directly from GitHub:

pip install git+https://github.com/Killeroid/OpenCyVer.git

Or, you can manually clone the repository and run:

git clone https://github.com/Killeroid/OpenCyVer.git
cd OpenCyVer
pip install .

💻 Example Usage

Importing the Library

from opencyver import SyntaxValidator, SchemaValidator, PropertiesValidator

Connect to your database

Pass a FalkorDB client to the validators as driver. database_name is the name of the graph:

from falkordb import FalkorDB

driver = FalkorDB(host='localhost', port=6379)
database_name = 'my_graph'

You can also pass a graph directly, in which case database_name can be omitted:

driver = FalkorDB(host='localhost', port=6379).select_graph('my_graph')

FalkorDBLite (pip install falkordblite, Python >= 3.12), an embedded FalkorDB, works too:

from redislite.falkordb_client import FalkorDB
driver = FalkorDB('/path/to/graph.db')

How validation works on FalkorDB

  • Validation never executes or modifies your data: queries are checked with GRAPH.EXPLAIN and everything else runs read-only (GRAPH.RO_QUERY).
  • FalkorDB sends no warnings of its own, so OpenCyVer derives the unknown label / relationship type / property warnings from the graph schema, and detects missing $parameters from the query text.
  • Cypher that FalkorDB cannot parse, such as (n:!Label), [:A&B] or (n:A|B), is reported as a syntax error by SyntaxValidator.

FalkorDB's own extensions to Cypher

  • Syntax: SyntaxValidator asks FalkorDB itself, so whatever your server version supports passes (vector functions such as vecf32, db.idx.* and algo.* procedures, index commands such as CREATE VECTOR INDEX, ...) and whatever it does not is reported (an unregistered procedure, shortestPath inside MATCH, ...). OpenCyVer does not need to know about them.
  • Schema and properties: these validators understand node, relationship and path patterns and variable.property accesses, plus one extension: the full-text and vector index query procedures. In CALL db.idx.fulltext.queryNodes('Goal', ...) YIELD node (and queryRelationships, db.idx.vector.queryNodes / queryRelationships) the label or relationship type is checked like one in a pattern, the properties read from the yielded node / relationship are checked against it, and for a vector query so is its attribute. SchemaValidator also checks that the graph has a full-text or vector index for the call (OpenCyVer.Warning.UnknownIndex), and its score is then the average of the pattern score and the share of the calls that have an index. This matters because FalkorDB answers an unknown label, or a label without an index, with an empty result, not an error.
  • Not checked: a label that is not a plain string in the call (a $parameter, say), whether a vector index's dimension fits the vector you pass, and anything else inside other procedure calls or functions.

Syntax Validator

syntax_validator =  SyntaxValidator(driver, check_multilabeled_nodes=False)
query = 'MATCH (g:Goal) RETURN COUNT(g) AS output'
is_valid, syntax_metadata = syntax_validator.validate(query, database_name=database_name)
print(f"Syntax Valid: {is_valid}")
print(f"Syntax Metadata: {syntax_metadata}")

Schema Validator

schema_validator =  SchemaValidator(driver)
query = 'MATCH (g:Goal)-[:HAS_TARGET]->(t:Target) RETURN g, t'
# Extraction
extracted_node_labels, extracted_rel_labels, extracted_paths = schema_validator.extract(query, database_name=database_name)
print(f"Extracted Node patterns : {extracted_node_labels}")
print(f"Extracted Relationships patterns : {extracted_rel_labels}")
print(f"Extracted Path patterns : {extracted_paths}")
# Validation 
schema_score, schema_metadata = schema_validator.validate(query, database_name=database_name)
print(f"Schema Validation Score: {schema_score}")
print(f"Schema Validation Metadata: {schema_metadata}")

Properties Validator

props_validator =  PropertiesValidator(driver)
query = 'MATCH (g:Goal)-[:HAS_TARGET]-(t:Target) WHERE g.code =1 RETURN t'
# Extraction
variables_properties , labels_properties = props_validator.extract(query, strict = False, database_name=database_name)
print(f"Accessed properties by variables: {variables_properties}")
print(f"Accessed properties by labels (including inferred): {labels_properties}")

# Validation 
props_score, properties_metadata = props_validator.validate(query, database_name=database_name, strict=False)
print(f"Properties Validation Score: {props_score}")
print(f"Properties Validation Metadata: {properties_metadata}")

📊 Tip:

Always start with the SyntaxValidator before using the Schema and Properties validators. Even a small syntax error can cause misleading results in downstream validation. Ensuring syntactic correctness first helps you avoid wasted time and confusion. Building on this principle, we define the KG Valid Query metric to systematically evaluate generated Cypher queries for knowledge graphs.

A query is considered valid only if it satisfies all three checks:

  1. SyntaxValidator.is_valid= True → the query is syntactically correct.
  2. SchemaValidator.score = 1 → the query respects the graph schema.
  3. PropertiesValidator.score = 1 or None → the query accesses only valid properties.
KG_Valid_Query

🧪 Development

uv sync            # create the environment (Python >= 3.12 also installs FalkorDBLite for the tests)
uv run pytest      # run the tests

Releasing

Set version in pyproject.toml, add the release to CHANGELOG.md and commit. Then push a tag with the same version:

git tag v3.0.0
git push origin v3.0.0

.github/workflows/publish.yml checks that the tag matches the version, runs the checks and the tests, builds the sdist and the wheel, and publishes them to PyPI from the GitHub environment pypi, with PyPI trusted publishing (no token). The one-time setup on PyPI is a trusted publisher with owner Killeroid, repository OpenCyVer, workflow publish.yml and environment pypi.

License

This project is licensed under the CC BY-SA 4.0 license.

🤝 Contributing

Contributions are welcome! Please submit a pull request or open an issue.

Cite

To cite this work, please use:

I. Mandilara, C. M. Androna, E. Fotopoulou, A. Zafeiropoulos and S. Papavassiliou, "Decoding the Mystery: How can LLMs Turn Text into Cypher in Complex Knowledge Graphs?," in IEEE Access , doi: 10.1109/ACCESS.2025.3567759.

Contact

For any request for detailed information or expression of interest for participating at this initiative, you may contact:

  • Ioanna Mandilara - ioannamand (at) netmode (dot) ntua (dot) gr
  • Christina Maria Androna - andronaxm (at) netmode (dot) ntua (dot) gr

Metadata

Release files for OpenCyVer 3.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for OpenCyVer 3.0.1
File Size Uploaded
opencyver-3.0.1.tar.gz 32.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for OpenCyVer 3.0.1
File Interpreter ABI Platform
opencyver-3.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 68.3 kB

Release files / opencyver-3.0.1.tar.gz

Download URL opencyver-3.0.1.tar.gz
Size 32.4 kB
Tags Source
SHA-256 checksum
How to use checksums
3582b82ac2d3c91699d384a76806f4956f5bf655bcf39ef8f09847e7b9d038b2
BLAKE2b-256 checksum
How to use checksums
163cacd9425658189de4361b06b023a4faba30bc561a54ad4fe91a245b788e1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / opencyver-3.0.1-py3-none-any.whl

Download URL opencyver-3.0.1-py3-none-any.whl
Size 35.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
01dd531f377eb589c039e97272572ef13051b4f3fdb8ae67b28cfe6aa2dca2c6
BLAKE2b-256 checksum
How to use checksums
0a5f04b44bd55e1536441d7dc69f0b7513c6e24532ac6f0e65f6840dfff4bd58
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

3.0.1 This release

2 release files

3.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page