Skip to content

Python API

The triplate package requires Python 3.10+ and has no required dependencies. See Installation to add it (and the optional rdflib extra for the term type), and the API overview for the cross-language model.

from triplate import compile, render, is_template, register_type

Functions

compile(template)

def compile(template: str) -> CompiledTemplate

Parses template once. Raises TriplateSyntaxError if the template is malformed (including any reference to an undeclared parameter). Returns a reusable CompiledTemplate.

render(template, context=None, **kwargs)

def render(template: str, context: dict | None = None, **kwargs) -> str

One-shot convenience equivalent to compile(template).render(context, **kwargs). Values may be passed as a mapping, as keyword arguments, or both.

is_template(text)

def is_template(text: str) -> bool

Returns True if text opens with a --- frontmatter header. A cheap, non-throwing detector — unlike compile, it never parses or raises.

CompiledTemplate

class CompiledTemplate:
schema: Schema # property
examples: list[ExampleSet] # property
def render(self, context=None, **kwargs) -> str
def preview_example(self, example_id: str) -> str
def context_from_strings(self, inputs: dict[str, str | None]) -> dict
def frontmatter_prefixes(self) -> set[str]
MemberDescription
schemaThe declared parameter schema.
examplesThe named example blocks from the frontmatter; each ExampleSet carries its source line/column.
render(context=None, **kwargs)Renders against a mapping and/or kwargs. Raises a render-time error on a missing, unknown or mistyped value. Returns the rendered string.
preview_example(example_id)Renders using the named example set (development/preview). Raises if no such set exists.
context_from_strings(inputs)Builds a validated context from raw string inputs. See below.
frontmatter_prefixes()The prefixes referenced in the frontmatter. See below.

context_from_strings(inputs)

Coerces raw string inputs (CLI args, editor prompts) to their declared scalar types and validates the result against the schema:

  • An absent or blank input is omitted, so optional params stay absent.
  • An array param is split on commas (items trimmed, blanks dropped) and coerced element-wise.
  • A record param cannot be expressed as a string and is skipped — supply records via an example block instead.
  • int / decimal / double / bool are parsed strictly; an uncoercible value raises TriplateTypeError. Structural problems (missing required, cardinality) raise the usual binding/cardinality errors.
tmpl = compile("---\nparams { ids: int[], active: bool }\n---\n")
tmpl.context_from_strings({"ids": "1, 2, 3", "active": "true"})
# → {"ids": [1, 2, 3], "active": True}

frontmatter_prefixes()

Returns the set[str] of namespace prefixes referenced in the frontmatter — in example binding values (prefix:local), in literal datatypes on those values ("x"^^p:t), and in literal(p:t) parameter types. Because tools blank the frontmatter before tokenizing the body, these usages are invisible to a body token stream; a linter can use this set to avoid flagging a body PREFIX declaration as unused. A full <iri> contributes no prefix; the empty string denotes the default prefix.

tmpl = compile('---\nparams { t: iri }\nexample d "" { t: schema:Person }\n---\n${t}')
tmpl.frontmatter_prefixes() # → {"schema"}
tmpl = compile(template_string)
tmpl.schema.params # declared inputs
tmpl.render(service="http://dbpedia.org/sparql",
classes=["http://example.org/Person"], limit=10)
tmpl.render({"service": "", "classes": [...]}) # or a mapping
tmpl.preview_example("demo") # render a named example block

Accepted values

Each declared header type accepts:

Header typePython value
iri, pname, string, raw, literal(<dt>)str
intint
decimal, doublefloat (or int)
boolbool
date, dateTime, timedatetime.date / datetime / time, or an ISO str
terman rdflib term (requires the rdflib extra)
T[]a list of the element type
{ … } recorda dict

Custom types

def register_type(name: str, serializer: Callable[[Any, Pos], str]) -> None

Register a serializer, then use name as a header type (params { id: name }). The serializer is called as serializer(value, pos) where pos has .line and .column; it must validate value and return the exact text to emit — it is fully responsible for injection safety.

from triplate import register_type, TriplateTypeError
import re
def uuidref(value, pos):
if not re.fullmatch(r"[0-9a-f-]{36}", str(value)):
raise TriplateTypeError("not a UUID", pos.line, pos.column)
return f"<urn:uuid:{value}>"
register_type("uuidref", uuidref)

Errors

class TriplateError(Exception):
line: int | None
column: int | None
class TriplateSyntaxError(TriplateError): ... # compile time
class TriplateBindingError(TriplateError): ... # render: missing/unknown/absent
class TriplateTypeError(TriplateError): ... # render: failed validation
class TriplateCardinalityError(TriplateError): ... # render: min/max violated

All five names are exported from the top-level triplate package.