trails.schema_watcher observes kg_write events and incrementally builds
per-type field statistics. It detects new types, new fields, type drift (a field's
inferred Python type changes), and cardinality changes (single-valued to
multi-valued). The watcher is opt-in and runs at near-zero cost (dict updates, no
SPARQL).
fromtrails.schema_watcherimportSchemaWatcherwatcher=SchemaWatcher(ctx,min_samples=5)watcher.start()# ... normal ctx.kg usage — the watcher observes in the background ...# Check for schema anomaliesforalertinwatcher.get_alerts():print(f"[{alert.alert_type}] {alert.type_name}.{alert.field_name}: {alert.details}")# Get @node_type suggestions for types with enough samplesforsuggestioninwatcher.get_suggestions():print(suggestion.suggested_node_type_code)# @node_type("Person", fields={# "name": str,# "age": int,# })# class Person:# pass# Summary statisticsstats=watcher.get_stats()print(f"Types observed: {stats['types_observed']}")watcher.stop()