graflo.architecture.onto_sample¶
Resource sampling contract — pure-JSON samples and their derived profiles.
Samples are the raw material every schema inferencer consumes, whether it reasons
algorithmically (:mod:graflo.db.identity_inference) or with a language model
(ScheWea). Two ideas, deliberately kept apart:
- Sampling pulls documents from a connector. :class:
ResourceSampleholds them verbatim as JSON — tabular sources yield flatlist[dict]rows, API sources yield arbitrarily nested documents. Nothing is flattened at this boundary, so a hierarchical response survives intact. - Profiling describes those documents. :func:
profile_samplederives the flat, path-keyed, typed view (:class:ResourceProfile) used for prompting, studio previews and identity inference.
:attr:ResourceSample.connector records where the documents came from. That
relation is what later becomes a resource plus its resource_connector
binding, so it must survive the round trip — a sample that has lost its
provenance cannot be turned back into an ingestion model.
Attributes¶
DEFAULT_MAX_DOCS = 100
module-attribute
¶
DEFAULT_MAX_EXAMPLES = 3
module-attribute
¶
DEFAULT_MAX_PATHS = 200
module-attribute
¶
LIST_MARKER = '[]'
module-attribute
¶
__all__ = ['DEFAULT_MAX_DOCS', 'DEFAULT_MAX_EXAMPLES', 'DEFAULT_MAX_PATHS', 'LIST_MARKER', 'FieldProfile', 'ForeignKeyHint', 'ResourceProfile', 'ResourceSample', 'SourceSample', 'infer_field_type', 'iter_paths', 'profile_sample', 'profile_source']
module-attribute
¶
Classes¶
FieldProfile
¶
Bases: ConfigBaseModel
Derived description of one field path within a resource sample.
Source code in graflo/architecture/onto_sample.py
Attributes¶
depth = 0
class-attribute
instance-attribute
¶
Nesting depth of the path. 0 for a top-level scalar.
description = None
class-attribute
instance-attribute
¶
The source's own description of the field, when it declares one.
distinct = 0
class-attribute
instance-attribute
¶
examples = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
item_type = None
class-attribute
instance-attribute
¶
Element type; set only when type is LIST.
null_count = 0
class-attribute
instance-attribute
¶
null_ratio
property
¶
Fraction of occurrences whose value was null.
path
instance-attribute
¶
Dotted path to the value, e.g. address.city or items[].sku.
present = 0
class-attribute
instance-attribute
¶
Documents in which the path occurred.
type = FieldType.STRING
class-attribute
instance-attribute
¶
unique
property
¶
True when every non-null occurrence was distinct.
ForeignKeyHint
¶
Bases: ConfigBaseModel
A declared reference from one resource to another.
Populated only when the source declares it (a SQL foreign key, an RDF range). This is ground truth for edge inference and must not be confused with the name-suffix guessing an inferencer falls back to.
Source code in graflo/architecture/onto_sample.py
ResourceProfile
¶
Bases: ConfigBaseModel
Derived, flat, typed view of a :class:ResourceSample.
Source code in graflo/architecture/onto_sample.py
Attributes¶
connector = None
class-attribute
instance-attribute
¶
description = None
class-attribute
instance-attribute
¶
Carried from :attr:ResourceSample.description.
doc_count = 0
class-attribute
instance-attribute
¶
field_paths
property
¶
fields = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
foreign_keys = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
max_depth = 0
class-attribute
instance-attribute
¶
Deepest nesting observed. > 0 means ingestion needs descend steps.
nested
property
¶
primary_key = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
resource_name
instance-attribute
¶
truncated = False
class-attribute
instance-attribute
¶
Methods:¶
flat_docs(docs)
¶
Project docs onto this profile's paths as flat records.
Identity inference operates on flat records; this is how a nested source becomes eligible for it.
Source code in graflo/architecture/onto_sample.py
ResourceSample
¶
Bases: ConfigBaseModel
Documents sampled from one resource, plus what the source declared about it.
Source code in graflo/architecture/onto_sample.py
Attributes¶
connector = None
class-attribute
instance-attribute
¶
Name of the connector the documents came from; becomes the
resource_connector binding. None when sampled without bindings.
description = None
class-attribute
instance-attribute
¶
What the source says the resource is -- a SQL table comment, say.
docs = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
Sampled documents, verbatim JSON. Flat rows for tables, nested for APIs.
field_descriptions = PydanticField(default_factory=dict)
class-attribute
instance-attribute
¶
What the source says each field is, keyed by field path -- SQL column comments, for instance. Only declared text; never inferred.
foreign_keys = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
Declared outbound references, when the source has them.
primary_key = PydanticField(default_factory=list)
class-attribute
instance-attribute
¶
Declared primary key, when the source has one.
resource_name
instance-attribute
¶
Logical resource name; becomes ResourceConfig.name.
total_estimate = None
class-attribute
instance-attribute
¶
Approximate total document count at the source, when cheaply available.
truncated = False
class-attribute
instance-attribute
¶
True when documents were dropped or values clipped to respect caps.
SourceSample
¶
Bases: ConfigBaseModel
A set of resource samples drawn from one logical source.
Source code in graflo/architecture/onto_sample.py
Attributes¶
description = None
class-attribute
instance-attribute
¶
samples = PydanticField(min_length=1)
class-attribute
instance-attribute
¶
samples_by_resource
property
¶
Documents keyed by resource name.
This is the input shape consumed by cross-resource identity inference, so no adapter is needed between sampling and inference.
Returns the live document lists, not copies — treat them as read-only.
source_name
instance-attribute
¶
Methods:¶
get(resource_name)
¶
Return the sample for resource_name, or None.
Functions:¶
infer_field_type(values)
¶
Infer a FieldType (and item_type for lists) from observed values.
Checks bool before int deliberately — bool is an int subclass
in Python, so the naive order mistypes every boolean column as INT.
Source code in graflo/architecture/onto_sample.py
iter_paths(doc, prefix='', depth=0)
¶
Yield (path, depth, value) for every leaf in a JSON document.
Nested objects extend the path with .; lists of objects extend it with
[]. Lists of scalars are yielded whole so they can be typed as LIST.
Source code in graflo/architecture/onto_sample.py
profile_sample(sample, *, max_paths=DEFAULT_MAX_PATHS, max_examples=DEFAULT_MAX_EXAMPLES)
¶
Derive a :class:ResourceProfile from a sample's documents.
Handles tabular and hierarchical documents through one code path: a flat row is simply the depth-0 case.
Source code in graflo/architecture/onto_sample.py
profile_source(source_sample, *, max_paths=DEFAULT_MAX_PATHS, max_examples=DEFAULT_MAX_EXAMPLES)
¶
Profile every resource in a :class:SourceSample.