TripleLite
TripleLite is an in-memory RDF triple store for Python. It stores triples in nested dictionaries, with an optional reverse index configurable per predicate.
Install
Section titled “Install”pip install tripleliteNeed rdflib interop? Install the extra:
pip install triplelite[rdflib]Quick start
Section titled “Quick start”This example models the article “OpenCitations, an infrastructure organization for open scholarship” using predicates from the OpenCitations Data Model:
from triplelite import TripleLite, RDFTerm
DCTERMS = "http://purl.org/dc/terms/"FABIO = "http://purl.org/spar/fabio/"FRBR = "http://purl.org/vocab/frbr/core#"PRISM = "http://prismstandard.org/namespaces/basic/2.0/"XSD = "http://www.w3.org/2001/XMLSchema#"RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
OC = "https://w3id.org/oc/meta/"article = f"{OC}br/062501777134"journal = f"{OC}br/062501778099"
g = TripleLite(identifier=f"{OC}br/")
g.add_many([ (article, RDF_TYPE, RDFTerm("uri", f"{FABIO}JournalArticle")), (article, f"{DCTERMS}title", RDFTerm("literal", "OpenCitations, An Infrastructure Organization For Open Scholarship")), (article, f"{PRISM}publicationDate", RDFTerm("literal", "2020-02", f"{XSD}gYearMonth")), (article, f"{PRISM}volume", RDFTerm("literal", "1")), (article, f"{PRISM}startingPage", RDFTerm("literal", "428")), (article, f"{PRISM}endingPage", RDFTerm("literal", "444")), (article, f"{FRBR}partOf", RDFTerm("uri", journal)),])Query by pattern (None is a wildcard):
for s, p, o in g.triples((article, None, None)): print(p.split("/")[-1], "->", o.value)
for obj in g.objects(article, f"{DCTERMS}title"): print(obj.value)
print(len(g)) # 7Remove by pattern:
g.remove((article, f"{PRISM}startingPage", None))g.remove((article, f"{PRISM}endingPage", None))print(len(g)) # 5Single add vs batch add
Section titled “Single add vs batch add”add() inserts one triple. add_many() accepts any iterable and avoids per-call overhead by caching internal lookups across the batch. Use add_many() when loading data from a file, a SPARQL result set, or any source with more than a handful of triples:
g.add((article, f"{DCTERMS}title", RDFTerm("literal", "Some title")))
g.add_many( (str(s), str(p), RDFTerm("uri", str(o))) for s, p, o in some_external_source)Both methods deduplicate: adding a triple that already exists is a no-op.
What’s next
Section titled “What’s next”- Data model: how triples, URIs, and literals are represented internally
- Reverse indexing: when to enable it, selective vs full, memory trade-offs
- Subgraph extraction: pulling all triples for a subject into a new graph
- rdflib interop: converting between TripleLite and rdflib