Skip to content

SPARQL terms

app.sparql_terms

Safe construction of SPARQL terms from untrusted input.

Every IRI and literal that reaches a query from an HTTP parameter goes through here. Interpolating a raw value would let a caller close the term and append graph patterns of their own, so the checks below follow the SPARQL 1.1 grammar rather than blacklisting characters ad hoc.

InvalidTerm

Bases: ValueError

A value cannot be expressed as the SPARQL term it was asked for.

is_iri(value)

True when value can be written between angle brackets unchanged.

Parameters:

Name Type Description Default
value str

Candidate IRI string.

required

Returns:

Type Description
bool

Whether value matches SPARQL 1.1 IRIREF character rules.

Source code in src/backend/app/sparql_terms.py
30
31
32
33
34
35
36
37
38
39
def is_iri(value: str) -> bool:
    """True when *value* can be written between angle brackets unchanged.

    Args:
        value: Candidate IRI string.

    Returns:
        Whether *value* matches SPARQL 1.1 IRIREF character rules.
    """
    return bool(value) and _NOT_IN_IRIREF.search(value) is None

iri_term(value)

Render value as an IRIREF.

Raise InvalidTerm when the value carries a character that would escape the brackets, so a caller-supplied IRI can never extend the query.

Parameters:

Name Type Description Default
value str

Absolute IRI.

required

Returns:

Type Description
str

SPARQL <...> term.

Raises:

Type Description
InvalidTerm

When value is not a safe IRIREF.

Source code in src/backend/app/sparql_terms.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def iri_term(value: str) -> str:
    """Render *value* as an IRIREF.

    Raise InvalidTerm when the value carries a character that would escape the
    brackets, so a caller-supplied IRI can never extend the query.

    Args:
        value: Absolute IRI.

    Returns:
        SPARQL ``<...>`` term.

    Raises:
        InvalidTerm: When *value* is not a safe IRIREF.
    """
    if not is_iri(value):
        raise InvalidTerm(f"{value!r} is not a valid IRI")
    return f"<{value}>"

string_literal(value)

Render value as a quoted SPARQL string literal, escapes included.

Parameters:

Name Type Description Default
value str

Untrusted string content.

required

Returns:

Type Description
str

Double-quoted SPARQL literal with escapes applied.

Source code in src/backend/app/sparql_terms.py
62
63
64
65
66
67
68
69
70
71
72
def string_literal(value: str) -> str:
    """Render *value* as a quoted SPARQL string literal, escapes included.

    Args:
        value: Untrusted string content.

    Returns:
        Double-quoted SPARQL literal with escapes applied.
    """
    escaped = "".join(_LITERAL_ESCAPES.get(char, char) for char in value)
    return f'"{escaped}"'