graflo.architecture.contract.ingestion.steps.models¶
Pydantic models for actor configuration.
Attributes¶
ActorConfig = Annotated[VertexActorConfig | TransformActorConfig | EdgeActorConfig | DescendActorConfig | VertexRouterActorConfig, PydanticField(discriminator='type')]
module-attribute
¶
Classes¶
DescendActorConfig
¶
Bases: ConfigBaseModel
Configuration for a DescendActor.
Source code in graflo/architecture/contract/ingestion/steps/models.py
Attributes¶
any_key = PydanticField(default=False, description='Process all keys')
class-attribute
instance-attribute
¶
key = PydanticField(default=None, description='Key to descend into')
class-attribute
instance-attribute
¶
pipeline = PydanticField(default_factory=list, alias='apply', description='Pipeline of actors to apply to nested data')
class-attribute
instance-attribute
¶
type = PydanticField(default='descend', description='Actor type discriminator')
class-attribute
instance-attribute
¶
Methods:¶
set_type_and_normalize(data)
classmethod
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
EdgeActorConfig
¶
Bases: EdgeEndpointMatchOptionsConfig
Configuration for an EdgeActor (logical edge + ingestion derivation; flat YAML).
Single-intent mode (default): declare source/target via from/to (static
vertex type names) or source_role/target_role (slot-based dynamic
resolution; source_type_field/target_type_field remain accepted aliases).
One edge intent is emitted per document.
Multi-link mode (links list): declare a list of :class:EdgeLinkConfig items.
Each item emits one edge intent per document, allowing a single pipeline step to produce
multiple relationship types from one flat row. Mutually exclusive with all top-level
source/target fields.
Source code in graflo/architecture/contract/ingestion/steps/models.py
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 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | |
Attributes¶
derivation
property
¶
Normalized ingestion-only fields for assembly/render.
description = PydanticField(default=None, description='Optional semantic description (merged into schema Edge).')
class-attribute
instance-attribute
¶
emit_inverse = PydanticField(default=False, description='Also write the declared inverse of every edge this step writes: for ``(s, t, a)`` with ``a`` paired to ``b`` in ``edge_config.inverses``, ``(t, s, b)`` with the same properties. The relation is mirrored after it is resolved, so ``relation_field``, ``relation_map`` and ``relation_from_key`` are all covered. Only a *materialized* inverse is written -- one whose edge ``(t, s, b)`` is declared; a pair that is only declared, or that the database maintains, stores nothing here.')
class-attribute
instance-attribute
¶
exclude_source = PydanticField(default=None, description='Ingestion: exclude source locations containing this segment.')
class-attribute
instance-attribute
¶
exclude_target = PydanticField(default=None, description='Ingestion: exclude target locations containing this segment.')
class-attribute
instance-attribute
¶
links = PydanticField(default=None, description='Multi-intent list. When set, each item emits one edge intent per document. Mutually exclusive with all top-level source/target/role fields. Use when a single flat row encodes multiple relationships.')
class-attribute
instance-attribute
¶
match = PydanticField(default=None, description='Ingestion: require this segment on both source and target locations.')
class-attribute
instance-attribute
¶
match_source = PydanticField(default=None, description='Ingestion: require this path segment in source locations.')
class-attribute
instance-attribute
¶
match_target = PydanticField(default=None, description='Ingestion: require this path segment in target locations.')
class-attribute
instance-attribute
¶
properties = PydanticField(default_factory=list, description='Edge properties merged into schema Edge (same forms as Edge.properties).')
class-attribute
instance-attribute
¶
relation = PydanticField(default=None, description='Optional fixed logical relation / edge type name.')
class-attribute
instance-attribute
¶
relation_field = PydanticField(default=None, description='Ingestion: document field name for per-document relationship type.')
class-attribute
instance-attribute
¶
relation_from_key = PydanticField(default=False, description='Ingestion: derive per-document relation label from the location key during assembly.')
class-attribute
instance-attribute
¶
relation_map = PydanticField(default=None, description='Map raw relation values to canonical relation names.')
class-attribute
instance-attribute
¶
relation_map_only = PydanticField(default=False, description='When True, a raw relation value absent from ``relation_map`` emits no edge. By default it passes through as the relation name, which is wrong for a step that must write only the mapped relations -- e.g. an inverse step, where a passed-through forward name would be written with swapped endpoints.')
class-attribute
instance-attribute
¶
source = PydanticField(default=None, alias='from', description='Source vertex type name (optional if source_type_field/source_role is set).')
class-attribute
instance-attribute
¶
source_role = PydanticField(default=None, description='Role slot name for the source vertex — role-first alias for source_type_field. When both are set, values must match.')
class-attribute
instance-attribute
¶
source_type_field = PydanticField(default=None, description='Accumulator slot segment for the source vertex (same name as the upstream VertexRouterActor role, inferred from type_field when role is omitted). EdgeActor scans acc_vertex for data at lindex.extend((source_type_field, 0)) to resolve the source type dynamically. Legacy alias for source_role.')
class-attribute
instance-attribute
¶
strict_edge_types = PydanticField(default=False, description='When True, skip documents whose resolved (source_type, target_type) pair is not pre-declared in the resource edge_config at init. When False (default), dynamic pairs are registered at runtime.')
class-attribute
instance-attribute
¶
target = PydanticField(default=None, alias='to', description='Target vertex type name (optional if target_type_field/target_role is set).')
class-attribute
instance-attribute
¶
target_role = PydanticField(default=None, description='Role slot name for the target vertex — role-first alias for target_type_field. When both are set, values must match.')
class-attribute
instance-attribute
¶
target_type_field = PydanticField(default=None, description='Accumulator slot segment for the target vertex (same name as upstream VertexRouterActor role, inferred from type_field when role is omitted). Legacy alias for target_role.')
class-attribute
instance-attribute
¶
type = PydanticField(default='edge', description='Actor type discriminator')
class-attribute
instance-attribute
¶
vertex_weights = PydanticField(default_factory=list, description='Vertex-derived weight rules registered in EdgeDerivationRegistry.')
class-attribute
instance-attribute
¶
Methods:¶
set_type_and_flatten(data)
classmethod
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
validate_type_sources()
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
EdgeEndpointMatchOptionsConfig
¶
Bases: ConfigBaseModel
How an edge step locates its endpoint vertices.
By default both endpoints are matched on the vertex's primary identity,
which is what every edge step has always done. Selecting a secondary
identity instead lets an edge-only source reference endpoints by a business
key. The choice is per endpoint, so source and target may differ.
Source code in graflo/architecture/contract/ingestion/steps/models.py
Attributes¶
on_ambiguous = PydanticField(default=None, description='Override for this step when a secondary identity matches several vertices. Inherits ingestion_model.endpoints_on_ambiguous when unset. Has no effect on endpoints matched by primary identity.')
class-attribute
instance-attribute
¶
source_match = PydanticField(default=None, description="Which identity to match the source endpoint on: omitted or 'identity' for the primary identity (default), a declared secondary identity name, an explicit field list equal to a declared secondary identity, or 'secondary' when the vertex declares exactly one.")
class-attribute
instance-attribute
¶
target_match = PydanticField(default=None, description='Same as source_match, for the target endpoint.')
class-attribute
instance-attribute
¶
EdgeLinkConfig
¶
Bases: EdgeEndpointMatchOptionsConfig
One intent in a multi-link edge step.
Each item in an EdgeActorConfig.links list describes one source→target→relation
binding to emit per document. Equivalent to a single-intent edge step without the
links field itself.
Slot resolution uses role-first semantics (source_role / target_role).
Legacy aliases (source_type_field / target_type_field) are accepted and
canonicalized to their role counterparts. The slot name is the accumulator segment
populated by an upstream vertex step with a matching role, or by
vertex_router.role (which defaults to type_field when omitted).
Source code in graflo/architecture/contract/ingestion/steps/models.py
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 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 | |
Attributes¶
emit_inverse = PydanticField(default=False, description='Also write the declared inverse of every edge this link writes: for ``(s, t, a)`` with ``a`` paired to ``b`` in ``edge_config.inverses``, ``(t, s, b)`` with the same properties. The relation is mirrored after it is resolved, so ``relation_field``, ``relation_map`` and ``relation_from_key`` are all covered. Only a *materialized* inverse is written -- one whose edge ``(t, s, b)`` is declared; a pair that is only declared, or that the database maintains, stores nothing here.')
class-attribute
instance-attribute
¶
match_source = PydanticField(default=None, description='Require this path segment in source vertex locations.')
class-attribute
instance-attribute
¶
match_target = PydanticField(default=None, description='Require this path segment in target vertex locations.')
class-attribute
instance-attribute
¶
model_config = {'extra': 'forbid', 'populate_by_name': True}
class-attribute
instance-attribute
¶
relation = PydanticField(default=None, description='Fixed relation / edge type name for this link.')
class-attribute
instance-attribute
¶
relation_field = PydanticField(default=None, description='Document field name for per-document relationship type.')
class-attribute
instance-attribute
¶
source = PydanticField(default=None, alias='from', description='Static source vertex type name. Exclusive with source_type_field / source_role.')
class-attribute
instance-attribute
¶
source_role = PydanticField(default=None, description='Role-first alias for source_type_field (same accumulator segment name). When both are set, values must match.')
class-attribute
instance-attribute
¶
source_type_field = PydanticField(default=None, description="Accumulator slot segment for the source vertex (same name as upstream vertex/vertex_router role). Exclusive with 'from' and source_role.")
class-attribute
instance-attribute
¶
target = PydanticField(default=None, alias='to', description='Static target vertex type name. Exclusive with target_type_field / target_role.')
class-attribute
instance-attribute
¶
target_role = PydanticField(default=None, description='Role-first alias for target_type_field (same accumulator segment name). When both are set, values must match.')
class-attribute
instance-attribute
¶
target_type_field = PydanticField(default=None, description="Accumulator slot segment for the target vertex (same name as upstream vertex/vertex_router role). Exclusive with 'to' and target_role.")
class-attribute
instance-attribute
¶
Methods:¶
resolve_and_validate()
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
TransformActorConfig
¶
Bases: ConfigBaseModel
Configuration for a TransformActor.
Source code in graflo/architecture/contract/ingestion/steps/models.py
Attributes¶
call = PydanticField(default=None, description='Function-call configuration in explicit DSL form: transform.call.')
class-attribute
instance-attribute
¶
rename = PydanticField(default=None, description='Rename mapping in explicit DSL form: transform.rename.')
class-attribute
instance-attribute
¶
type = PydanticField(default='transform', description='Actor type discriminator')
class-attribute
instance-attribute
¶
when = PydanticField(default=None, description='Optional guard: the step runs only when the observation satisfies it, and writes nothing otherwise. See TransformGuardConfig.')
class-attribute
instance-attribute
¶
Methods:¶
set_type_and_flatten(data)
classmethod
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
validate_mode()
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
TransformCallConfig
¶
Bases: ConfigBaseModel
Explicit function call transform DSL payload.
Source code in graflo/architecture/contract/ingestion/steps/models.py
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 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 | |
Attributes¶
dress = PydanticField(default=None, description='Pivot dressing output for scalar call results.')
class-attribute
instance-attribute
¶
foo = PydanticField(default=None, description='Transform function name in module.')
class-attribute
instance-attribute
¶
input = PydanticField(default=None, description='Input field names for function execution.')
class-attribute
instance-attribute
¶
input_groups = PydanticField(default=None, description='Explicit groups of input fields for repeated tuple-style function calls.')
class-attribute
instance-attribute
¶
keys = PydanticField(default=None, description="Optional key selection for target='keys'.")
class-attribute
instance-attribute
¶
module = PydanticField(default=None, description='Module containing transform function.')
class-attribute
instance-attribute
¶
output = PydanticField(default=None, description='Optional output field names.')
class-attribute
instance-attribute
¶
output_groups = PydanticField(default=None, description='Optional output field groups aligned with input_groups.')
class-attribute
instance-attribute
¶
params = PydanticField(default_factory=dict, description='Function call keyword arguments.')
class-attribute
instance-attribute
¶
strategy = PydanticField(default=None, description='Execution strategy for function calls.')
class-attribute
instance-attribute
¶
target = PydanticField(default=None, description='Transform target. Omit with call.use to inherit from ingestion_model.transforms entry. values=transform input values, keys=transform selected document keys. Inline calls (no use) default to values when omitted.')
class-attribute
instance-attribute
¶
use = PydanticField(default=None, description='Named transform reference from ingestion_model.transforms. When provided, module/foo must be omitted.')
class-attribute
instance-attribute
¶
Classes¶
KeySelectionConfig
¶
Bases: ConfigBaseModel
Selection of document keys for key-target transforms.
Source code in graflo/architecture/contract/ingestion/steps/models.py
Attributes¶
mode = PydanticField(default='all', description="How keys are selected when target='keys': all=all keys, include=only provided keys, exclude=all except provided keys.")
class-attribute
instance-attribute
¶names = PydanticField(default_factory=list, description='Key names used by include/exclude selection modes.')
class-attribute
instance-attribute
¶Methods:¶
validate_mode_names()
¶Source code in graflo/architecture/contract/ingestion/steps/models.py
Methods:¶
normalize_io(data)
classmethod
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
validate_target()
¶
Source code in graflo/architecture/contract/ingestion/steps/models.py
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 | |
TransformGuardConfig
¶
Bases: ConfigBaseModel
A guard deciding whether a transform step runs on an observation.
The step runs only when field holds one of values (exact match —
the same test a vertex_router applies to its type_map keys). When
it does not, the step writes nothing: no output, no None. That is
what makes a guard different from a function returning None — behind a
router, which merges the transform buffer into one observation dict, a
later None overwrites an earlier real value, whereas a step that did
not run leaves the value alone. A missing field fails the guard.
Source code in graflo/architecture/contract/ingestion/steps/models.py
Attributes¶
field = PydanticField(..., description='Observation field the guard reads (raw document key).')
class-attribute
instance-attribute
¶
values = PydanticField(..., alias='in', min_length=1, description='Values of ``field`` that let the step run; exact match.')
class-attribute
instance-attribute
¶
Methods:¶
passes(observation)
¶
Whether observation satisfies the guard.
VertexActorConfig
¶
Bases: VertexExtractionOptionsConfig
Configuration for a VertexActor.
Source code in graflo/architecture/contract/ingestion/steps/models.py
Attributes¶
lookup_only = PydanticField(default=False, description='When true the extracted documents are used to locate existing vertices for edge endpoints but are never written. Set this on edge-only resources, which reference a vertex without owning it — their documents typically carry a secondary identity and no primary key, so upserting them would create keyless duplicates.')
class-attribute
instance-attribute
¶
type = PydanticField(default='vertex', description='Actor type discriminator')
class-attribute
instance-attribute
¶
vertex = PydanticField(..., description='Name of the vertex type to create')
class-attribute
instance-attribute
¶
Methods:¶
set_type(data)
classmethod
¶
VertexExtractionOptionsConfig
¶
Bases: ConfigBaseModel
Shared field-extraction options for vertex-like actors.
Source code in graflo/architecture/contract/ingestion/steps/models.py
Attributes¶
extraction_scope = PydanticField(default='full', description='Field extraction policy. full (default) includes passthrough for remaining schema properties from the merged observation (doc + same-location transform buffer), while mapped_only limits extraction to explicit field mappings declared in from.')
class-attribute
instance-attribute
¶
from_doc = PydanticField(default=None, alias='from', description='Projection: {vertex_field: doc_field}.')
class-attribute
instance-attribute
¶
keep_fields = PydanticField(default=None, description='Optional list of fields to keep')
class-attribute
instance-attribute
¶
role = PydanticField(default=None, description='Optional accumulator slot segment used for storage/addressing. Vertex-like actors store observations at lindex.extend((role, 0)) when set. When omitted, actor-specific defaults may apply.')
class-attribute
instance-attribute
¶
VertexRouterActorConfig
¶
Bases: VertexExtractionOptionsConfig
Configuration for a VertexRouterActor.
Field handling matches :class:VertexActorConfig: optional router-level from /
from_doc (and per-type vertex_from_map), optional keep_fields, and the
same merged observation dict is passed to the lazily created :class:VertexActor
(no separate slice / rename layer).