Extract linked information from a mess or sources
Project description
creel
Extract a typed graph from a mess of sources.
creel is a general, AI-powered source-to-graph extraction engine. You give it (a) sources — freeform prose, tables, JSON, PDFs; (b) a grammar of the graph you want — its node-types and edge-types and the typed values they carry; and (c) extractors — pluggable strategies that know how to find each element. creel returns a clean, auditable, typed property graph as a single source of truth, canonically a JSON graph specification:
extract(sources, graph_spec, extractors) -> graph
Everything downstream — persistence, query, graph-RAG, annotation, rendering to slides/reports — is a projection of that one graph.
Install
pip install creel # core: pydantic, jsonschema, networkx
pip install "creel[query]" # SQL/JSON query extractors (duckdb, jmespath)
pip install "creel[ingest]" # document loaders (docling, trafilatura, openpyxl, python-docx)
pip install "creel[aix]" # real LLM extraction/judging/embedding via aix
A first taste
Declare a grammar, extract a graph from prose, validate it, emit canonical JSON:
from creel import (
GraphSpec, NodeType, EdgeType, AttrSchema, EnumDef,
extract, validate_graph, to_canonical_json,
)
spec = GraphSpec(
enums=(EnumDef("Currency", ("USD", "EUR")),),
node_types=(
NodeType("donor", attributes=(AttrSchema("name", required=True),)),
NodeType("project", attributes=(AttrSchema("title", required=True),)),
),
edge_types=(
EdgeType("funds", subject_type="donor", object_type="project",
attributes=(AttrSchema("amount", range="integer", required=True, minimum=0),
AttrSchema("currency", range="Currency", required=True))),
),
)
# Deterministic pattern extractors (no LLM): regex over prose.
bindings = {
"donor": ("regex_node", {"pattern": r"Donor:\s*(?P<name>.+)", "id_attribute": "name"}),
"project": ("regex_node", {"pattern": r"Project:\s*(?P<title>.+)", "id_attribute": "title"}),
"funds": ("regex_edge", {
"pattern": r"(?P<donor>[\w ]+?) funds (?P<project>[\w ]+?) with (?P<currency>[A-Z]{3}) (?P<amount>\d+)",
"source_id_template": "donor:{donor}", "target_id_template": "project:{project}",
"casts": {"amount": "int"}, "exclude_groups": ("donor", "project")}),
}
src = "Donor: Gov X\nProject: WASH\nGov X funds WASH with USD 1000000"
g = extract(src, spec, bindings, on_missing_binding="skip")
assert validate_graph(g, spec) == []
print(to_canonical_json(g)) # deterministic, git-diffable JSON
print(g.evidence) # every element traced back to its source span
With a real LLM (schema-as-extractor)
The attribute descriptions become the extraction instruction; the LLM client is
injected (no provider SDK in the core):
from creel.extract.llm import aix_client
g = extract(prose, spec, {"donor": ("llm", {})},
services={"llm": aix_client()}, on_missing_binding="skip")
What you get
- Labeled Property Graph — attributes (funding amounts, indicator values) live on edges, which have their own identity; deterministic, git-diffable canonical JSON.
- Three extractor families behind one
Extractorprotocol: deterministic pattern/function, query (DuckDB SQL / JMESPath over structured sources), and LLM (schema-as-extractor, validate-retry, faithfulness gate) — plus cluster-pass (extract several coupled types in one LLM call). - Ingestion (
ingest()): route-by-format file loaders (md/csv/json/txt built-in; PDF/DOCX/XLSX/HTML via extras). - Auditability: every node/edge/value carries a separable evidence record (provenance + grounding selector back to the exact source span + confidence). A reverse-trace index answers "which elements did this passage produce?", and a re-anchoring resolver keeps highlights valid across re-ingestion.
- Evaluation by pluggable verifiers, not
==:numeric_tolerance,set_match,graph_match(partial credit),llm_rubric(NL-defined, G-Eval), … with a corpus runner. - Entity resolution cascade (normalize → registry → LLM), the reify edge↔node toggle, views (DOT/Mermaid/Cytoscape/tables), and export adapters (JGF, GraphML, parameterized Cypher, RDF-star).
Design & docs
The full reasoning lives in the research + design docs: start with the
synthesis (decisions
D1–D15), then the roadmap, the
decision log, and the
progress log. A worked example is in
examples/.
License
MIT.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file creel-0.1.1.tar.gz.
File metadata
- Download URL: creel-0.1.1.tar.gz
- Upload date:
- Size: 275.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9572c477a080ba467be526e87b554bc92831ac8786eacec1e861740d2ee37761
|
|
| MD5 |
10ca3653891fa7a2fd8b21b77e76989c
|
|
| BLAKE2b-256 |
aab39a3d753f4b6be11db9c795fa0b9771104485111ef4f809ec6cf37151fa96
|
File details
Details for the file creel-0.1.1-py3-none-any.whl.
File metadata
- Download URL: creel-0.1.1-py3-none-any.whl
- Upload date:
- Size: 82.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
127c0d3c39364c467076ace43b19403c6e5e436585c51da11dd251f9ce98a0d9
|
|
| MD5 |
5e2724010cbe1a5a8b1ef65c7ea6121d
|
|
| BLAKE2b-256 |
bd39c1d9bfa5aeb683245e6bcfc58d9d175727f2cbf64679dda27903ee40ccb8
|