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, schema specs; (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/video — is a projection of that one graph.
Status — early development. The
v0.1data layer (grammar, the in-memory Labeled Property Graph, and deterministic canonical JSON) is implemented and tested. Theextract()facade and the extractor/verifier strategy layers are being built next — seemisc/docs/design/ROADMAP.md.
Install
pip install creel # core: pydantic, jsonschema, networkx
pip install "creel[llm]" # + the default LLM-extraction adapter
pip install "creel[query]" # + SQL/JSON query extractors (duckdb, jmespath)
pip install "creel[eval]" # + the verifier/evaluation backend
A first taste (the data layer, today)
Declare a grammar, build a graph against it, validate it, and emit canonical JSON:
from creel import (
GraphSpec, NodeType, EdgeType, AttrSchema, EnumDef,
Graph, validate_graph, to_canonical_json,
)
spec = GraphSpec(
enums=(EnumDef("Currency", ("USD", "EUR", "CHF")),),
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="decimal", required=True, minimum=0),
AttrSchema("currency", range="Currency", required=True),
),
),
),
)
g = Graph()
g.add_node("d:gov-x", types=("donor",), attributes={"name": "Government X"})
g.add_node("p:wash", types=("project",), attributes={"title": "WASH programme"})
# Edges are first-class: attributes (funding amounts!) live ON the edge, and each
# edge has its own id, so two distinct fundings are distinguishable.
g.add_edge("f:1", source="d:gov-x", target="p:wash", type="funds",
attributes={"amount": 1_000_000, "currency": "USD"})
assert validate_graph(g, spec) == [] # conforms to the grammar
print(to_canonical_json(g, spec=spec)) # deterministic, git-diffable JSON
Design at a glance
- Labeled Property Graph internal model — attributes live on edges, which have their own identity (parallel edges stay distinguishable).
- Two physically separate layers, joined by id — the grammar (what the graph is) and the extraction/verification metadata (how to populate and check it) are recombined on demand, so each is reused independently.
- Strategy pattern throughout — extractors, verifiers, renderers are pluggable
Protocols; new mechanisms slot in without touching old ones. - Schema-as-extractor / schema-as-verifier defaults — an attribute's description doubles as the default extraction instruction and verification criterion, so simple cases stay simple.
- Auditability over opaqueness — every node, edge, and value will carry a separable evidence record (provenance + grounding back to the source span + confidence).
- Evaluation is verifier-based, not equality-based — comparing extracted output
to expected output uses pluggable verifiers (numeric tolerance, set/graph
matching with partial credit, LLM rubrics), never a brittle
==.
The full reasoning lives in the research + design docs: start with the synthesis (decisions D1–D15), then the roadmap and decision log.
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.0.3.tar.gz.
File metadata
- Download URL: creel-0.0.3.tar.gz
- Upload date:
- Size: 183.0 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 |
b565757c61515efa4fb1ba897b561971e0511ac7c0ba18fd0cf0afb72c5a1a70
|
|
| MD5 |
19fd1eb617297d484bf6984473a07587
|
|
| BLAKE2b-256 |
0c1a04111e6008cb7e94369d64e0c1ebf941e81ad1c668d455f118bb71400be7
|
File details
Details for the file creel-0.0.3-py3-none-any.whl.
File metadata
- Download URL: creel-0.0.3-py3-none-any.whl
- Upload date:
- Size: 45.4 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 |
c1b4948229e9b93487d0e4a1b06d7698dc2e34631b19475c88a0cd7a4052c467
|
|
| MD5 |
268e89d6ae1818908f5be2a47b7cecf8
|
|
| BLAKE2b-256 |
8580ebcfc021ea20bd89782089e147a5d9f18b4709fcf21e691971b178eacca0
|