Skip to content

Fix language dispatch and result processing in Grafeo backend#6

Closed
XXXM1R0XXX wants to merge 3 commits into
GrafeoDB:mainfrom
XXXM1R0XXX:main
Closed

Fix language dispatch and result processing in Grafeo backend#6
XXXM1R0XXX wants to merge 3 commits into
GrafeoDB:mainfrom
XXXM1R0XXX:main

Conversation

@XXXM1R0XXX

Copy link
Copy Markdown
Contributor

This pull request refactors and extends the GrafeoBackend class in src/anywidget_graph/backends/grafeo.py to improve support for multiple query languages and to better handle Grafeo-specific node and relationship formats. The main changes include adding language-specific execution logic, and introducing robust methods for processing Grafeo node and relationship dictionaries.

Language support enhancements:

  • Added the _LANGUAGE_METHODS mapping to associate query languages (like "cypher", "gremlin", etc.) with their corresponding execution methods, enabling flexible query execution based on language.
  • Updated the execute method to use the appropriate database method for the specified language, falling back to a generic execute if no match is found.

Grafeo node and relationship processing improvements:

  • Refactored _process_result to prioritize Grafeo node and relationship detection using new helper methods, ensuring correct conversion to widget formats.
  • Added static methods _is_grafeo_node, _is_grafeo_relationship, _grafeo_node_to_dict, and _grafeo_relationship_to_dict to reliably identify and transform Grafeo node and relationship dictionaries for downstream use.

Simplified API Usage Examples

Thanks to these improvements, you no longer need to manually parse raw results using internal private methods (like _process_result). You can now easily render a Grafeo graph using one of the following simplified approaches:

Setup data:

from grafeo import GrafeoDB
from anywidget_graph import Graph

db = GrafeoDB()

# Create people
alix = db.create_node(["Person"], {"name": "Alix", "age": 30, "city": "Utrecht"})
gus = db.create_node(["Person"], {"name": "Gus", "age": 35, "city": "Portland"})
harm = db.create_node(["Person"], {"name": "Harm", "age": 28, "city": "Utrecht"})
dave = db.create_node(["Person"], {"name": "Dave", "age": 40, "city": "San Francisco"})
eve = db.create_node(["Person"], {"name": "Eve", "age": 32, "city": "Portland"})

# Create companies
acme = db.create_node(["Company"], {"name": "Acme Corp", "industry": "Tech"})
globex = db.create_node(["Company"], {"name": "Globex Inc", "industry": "Finance"})

# Friendships
db.create_edge(alix.id, gus.id, "KNOWS", {"since": 2020})
db.create_edge(alix.id, harm.id, "KNOWS", {"since": 2019})
db.create_edge(gus.id, harm.id, "KNOWS", {"since": 2021})
db.create_edge(gus.id, dave.id, "KNOWS", {"since": 2018})
db.create_edge(harm.id, eve.id, "KNOWS", {"since": 2022})
db.create_edge(dave.id, eve.id, "KNOWS", {"since": 2020})

# Employment
db.create_edge(alix.id, acme.id, "WORKS_AT", {"role": "Engineer"})
db.create_edge(gus.id, acme.id, "WORKS_AT", {"role": "Manager"})
db.create_edge(harm.id, globex.id, "WORKS_AT", {"role": "Analyst"})
db.create_edge(dave.id, globex.id, "WORKS_AT", {"role": "Director"})
db.create_edge(eve.id, acme.id, "WORKS_AT", {"role": "Designer"})

graph = Graph(database_backend="grafeo", grafeo_db=db)

Option 1: Using Widget Properties (Recommended)
The widget can now natively parse the query using the assigned query language.

# Programmatically execute the query to extract the graph
graph.query = "MATCH (n)-[r]->(m) RETURN n, r, m"
graph.query_language = "cypher"

# Render
graph

Option 2: Using the Backend Execute Method directly
The execute method now properly respects the language parameter and correctly formats the output out-of-the-box.

# Fetch and format nodes and edges directly from the backend
nodes, edges = graph.backend.execute("MATCH (n)-[r]->(m) RETURN n, r, m", language="cypher")

# Assign to widget
graph.nodes = nodes
graph.edges = edges

# Render
graph

Copilot AI and others added 3 commits March 13, 2026 16:27
Co-authored-by: XXXM1R0XXX <87042609+XXXM1R0XXX@users.noreply.github.com>
…rameters

Fix GrafeoBackend: language-aware dispatch and grafeo result parsing
StevenBtw added a commit that referenced this pull request Mar 14, 2026
GrafeoBackend now routes queries to language-specific methods
(execute_cypher, execute_gremlin, etc.) when available, falling
back to generic execute(). Adds detection and conversion of
Grafeo's internal _id/_labels/_source/_target/_type dict format
so native query results render correctly in the widget.

Based on PR #6 by Богдан Кристиан, with added ClassVar annotation,
test coverage, and version bump to 0.2.8.

Co-Authored-By: Богдан Кристиан <87042609+XXXM1R0XXX@users.noreply.github.com>
@StevenBtw

Copy link
Copy Markdown
Contributor

Thanks for this contribution @XXXM1R0XXX! I have just incorporated your changes
into the 0.2.8 release with a few additions (ClassVar lint fix, test
coverage). Your Co-Authored-By credit is on the commit.

Closing in favor of the release branch, which includes your work.

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.

3 participants