Skip to main content

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 Extractor protocol: 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

creel-0.1.1.tar.gz (275.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

creel-0.1.1-py3-none-any.whl (82.0 kB view details)

Uploaded Python 3

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

Hashes for creel-0.1.1.tar.gz
Algorithm Hash digest
SHA256 9572c477a080ba467be526e87b554bc92831ac8786eacec1e861740d2ee37761
MD5 10ca3653891fa7a2fd8b21b77e76989c
BLAKE2b-256 aab39a3d753f4b6be11db9c795fa0b9771104485111ef4f809ec6cf37151fa96

See more details on using hashes here.

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

Hashes for creel-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 127c0d3c39364c467076ace43b19403c6e5e436585c51da11dd251f9ce98a0d9
MD5 5e2724010cbe1a5a8b1ef65c7ea6121d
BLAKE2b-256 bd39c1d9bfa5aeb683245e6bcfc58d9d175727f2cbf64679dda27903ee40ccb8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page