Natural-language queries in SPARQL (Text2SPARQL)

Optional module

The SPARQL counterpart of Natural-language queries (Text2Cypher), with the same API: an LLM translates the question to SPARQL and the query is run on the graph.

from cvcdocdb import JenaGraph, Text2SPARQL

graph = JenaGraph("http://localhost:3030/ds")
t2s = Text2SPARQL(graph, llm=lambda prompt: my_client.complete(prompt))
result = t2s.query("Quantes pàgines té el document D1?")
result.sparql, result.records

Notes

  • The schema shown to the LLM uses the RDF vocabulary JenaGraph writes, with PREFIX declarations for its namespace (label:, prop:, rel:). Relationship properties are read with the RDF 1.2 annotation syntax ?a rel:X ?b {| prop:p ?v |}.

  • Only read-only SPARQL is executed: a SELECT/ASK/CONSTRUCT/ DESCRIBE with no update operation and no SERVICE (federated queries could reach other servers). Anything else raises Text2SPARQLError before running.

  • schema=, examples=[...] and custom_prompt=... work as in Text2Cypher.

API

Natural-language questions over a SPARQL backend (JenaGraph).

Text2SPARQL is the SPARQL counterpart of Text2Cypher, with the same API:

from cvcdocdb import JenaGraph, Text2SPARQL

t2s = Text2SPARQL(graph, llm=my_llm)            # graph: a JenaGraph
result = t2s.query("Quantes pàgines té el document D1?")
result.sparql    # "PREFIX label: <urn:cvcdocdb:label/> SELECT ..."
result.records   # [{'c': 2}] — same shape as graph.query(sparql)

The LLM gets the graph schema in the RDF vocabulary JenaGraph writes (with PREFIX declarations for its namespace) and the question. The query it returns is only run if it is read-only: a SELECT/ASK/CONSTRUCT/ DESCRIBE with no update operation and no SERVICE (federated queries could reach other servers). Anything else raises Text2SPARQLError.

Text2Query picks Text2SPARQL or Text2Cypher from the backend. No extra dependency is needed.

class cvcdocdb.text2sparql.Text2SPARQL(graph, llm, *, schema=None, examples=None, custom_prompt=None)[source]

Ask natural-language questions to a SPARQL-backed cvcdocdb graph.

Parameters:
  • graph (Any) – A JenaGraph.

  • llm (Any) – The LLM handle — a prompt: str -> str callable, or an object with invoke(prompt) returning an answer with .content.

  • schema (Optional[str]) – Schema text for the prompt; introspected when omitted.

  • examples (Optional[List[str]]) – Optional example question/SPARQL pairs for the prompt.

  • custom_prompt (Optional[str]) – Optional prompt template replacing DEFAULT_SPARQL_PROMPT, with {schema}, {examples} and {query_text} placeholders.

Raises:

TypeError – If graph isn’t a SPARQL backend, or llm is neither a callable nor an object with invoke.

__init__(graph, llm, *, schema=None, examples=None, custom_prompt=None)[source]
Parameters:
  • graph (Any)

  • llm (Any)

  • schema (str | None)

  • examples (List[str] | None)

  • custom_prompt (str | None)

Return type:

None

query(question)[source]

Translate question to SPARQL with the LLM, run it, return the rows.

Raises:

Text2SPARQLError – If the generated SPARQL is invalid or not read-only (nothing is executed in that case).

Parameters:

question (str)

Return type:

Text2SPARQLResult

exception cvcdocdb.text2sparql.Text2SPARQLError[source]

The LLM’s answer could not be run: invalid or non-read-only SPARQL.

class cvcdocdb.text2sparql.Text2SPARQLResult(sparql, records, metadata=<factory>)[source]

Answer to a natural-language question.

Parameters:
sparql

The SPARQL query generated by the LLM (and executed).

Type:

str

records

Query results, shaped like graph.query(sparql).

Type:

List[Dict[str, Any]]

metadata

Extra metadata (sparql).

Type:

Dict[str, Any]

__init__(sparql, records, metadata=<factory>)
Parameters:
Return type:

None

cvcdocdb.text2sparql.extract_sparql(text)[source]

Return the SPARQL in an LLM answer (inside a code fence if there is one).

Parameters:

text (str)

Return type:

str

cvcdocdb.text2sparql.format_sparql_schema(namespace, node_props, rel_props, relationships)[source]

Render a graph schema (see cvcdocdb.text2cypher.collect_schema()) in the RDF vocabulary of JenaGraph.

Parameters:
Return type:

str

cvcdocdb.text2sparql.is_read_only_sparql(query)[source]

Whether query is a SPARQL query form that can’t modify data or reach another server (no update operation, no SERVICE). String literals, IRIs and comments are ignored.

Parameters:

query (str)

Return type:

bool