causalatee.graph
See Causal Graphs for a guide and the CGF 1.0 specification for the on-disk format.
graph
Classes
CauseEffectEdge
CauseEffectEdge(graph: 'CauseEffectGraph', cause: CauseEffectNode, effect: CauseEffectNode, *, count: int, necessity: float, sufficiency: float)
Bases: Edge[CauseEffectNode, 'CauseEffectEdge']
A directed cause->effect edge with an occurrence count and two causal-strength scores.
Source code in causalatee/graph/_cause_effect_graph.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
Attributes
count
property
count: int
Return the number of occurrences supporting this pair.
necessity
property
necessity: float
Return the necessity causal-strength score.
sufficiency
property
sufficiency: float
Return the sufficiency causal-strength score.
CauseEffectNode
CauseEffectNode(graph: 'CauseEffectGraph', token: str)
Bases: Node['CauseEffectNode', 'CauseEffectEdge']
A single lexical (word-level) node in the Cause-Effect Graph.
Source code in causalatee/graph/_cause_effect_graph.py
67 68 69 | |
Attributes
token
property
token: str
Return the lexical token this node represents.
CauseNetEdge
CauseNetEdge(graph: CauseNet, cause: CauseNetNode, effect: CauseNetNode, *, sources: Sequence[Mapping[str, object]], support: int)
Bases: Edge[CauseNetNode, 'CauseNetEdge']
A directed CauseNet relation from a cause to an effect.
Source code in causalatee/graph/_causenet.py
158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
Attributes
sources
property
sources: tuple[Mapping[str, object], ...]
Return the source records supporting this relation.
support
property
support: int
Return the number of source records supporting this relation.
CauseNetNode
CauseNetNode(graph: CauseNet, concept: str)
Bases: Node['CauseNetNode', 'CauseNetEdge']
A CauseNet concept node.
Source code in causalatee/graph/_causenet.py
137 138 139 | |
Attributes
concept
property
concept: str
Return the CauseNet concept represented by this node.
Edge
Edge(graph: Graph[N, E])
Bases: Generic[N, E], ABC
A directed edge associated with a graph backend.
Source code in causalatee/graph/_graph.py
57 58 | |
Attributes
source
abstractmethod
property
source: N
Return the source node.
target
abstractmethod
property
target: N
Return the target node.
metadata
property
metadata: Mapping[str, object]
Return backend-provided metadata for this edge.
Graph
Bases: Generic[N, E], ABC
Abstract interface for a directed graph with typed nodes and edges.
Attributes
nodes
abstractmethod
property
nodes: Collection[N]
Return a collection view of the graph's nodes.
edges
abstractmethod
property
edges: Collection[E]
Return a collection view of the graph's edges.
node_metadata_schema
property
node_metadata_schema: Mapping[str, object] | str | None
Return the Avro writer schema for node metadata, if defined.
edge_metadata_schema
property
edge_metadata_schema: Mapping[str, object] | str | None
Return the Avro writer schema for edge metadata, if defined.
Methods:
get_node
abstractmethod
get_node(node_id: str) -> N
Return the node identified by node_id.
Implementations should raise KeyError when no node exists.
Source code in causalatee/graph/_graph.py
104 105 106 107 108 109 110 111 | |
edges_from
abstractmethod
edges_from(node: N) -> Iterable[E]
Iterate over edges whose source is node.
Source code in causalatee/graph/_graph.py
113 114 115 116 117 | |
edges_to
abstractmethod
edges_to(node: N) -> Iterable[E]
Iterate over edges whose target is node.
Source code in causalatee/graph/_graph.py
119 120 121 122 123 | |
node_metadata
node_metadata(node: N) -> Mapping[str, object]
Return resource-specific node metadata.
Source code in causalatee/graph/_graph.py
125 126 127 128 | |
edge_metadata
edge_metadata(edge: E) -> Mapping[str, object]
Return resource-specific edge metadata.
Source code in causalatee/graph/_graph.py
130 131 132 133 | |
Node
Node(graph: Graph[N, E])
Bases: Generic[N, E], ABC
A lightweight node associated with a graph backend.
Source code in causalatee/graph/_graph.py
21 22 | |
Attributes
id
abstractmethod
property
id: str
Return the node identifier, unique within its graph.
metadata
property
metadata: Mapping[str, object]
Return backend-provided metadata for this node.
Methods:
outgoing_edges
outgoing_edges() -> Iterable[E]
Iterate over edges whose source is this node.
Source code in causalatee/graph/_graph.py
37 38 39 40 | |
incoming_edges
incoming_edges() -> Iterable[E]
Iterate over edges whose target is this node.
Source code in causalatee/graph/_graph.py
42 43 44 45 | |
SQLGraph
SQLGraph(connection: Connection)
Bases: Graph[SQLGraphNode, SQLGraphEdge]
A mutable graph backed by a caller-supplied SQLite connection. See module docstring.
Source code in causalatee/graph/_sql_graph.py
136 137 138 139 140 141 142 143 144 | |
Methods:
add_node
add_node(node_id: str, metadata: Mapping[str, object] | None = None) -> SQLGraphNode
Add (or replace) a node. Safe to call again for an existing id -- overwrites its metadata.
Source code in causalatee/graph/_sql_graph.py
146 147 148 149 150 151 152 153 154 | |
add_edge
add_edge(source_id: str, target_id: str, metadata: Mapping[str, object] | None = None) -> SQLGraphEdge
Add a directed edge, auto-creating either endpoint (with empty metadata) if it doesn't exist yet
-- same convention networkx's add_edge uses. Does NOT deduplicate or merge with an existing
edge between the same pair (a multigraph, in effect); callers that need one aggregated edge per
pair must aggregate before calling this once per pair (see causalatee.mining.GraphSink).
Source code in causalatee/graph/_sql_graph.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |
SQLGraphEdge
SQLGraphEdge(graph: SQLGraph, source: SQLGraphNode, target: SQLGraphNode, metadata: Mapping[str, object])
Bases: Edge[SQLGraphNode, 'SQLGraphEdge']
A directed edge in a SQLGraph. Metadata is fetched once at construction time, not re-queried on
access.
Source code in causalatee/graph/_sql_graph.py
52 53 54 55 56 57 58 | |
SQLGraphNode
SQLGraphNode(graph: SQLGraph, node_id: str, metadata: Mapping[str, object])
Bases: Node['SQLGraphNode', 'SQLGraphEdge']
A node in a SQLGraph. Metadata is fetched once at construction time, not re-queried on access.
Source code in causalatee/graph/_sql_graph.py
35 36 37 38 | |
Functions:
load_cause_effect_graph
load_cause_effect_graph(source: Source, *, limit: int | None = None) -> CauseEffectGraph
Load a Lexical Cause-Effect Graph (CEG) file from source.
source must be a local path to the tab-separated CEG text file (see module docstring for the exact line
format).
Unlike load_causenet, omitting limit is safe even for the complete, tens-of-millions-of-edges release:
node vocabulary is materialized eagerly (cheap -- a real release has on the order of 10^4-10^5 unique tokens),
but edges are streamed from disk rather than materialized as Python objects, so
save_cgf(load_cause_effect_graph(path), out_path) converts a file far larger than available RAM.
limit, when given, caps the number of EDGE LINES read from the top of the file -- applied consistently to
both the node vocabulary built here and every later .edges iteration -- for quick examples/tests, exactly
like load_causenet's own limit.
Source code in causalatee/graph/_cause_effect_graph.py
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | |
load_causenet
load_causenet(source: Source, *, limit: int | None = None, timeout: float = 60.0) -> CauseNet
Load CauseNet from source.
Omit limit to load the complete resource. This eager implementation
may use substantial memory for the full graph.
Source code in causalatee/graph/_causenet.py
358 359 360 361 362 363 364 365 366 367 368 369 370 | |
diff_avro_schema
diff_avro_schema(expected: object, actual: object, *, path: str = '$') -> list[str]
Recursively compare two Avro (sub-)schemas -- e.g. two infer_avro_schema
results, or two field type values nested within them -- and return every structural difference found
(missing fields, unexpected extra fields, type mismatches) as a human-readable string. An empty list means
the two schemas describe the same shape.
Only type/fields/items are compared -- a record's own name/namespace are deterministic
byproducts of field path (see infer_avro_schema), not part of its shape, so two schemas naming the same
nested record differently are NOT reported as different here. Field order doesn't matter either, only
presence and type.
path accumulates a location for each reported difference (e.g. $.evidence[].topic) so a caller can
point at exactly where two metadata shapes disagree, rather than just reporting "they differ".
Source code in causalatee/graph/_cgf.py
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 | |
infer_avro_schema
infer_avro_schema(name: str, example: Mapping[str, object], *, namespace: str = 'causalatee.inferred') -> dict
Infer an Avro record schema from one example node.metadata/edge.metadata object.
Only handles "plain data" values -- str, bool, int, float, None, list/tuple, and
nested Mapping -- exactly the shapes JSON-like metadata is built from. Raises :class:TypeError for
anything else (a custom class instance, a set, ...), since there's no principled way to guess an Avro type for
it from a single example.
Field order in example becomes field order in the returned schema (Python dicts preserve insertion order,
and so does Avro's own fields list) -- deterministic for a given example. Nested records (dicts, and dicts
nested inside list items) get their own generated, path-qualified name (e.g. "EdgeMetadata.Evidence.Item")
so two structurally different fields that happen to share a key name (e.g. a top-level "source" and a
"source" nested inside each "evidence" entry) never collide under Avro's global name-uniqueness rule.
LIMITATION, stated plainly rather than hidden: this infers from exactly ONE example. A field that is sometimes
a different type across the real population, or a list that happens to be empty in this particular example
(inferred as a permissive nullable-string array, since there's nothing to inspect), won't be caught here --
this assumes every value that will actually be encoded against the returned schema shares this one example's
shape, which holds for one caller using one consistent metadata shape (e.g. one graph_sink() run over one
corpus), not a general-purpose schema-drift detector across a heterogeneous population.
Source code in causalatee/graph/_cgf.py
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 | |
load_cgf
load_cgf(path: PathLike, *, validate: bool = False) -> CGFGraph
Memory-map and return a read-only CGF graph.
Source code in causalatee/graph/_cgf.py
508 509 510 511 | |
save_cgf
save_cgf(graph: Graph[Any, Any], path: PathLike, *, include_incoming: bool = True, node_metadata_schema: Mapping[str, object] | str | None = None, edge_metadata_schema: Mapping[str, object] | str | None = None) -> None
Serialize graph using disk-backed sorting and streamed sections.
Memory use is bounded independently of metadata and edge count. SQLite is used as a disposable external-sort spool; final CGF sections are written to separate temporary streams and assembled atomically. The only graph-side state retained by this function is whatever the supplied graph itself owns.
Source code in causalatee/graph/_cgf.py
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 | |