graflo.architecture.contract.ingestion.resource¶
Declarative resource configuration (YAML/manifest contract).
Attributes¶
Resource = ResourceConfig
module-attribute
¶
logger = logging.getLogger(__name__)
module-attribute
¶
Classes¶
EdgeInferSpec
¶
Bases: ConfigBaseModel
Selector for controlling inferred edge emission.
Source code in graflo/architecture/contract/ingestion/resource.py
Attributes¶
edge_id
property
¶
relation = PydanticField(default=None, description='Optional relation discriminator. If omitted, selector applies to all relations for (source, target).')
class-attribute
instance-attribute
¶
source = PydanticField(..., description='Edge source vertex name.')
class-attribute
instance-attribute
¶
target = PydanticField(..., description='Edge target vertex name.')
class-attribute
instance-attribute
¶
Methods:¶
matches(edge_id)
¶
ResourceConfig
¶
Bases: ConfigBaseModel
Declarative resource definition (serializable contract).
Source code in graflo/architecture/contract/ingestion/resource.py
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | |
Attributes¶
drop_trivial_input_fields = PydanticField(default=False, description='If True, remove top-level input keys whose value is None or the empty string before the actor pipeline runs.')
class-attribute
instance-attribute
¶
encoding = PydanticField(default=EncodingType.UTF_8, description='Character encoding for input/output (e.g. utf-8, ISO-8859-1).')
class-attribute
instance-attribute
¶
extra_weights = PydanticField(default_factory=list, description='Additional edge attribute / vertex-weight enrichment for this resource.')
class-attribute
instance-attribute
¶
fail_fast = PydanticField(default=False, description='If True, a transform step fails when required input keys are missing in the current document (rename: all source keys must be present; call: all input keys). If False (default), rename applies only to keys present in the document and functional transforms skip the step when inputs are missing.')
class-attribute
instance-attribute
¶
infer_edge_except = PydanticField(default_factory=list, description='Optional deny-list for inferred edges. Applies only to inferred (greedy) edges, not explicit edge actors.')
class-attribute
instance-attribute
¶
infer_edge_only = PydanticField(default_factory=list, description='Optional allow-list for inferred edges. Applies only to inferred (greedy) edges, not explicit edge actors.')
class-attribute
instance-attribute
¶
infer_edges = PydanticField(default=True, description='If True, infer edges from current vertex population. If False, emit only edges explicitly declared as edge actors in the pipeline.')
class-attribute
instance-attribute
¶
merge_collections = PydanticField(default_factory=list, description='Collection names whose documents fuse when written to the graph -- several observations becoming one node, not two type declarations becoming one. Named `merge_` because it is an authored contract key; the vocabulary calls this sense `fuse`.')
class-attribute
instance-attribute
¶
model_config = {'extra': 'forbid'}
class-attribute
instance-attribute
¶
name = PydanticField(..., description='Name of the resource (e.g. table or file identifier).')
class-attribute
instance-attribute
¶
pipeline = PydanticField(..., description='Pipeline of actor steps to apply in sequence (vertex, edge, transform, descend). Each step is a dict, e.g. {"vertex": "user"} or {"edge": {"from": "a", "to": "b"}}.', validation_alias=AliasChoices('pipeline', 'apply'))
class-attribute
instance-attribute
¶
tolerate_transform_errors = PydanticField(default=True, description='If True, a failing transform step sets its declared output fields to None, records the error, and continues the pipeline.')
class-attribute
instance-attribute
¶
types = PydanticField(default_factory=dict, description='Field name to Python type expression for casting (e.g. {"amount": "float"}).')
class-attribute
instance-attribute
¶
Methods:¶
canonical_field_payload(field_name)
¶
Canonical rendering of field_name, when it differs from its dump.
Consulted by content hashing and by the manifest differ. pipeline
is stored as authored dicts, and a step has several equivalent
spellings; this renders each step in one spelling (see
:func:~graflo.architecture.contract.ingestion.steps.parse.canonical_actor_step).
None means the field's ordinary dump is already canonical.
Source code in graflo/architecture/contract/ingestion/resource.py
collect_vertex_names()
¶
Vertex types referenced by this resource (pipeline and related config).
Source code in graflo/architecture/contract/ingestion/resource.py
pipeline_actor_count()
¶
Count actors in the pipeline without binding schema context.
Source code in graflo/architecture/contract/ingestion/resource.py
ResourceExtraWeightEntry
¶
Bases: ConfigBaseModel
Schema edge plus optional vertex-derived weight rules for DB enrichment.
Source code in graflo/architecture/contract/ingestion/resource.py
Functions:¶
collect_vertex_names_from_pipeline(steps)
¶
Collect vertex names referenced by pipeline steps (including nested descend).
Source code in graflo/architecture/contract/ingestion/resource.py
find_vertex_producing_levels(steps, vertex, *, known_vertices=None)
¶
Index paths of every pipeline level with a step producing vertex.
A path indexes one level's steps per element, descending through descend
steps: [] is the root level, [2] the level inside the root's third
step, [2, 0] one further down. Paths are returned outermost-first.
This is how a level-targeted op finds where to act. The level matters
because an actor reads its transform buffer at its own LocationIndex
with no ancestor fallback, so a derivation appended at the root is invisible
to a vertex produced under a descend.
Two tiers. Levels with an explicit producer — a vertex step or a
router whose table names the class — decide when any exist. Only when none
does, and known_vertices declares the class, every level holding a
vertex_router counts: the router routes the raw discriminator value
as the class name, which is the whole mechanism of a router without a
type_map. An explicit table outranks pass-through so that adding one
dynamic router elsewhere never turns a resolved level ambiguous.
Source code in graflo/architecture/contract/ingestion/resource.py
pipeline_has_vertex_router(steps)
¶
Whether any level of steps holds a vertex_router.
A router routes an unmapped discriminator value as the class name, so a pipeline holding one can produce any class the schema declares — not only the names its steps state. Anything scoping a schema to a resource by the names its pipeline mentions must widen to every class when this is true, or the router silently drops each record whose class it did not name.
Source code in graflo/architecture/contract/ingestion/resource.py
resolve_pipeline_level(steps, path)
¶
Return the live step list path addresses inside steps.
Mutating the returned list mutates steps. Getting that guarantee requires
rewriting each walked descend step into its normalized form and storing
it back: the shorthand spellings ({descend: {apply: [...]}}, a bare
{key, apply}) keep their sub-steps under a different key, so returning
whatever normalize_actor_step built would hand back a list nothing
holds — and an append into it would vanish without a word. Steps off the
path, and the root level itself, are left exactly as authored.
Raises when the path does not resolve. Every index on the way must address
a descend step; those are the only steps that own a nested level.
Source code in graflo/architecture/contract/ingestion/resource.py
step_produces_vertices(step, *, known_vertices=None)
¶
Vertex names a single (non-recursive) actor step produces.
Production, not reference: an edge step names endpoints it looks up, so
it is not counted. A vertex_router produces every type its type_map
can select and every type its vertex_from_map projects — its explicit
targets. A router also routes an unmapped discriminator value as-is, as the
class name, so with known_vertices (the schema's declared classes) it
produces every one of them by pass-through as well: that is how a router
without a type_map works at all, and the static picture must not say
it produces nothing.