cursus.core¶
Cursus Core module.
This module provides the core functionality for Cursus, including: - Pipeline assembling and template management - DAG compilation and configuration resolution - Configuration field management and three-tier architecture - Dependency resolution and specification management - Base classes for configurations, contracts, specifications, and builders
- class DependencyType(*values)[source]¶
Bases:
EnumTypes of dependencies in the pipeline.
- MODEL_ARTIFACTS = 'model_artifacts'¶
- PROCESSING_OUTPUT = 'processing_output'¶
- TRAINING_DATA = 'training_data'¶
- HYPERPARAMETERS = 'hyperparameters'¶
- PAYLOAD_SAMPLES = 'payload_samples'¶
- CUSTOM_PROPERTY = 'custom_property'¶
- class NodeType(*values)[source]¶
Bases:
EnumTypes of nodes in the pipeline based on their dependency/output characteristics.
- SOURCE = 'source'¶
- INTERNAL = 'internal'¶
- SINK = 'sink'¶
- SINGULAR = 'singular'¶
- class ValidationResult(*, is_valid, errors=<factory>, warnings=<factory>)[source]¶
Bases:
BaseModelResult of script contract validation
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class ScriptAnalyzer(script_path)[source]¶
Bases:
objectAnalyzes Python scripts to extract I/O patterns and environment variable usage
- class StepInterface(*, step_type, node_type=NodeType.INTERNAL, registry=<factory>, compute=<factory>, patterns=<factory>, contract, spec=<factory>, variants=<factory>)[source]¶
Bases:
BaseModelValidated representation of a .step.yaml file.
This is the single message passed among dep resolver, builder, and assembler. Replaces the previous (ScriptContract|StepContract, StepSpecification) tuple.
Build it from a parsed YAML dict via
from_yaml(), which applies any requestedjob_typevariant before validation.- property dependencies: Dict[str, DependencyDecl]¶
- classmethod from_yaml(data, job_type=None)[source]¶
Build a StepInterface from a parsed
.step.yamldict, resolving variants.When
job_typenames a variant, that variant’sspec/contractoverrides are deep-merged over the base sections before validation. The merge is recursive: a variant that lists only a subset ofspec.dependencies(oroutputs/ contractinputs) overrides just those ports’ fields and leaves the rest of the base set intact — it does not replace the whole nested dict. Steps without a matching variant fall back to the base sections unchanged.A shallow merge here was a latent bug: because variants routinely restate only the ports they tweak,
{**base, **variant}at the section level dropped every base port the variant happened to omit (e.g. it droppedhyperparameters_s3_urifromRiskTableMapping’s variants, which then violated the contract↔spec alignment invariant and raised at construction).
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- property outputs: Dict[str, OutputDecl]¶
- property script_contract: ContractSection¶
Legacy StepSpecification.script_contract accessor.
- validate_contract_alignment()[source]¶
Validate that the contract aligns with the spec.
Mirrors legacy StepSpecification.validate_contract_alignment: every contract input must have a matching spec dependency, and every contract output a matching spec output (extra spec deps/outputs and output aliases allowed). Returns a ValidationResult (is_valid / errors).
- registry: RegistrySection¶
- compute: ComputeSpec¶
Declarative COMPUTE descriptor (FZ 31e1d3k) — a TOP-LEVEL section (peer of contract/spec) because it describes the BUILDER’s compute object (processor/estimator/model/transformer), not the script contract: script-less steps (CreateModel/Transform) carry a near-empty contract but a full compute.
_sync_and_alignmirrors it ontocontract.computefor back-compat. Empty (kind=None) ⇒ the step keeps its own factory.
- patterns: PatternsSection¶
Per-axis STRATEGY-SELECTION knobs (FZ 31e1d3f1) — the blueprint that wires pattern injection (step_assembly / include_job_type_in_path / direct_input_keys), read into the bound handler by
_auto_bind_handlerso the YAML steers the build, not a builder shell.
- contract: ContractSection¶
- spec: SpecSection¶
- variants: Dict[str, VariantDecl]¶
- class ModelHyperparameters(*, full_field_list, cat_field_list, tab_field_list, id_name, label_name, multiclass_categories, categorical_features_to_encode=<factory>, model_class='base_model', device=-1, header=0, lr=3e-05, batch_size=2, eval_batch_size_multiplier=2.0, max_epochs=3, metric_choices=['f1_score', 'auroc'], optimizer='SGD', class_weights=None, **extra_data)[source]¶
Bases:
BaseModelBase model hyperparameters for training tasks.
Fields are organized into three tiers: 1. Tier 1: Essential User Inputs - fields that users must explicitly provide 2. Tier 2: System Inputs with Defaults - fields with reasonable defaults that can be overridden 3. Tier 3: Derived Fields - fields calculated from other fields (private attributes with properties)
- categorize_fields()[source]¶
Categorize all fields into three tiers: 1. Tier 1: Essential User Inputs - fields with no defaults (required) 2. Tier 2: System Inputs - fields with defaults (optional) 3. Tier 3: Derived Fields - properties that access private attributes
- classmethod from_base_hyperparam(base_hyperparam, **kwargs)[source]¶
Create a new hyperparameter instance from a base hyperparameter. This is a virtual method that all derived classes can use to inherit from a parent config.
- Parameters:
base_hyperparam (ModelHyperparameters) – Parent ModelHyperparameters instance
**kwargs (Any) – Additional arguments specific to the derived class
- Returns:
A new instance of the derived class initialized with parent fields and additional kwargs
- Return type:
- get_public_init_fields()[source]¶
Get a dictionary of public fields suitable for initializing a child hyperparameter. Only includes fields that should be passed to child class constructors. Both essential user inputs and system inputs with defaults or user-overridden values are included to ensure all user customizations are properly propagated.
- Returns:
Dictionary of field names to values for child initialization
- Return type:
Dict[str, Any]
- model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'protected_namespaces': (), 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_post_init(context, /)¶
This function is meant to behave like a BaseModel method to initialize private attributes.
It takes context as an argument since that’s what pydantic-core passes when calling it.
- Parameters:
self (BaseModel) – The BaseModel instance.
context (Any) – The context.
- class BasePipelineConfig(*, author, bucket, role, region, service_name, pipeline_version, model_class='xgboost', current_date=<factory>, framework_version='2.1.0', py_version='py310', source_dir=None, enable_caching=False, use_secure_pypi=False, max_runtime_seconds=172800, project_root_folder, **extra_data)[source]¶
-
Base configuration with shared pipeline attributes and self-contained derivation logic.
- categorize_fields()[source]¶
Categorize all fields into three tiers: 1. Tier 1: Essential User Inputs - public fields with no defaults (required) 2. Tier 2: System Inputs - public fields with defaults (optional) 3. Tier 3: Derived Fields - properties that access private attributes
- property effective_source_dir: str | None¶
Get effective source directory with hybrid resolution.
This base implementation works with just source_dir (which can be None). Processing configs override this to handle both processing_source_dir and source_dir.
Resolution Priority: 1. Hybrid resolution of source_dir 2. Legacy value (source_dir) 3. None if source_dir is not provided
- classmethod from_base_config(base_config, **kwargs)[source]¶
Create a new configuration instance from a base configuration. This is a virtual method that all derived classes can use to inherit from a parent config.
- Parameters:
base_config (BasePipelineConfig) – Parent BasePipelineConfig instance
**kwargs (Any) – Additional arguments specific to the derived class
- Returns:
A new instance of the derived class initialized with parent fields and additional kwargs
- Return type:
- classmethod get_config_class_name(step_name)[source]¶
Get the configuration class name from a step name using existing registry functions.
- get_environment_variables(declared_env_vars=None)[source]¶
Resolve the env-var VALUES for the names the step interface DECLARES (FZ 31e1d3g).
The interface (
.step.yamlenv_vars) declares WHICH env vars a step uses; this config supplies the VALUES. The single-source rule: the interface drives the key set, config resolves each one — by_env_overrides()first (computed/aliased), else convention (NAME->self.name, type-formatted). Names that resolve to nothing are omitted, so a declared-but-absent optional falls back to its interface default in the builder.Subclasses with a bespoke collector may override this entirely (and ignore
declared_env_vars) to return their full env dict — that path is preserved for back-compat.
- get_job_arguments()[source]¶
Build the script’s CLI arguments — config is the single source (FZ 31e1d3h).
Base default: no CLI arguments (
None). The builder’s_get_job_argumentscalls this; a step-config that passes arguments to its script OVERRIDES this method. The common--job_typecase has a ready helper,_job_type_arg()— a config opts in withreturn self._job_type_arg().None(not[]) is the “no args” contract the SDK ProcessingStep / processor.run expect.
- get_public_init_fields()[source]¶
Get a dictionary of public fields suitable for initializing a child config. Only includes fields that should be passed to child class constructors. Both essential user inputs and system inputs with defaults or user-overridden values are included to ensure all user customizations are properly propagated to derived classes.
- Returns:
Dictionary of field names to values for child initialization
- Return type:
Dict[str, Any]
- get_script_contract()[source]¶
Get script contract for this configuration using optimized step catalog discovery.
This optimized implementation uses the step catalog system for efficient contract discovery with O(1) lookups and workspace awareness, falling back to legacy methods for backward compatibility.
- Returns:
Script contract instance or None if not available
- Return type:
Any | None
- get_script_path(default_path=None)[source]¶
Get script path for this configuration.
This method provides a default implementation that returns None, since not all step types require scripts (e.g., Model creation steps don’t need scripts).
Derived classes that need script paths should override this method with their specific requirements: - Processing steps: Combine entry_point with source_dir - Training steps: Use contract entry_point or combine with source_dir - Model steps: May not need scripts at all
- classmethod get_step_name(config_class_name)[source]¶
Get the step name for a configuration class using existing registry functions.
- model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'protected_namespaces': (), 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_post_init(context, /)¶
This function is meant to behave like a BaseModel method to initialize private attributes.
It takes context as an argument since that’s what pydantic-core passes when calling it.
- Parameters:
self (BaseModel) – The BaseModel instance.
context (Any) – The context.
- property pipeline_description: str¶
Get pipeline description derived from service_name, model_class, and region.
- property pipeline_name: str¶
Get pipeline name derived from author, service_name, model_class, and region.
- print_config()[source]¶
Print complete configuration information organized by tiers. This method automatically categorizes fields by examining their characteristics: - Tier 1: Essential User Inputs (public fields without defaults) - Tier 2: System Inputs (public fields with defaults) - Tier 3: Derived Fields (properties that provide access to private fields)
- resolve_hybrid_path(relative_path)[source]¶
Resolve a path using the hybrid path resolution system.
This method uses the hybrid path resolution system to find files across different deployment scenarios (Lambda/MODS bundled, development monorepo, pip-installed separated).
- property resolved_source_dir: str | None¶
Get resolved source directory using hybrid resolution.
Returns None if source_dir is not provided, since it’s optional in base class. Processing, training, and model step configs should ensure source_dir is provided.
- property script_contract: Any | None¶
Property accessor for script contract.
- Returns:
Script contract instance or None if not available
- class StepBuilderBase(config, spec=None, sagemaker_session=None, role=None, registry_manager=None, dependency_resolver=None)[source]¶
Bases:
ABCBase class for all step builders
## Safe Logging Methods
To handle Pipeline variables safely in logs, use these methods:
```python # Instead of: logger.info(f”Using input path: {input_path}”) # May raise TypeError for Pipeline variables
# Use: self.log_info(“Using input path: %s”, input_path) # Handles Pipeline variables safely ```
Standard Pattern for input_names and output_names:
In config classes:
`python output_names = {"logical_name": "DescriptiveValue"} # VALUE used as key in outputs dict input_names = {"logical_name": "ScriptInputName"} # KEY used as key in inputs dict `In pipeline code: ```python # Get output using VALUE from output_names output_value = step_a.config.output_names[“logical_name”] output_uri = step_a.properties.ProcessingOutputConfig.Outputs[output_value].S3Output.S3Uri
# Set input using KEY from input_names inputs = {“logical_name”: output_uri} ```
In step builders: ```python # For outputs - validate using VALUES value = self.config.output_names[“logical_name”] if value not in outputs:
raise ValueError(f”Must supply an S3 URI for ‘{value}’”)
# For inputs - validate using KEYS for logical_name in self.config.input_names.keys():
- if logical_name not in inputs:
raise ValueError(f”Must supply an S3 URI for ‘{logical_name}’”)
Developers should follow this standard pattern when creating new step builders. The base class provides helper methods to enforce and simplify this pattern:
_validate_inputs(): Validates inputs using KEYS from input_names
_validate_outputs(): Validates outputs using VALUES from output_names
_get_script_input_name(): Maps logical name to script input name
_get_output_destination_name(): Maps logical name to output destination name
_create_standard_processing_input(): Creates standardized ProcessingInput
_create_standard_processing_output(): Creates standardized ProcessingOutput
Property Path Registry:
To bridge the gap between definition-time and runtime, step builders can register property paths that define how to access their outputs at runtime. This solves the issue where outputs are defined statically but only accessible via specific runtime paths.
register_property_path(): Registers a property path for a logical output name
get_property_paths(): Gets all registered property paths for this step
- COMMON_PROPERTIES = {'dependencies': 'Optional list of dependent steps', 'enable_caching': 'Whether to enable caching for this step (default: True)'}¶
- MODEL_OUTPUT_PROPERTIES = {'model': 'SageMaker model object', 'model_artifacts_path': 'S3 path to model artifacts'}¶
- STEP_NAME: str | None = None¶
The canonical registry step name for THIS builder (singular), e.g. “XGBoostTraining”. This is the authoritative identity slot
_get_step_namereads (FZ 31e1d3g3 Phase C1): every routed shell +TemplateStepBuildersets it, the materializer stamps it on synthesized fileless builders, and once the per-step shell classes are deleted it is the ONLY reliable canonical key (the class name collapses toTemplateStepBuilder). Declared here on the root so the base method that reads it owns the slot, and so it is not confused withSTEP_NAMES(PLURAL — the whole registry dict, below).Noneon a hand-written builder, which falls back to the legacy<Name>StepBuilderclass-name convention.
- property STEP_NAMES: Dict[str, Any]¶
Lazy load step names with workspace context awareness.
This property now supports workspace-aware step name resolution by: 1. Extracting workspace context from config or environment 2. Using hybrid registry manager for workspace-specific step names 3. Falling back to traditional registry if hybrid is unavailable 4. Maintaining backward compatibility with existing code
- TRAINING_OUTPUT_PROPERTIES = {'model_data': 'S3 path to the model artifacts', 'model_data_url': 'S3 URL to the model artifacts', 'training_job_name': 'Name of the training job'}¶
- abstractmethod create_step(**kwargs)[source]¶
Create pipeline step.
This method should be implemented by all step builders to create a SageMaker pipeline step. It accepts a dictionary of keyword arguments that can be used to configure the step.
Common parameters that all step builders should handle: - dependencies: Optional list of steps that this step depends on - enable_caching: Whether to enable caching for this step (default: True)
Step-specific parameters should be extracted from kwargs as needed.
- Parameters:
**kwargs (Any) – Keyword arguments for configuring the step
- Returns:
SageMaker pipeline step
- Return type:
Step
- extract_inputs_from_dependencies(dependency_steps)[source]¶
Extract inputs from dependency steps using the UnifiedDependencyResolver.
- Parameters:
dependency_steps (List[Step]) – List of dependency steps
- Returns:
Dictionary of inputs extracted from dependency steps
- Raises:
ValueError – If dependency resolver is not available or specification is not provided
- Return type:
- get_all_property_paths()[source]¶
Get all property paths defined in the specification.
- Returns:
Mapping from logical output names to runtime property paths
- Return type:
- get_optional_dependencies()[source]¶
Get list of optional dependency logical names from specification.
This method provides direct access to the optional dependencies defined in the step specification.
- Returns:
List of logical names for optional dependencies
- Raises:
ValueError – If specification is not provided
- Return type:
- get_outputs()[source]¶
Get output specifications directly from the step specification.
This method provides direct access to the outputs defined in the step specification, returning the complete OutputSpec objects.
- Returns:
Dictionary mapping output names to their OutputSpec objects
- Raises:
ValueError – If specification is not provided
- Return type:
- get_property_path(logical_name, format_args=None)[source]¶
Get property path for an output using the specification.
This method retrieves the property path for an output from the specification. It also supports template formatting if format_args are provided.
- Parameters:
- Returns:
Property path from specification, formatted with args if provided, or None if not found
- Return type:
str | None
- get_required_dependencies()[source]¶
Get list of required dependency logical names from specification.
This method provides direct access to the required dependencies defined in the step specification.
- Returns:
List of logical names for required dependencies
- Raises:
ValueError – If specification is not provided
- Return type:
- set_execution_prefix(execution_prefix=None)[source]¶
Set the execution prefix for dynamic output path resolution.
This method is called by PipelineAssembler to provide the execution prefix that step builders use for dynamic output path generation.
Based on analysis of regional_xgboost.py, only PIPELINE_EXECUTION_TEMP_DIR is used by step builders for output paths. Other pipeline parameters (KMS_ENCRYPTION_KEY_PARAM, VPC_SUBNET, SECURITY_GROUP_ID) are used at the pipeline level, not in step builders.
- validate_configuration()[source]¶
Validate builder-context configuration requirements (optional hook).
No-op by default. The Pydantic config class is the authority for config validation — required fields,
@field_validator/@model_validatorconstraints, and defaults are all enforced at config construction, BEFORE the builder runs. A config that constructs is valid by definition, so most builders need no override here (FZ 31e1d3e). Override ONLY to assert an invariant the config genuinely cannot express — one involving builder context (self.role/self.session/self.spec/ resolved dependencies) or a cross-field rule not yet on the config model.
- class PipelineAssembler(dag, config_map, step_catalog=None, sagemaker_session=None, role=None, pipeline_parameters=None, registry_manager=None, dependency_resolver=None)[source]¶
Bases:
objectAssembles pipeline steps using a DAG and step builders with specification-based dependency resolution.
This class implements a component-based approach to building SageMaker Pipelines, leveraging the specification-based dependency resolution system to simplify the code and improve maintainability.
The assembler follows these steps to build a pipeline: 1. Initialize step builders for all steps in the DAG 2. Determine the build order using topological sort 3. Propagate messages between steps using the dependency resolver 4. Instantiate steps in topological order, delegating input/output handling to builders 5. Create the pipeline with the instantiated steps
This approach allows for a flexible and modular pipeline definition, where each step is responsible for its own configuration and input/output handling.
- analyze_pipeline_structure()[source]¶
Analyze and print the complete pipeline structure including: 1. Dependency graph between steps 2. Input assignments with logical names, property paths, and destination paths
This method uses internal assembler data (step_messages, step_builders, step_instances) to provide comprehensive insights into how the pipeline is structured.
This should be called after generate_pipeline() to ensure all steps are instantiated.
- classmethod create_with_components(dag, config_map, step_catalog=None, context_name=None, **kwargs)[source]¶
Create pipeline assembler with managed components.
This factory method creates a pipeline assembler with properly configured dependency components from the factory module.
- Parameters:
dag (PipelineDAG) – PipelineDAG instance defining the pipeline structure
config_map (Dict[str, BasePipelineConfig]) – Mapping from step name to config instance
step_catalog (StepCatalog | None) – StepCatalog for config-to-builder resolution
context_name (str | None) – Optional context name for registry
**kwargs (Any) – Additional arguments to pass to the constructor
- Returns:
Configured PipelineAssembler instance
- Return type:
- generate_pipeline(pipeline_name)[source]¶
Build and return a SageMaker Pipeline object.
This method builds the pipeline by: 1. Propagating messages between steps using specification-based matching 2. Instantiating steps in topological order 3. Creating the pipeline with the instantiated steps
- Parameters:
pipeline_name (str) – Name of the pipeline
- Returns:
SageMaker Pipeline object
- Return type:
Pipeline
- generate_single_node_pipeline(target_node, manual_inputs, pipeline_name)[source]¶
Generate pipeline with single node and manual inputs.
This method bypasses normal message propagation and dependency resolution, directly instantiating the target node with provided manual inputs.
Backward Compatibility: This method is completely isolated and does not affect existing pipeline generation flow. The normal generate_pipeline() method remains unchanged.
- Parameters:
- Returns:
Single-node Pipeline
- Raises:
ValueError – If target node not found in step builders
- Return type:
Pipeline
Example
>>> manual_inputs = { ... "input_path": "s3://bucket/run-123/preprocess/data/" ... } >>> pipeline = assembler.generate_single_node_pipeline( ... target_node="train", ... manual_inputs=manual_inputs, ... pipeline_name="train-debug-001" ... )
- class PipelineTemplateBase(config_path, sagemaker_session=None, role=None, registry_manager=None, dependency_resolver=None, pipeline_parameters=None, step_catalog=None)[source]¶
Bases:
ABCBase class for all pipeline templates.
This class provides a consistent structure and common functionality for all pipeline templates, enforcing best practices and ensuring proper component lifecycle management.
The template follows these steps to build a pipeline: 1. Load configurations from file 2. Initialize component dependencies (registry_manager, dependency_resolver) 3. Create the DAG, config_map, and step_builder_map 4. Use PipelineAssembler to assemble the pipeline
This provides a standardized approach for creating pipeline templates, reducing code duplication and enforcing best practices.
- CONFIG_CLASSES: Dict[str, Type[BasePipelineConfig]] = {}¶
- analyze_pipeline_structure()[source]¶
Analyze and print the complete pipeline structure.
Delegates to the PipelineAssembler’s analyze_pipeline_structure method. Must be called after generate_pipeline().
- Raises:
AttributeError – If called before generate_pipeline()
- classmethod build_in_thread(config_path, **kwargs)[source]¶
Build pipeline using thread-local component instances.
This method creates a template with thread-local component instances, ensuring thread safety in multi-threaded environments.
- classmethod build_with_context(config_path, **kwargs)[source]¶
Build pipeline with scoped dependency resolution context.
This method creates a template with a dependency resolution context that ensures proper cleanup of resources after pipeline generation.
- classmethod create_with_components(config_path, context_name=None, **kwargs)[source]¶
Create template with managed dependency components.
This factory method creates a template with properly configured dependency resolution components from the factory module.
- Parameters:
- Returns:
Template instance with managed components
- Return type:
- generate_pipeline()[source]¶
Generate the SageMaker Pipeline.
This method coordinates the pipeline generation process: 1. Create the DAG and config_map (the assembler self-discovers builders) 2. Create the PipelineAssembler 3. Generate the pipeline 4. Store pipeline metadata
- Returns:
SageMaker Pipeline
- Return type:
Pipeline
- set_pipeline_parameters(parameters=None)[source]¶
Set pipeline parameters for this template.
This method allows DAGCompiler to inject custom parameters that will be used instead of the default parameters defined in subclasses.
- Parameters:
parameters (List[ParameterString] | None) – List of pipeline parameters to use
- compile_dag_to_pipeline(dag=None, dag_path=None, config_path=None, sagemaker_session=None, role=None, pipeline_name=None, **kwargs)[source]¶
Compile a PipelineDAG into a complete SageMaker Pipeline.
This is the main entry point for users who want a simple, one-call compilation from DAG to pipeline.
- Parameters:
dag (PipelineDAG | None) – PipelineDAG instance defining the pipeline structure (optional if dag_path provided)
dag_path (str | None) – Path to serialized DAG JSON file (optional if dag provided)
config_path (str) – Path to configuration file containing step configs
sagemaker_session (PipelineSession | None) – SageMaker session for pipeline execution
role (str | None) – IAM role for pipeline execution
pipeline_name (str | None) – Optional pipeline name override
**kwargs (Any) – Additional arguments passed to template constructor
- Returns:
Generated SageMaker Pipeline ready for execution
- Raises:
ValueError – If neither dag nor dag_path provided, or if DAG is invalid
FileNotFoundError – If dag_path or config_path files not found
ConfigurationError – If configuration validation fails
RegistryError – If step builders not found for config types
- Return type:
Pipeline
Example
>>> # Option 1: Using PipelineDAG instance >>> dag = PipelineDAG() >>> dag.add_node("data_load") >>> dag.add_node("preprocess") >>> dag.add_edge("data_load", "preprocess") >>> >>> pipeline = compile_dag_to_pipeline( ... dag=dag, ... config_path="configs/my_pipeline.json", ... sagemaker_session=session, ... role="arn:aws:iam::123456789012:role/SageMakerRole" ... ) >>> pipeline.upsert() >>> >>> # Option 2: Loading DAG from file >>> pipeline = compile_dag_to_pipeline( ... dag_path="saved_dags/my_pipeline.json", ... config_path="configs/my_pipeline.json", ... sagemaker_session=session, ... role="arn:aws:iam::123456789012:role/SageMakerRole" ... )
- class PipelineDAGCompiler(config_path, sagemaker_session=None, role=None, config_resolver=None, step_catalog=None, pipeline_parameters=None, project_root=None, anchor_file=None, workspace_dirs=None, **kwargs)[source]¶
Bases:
objectAdvanced API for DAG-to-template compilation with additional control.
This class provides more control over the compilation process, including validation, debugging, and customization options.
- analyze_pipeline_structure()[source]¶
Analyze and print the complete pipeline structure.
Delegates to the template’s analyze_pipeline_structure method. Must be called after compile() or compile_with_report().
- Raises:
AttributeError – If called before compilation
- compile(dag, pipeline_name=None, **kwargs)[source]¶
Compile DAG to pipeline with full control.
- Parameters:
dag (PipelineDAG | str) – PipelineDAG instance or path to serialized DAG file
pipeline_name (str | None) – Optional pipeline name override
**kwargs (Any) – Additional arguments for template
- Returns:
Generated SageMaker Pipeline
- Raises:
PipelineAPIError – If compilation fails
- Return type:
Pipeline
- compile_with_report(dag, pipeline_name=None, **kwargs)[source]¶
Compile DAG to pipeline and return detailed compilation report.
- Parameters:
dag (PipelineDAG | str) – PipelineDAG instance or path to serialized DAG file
pipeline_name (str | None) – Optional pipeline name override
**kwargs (Any) – Additional arguments for template
- Returns:
Tuple of (Pipeline, ConversionReport)
- Return type:
Tuple[Pipeline, ConversionReport]
- create_template(dag, **kwargs)[source]¶
Create a pipeline template from the DAG without generating the pipeline.
This allows inspecting or modifying the template before pipeline generation.
- Parameters:
dag (PipelineDAG) – PipelineDAG instance to create a template for
**kwargs (Any) – Additional arguments for template
- Returns:
DynamicPipelineTemplate instance ready for pipeline generation
- Raises:
PipelineAPIError – If template creation fails
- Return type:
- get_last_template()[source]¶
Get the last template used during compilation.
This template will have its pipeline_metadata populated from the generation process. Use this method to get access to a template that has gone through the complete pipeline generation process, particularly useful for execution document generation.
- Returns:
The last template used in compilation, or None if no compilation has occurred
- Return type:
Optional[‘DynamicPipelineTemplate’]
- get_supported_step_types()[source]¶
Get list of supported step types.
- Returns:
List of supported step type names
- Return type:
- preview_resolution(dag)[source]¶
Preview how DAG nodes will be resolved to configs and builders.
Returns a detailed preview showing: - Node → Configuration mappings - Configuration → Step Builder mappings - Detected step types and dependencies - Potential issues or ambiguities
- Parameters:
dag (PipelineDAG | str) – PipelineDAG instance or path to serialized DAG file
- Returns:
ResolutionPreview with detailed resolution information
- Return type:
- validate_dag_compatibility(dag)[source]¶
Validate that DAG nodes have corresponding configurations.
Returns detailed validation results including: - Missing configurations - Unresolvable step builders - Configuration validation errors - Dependency resolution issues
- Parameters:
dag (PipelineDAG | str) – PipelineDAG instance or path to serialized DAG file
- Returns:
ValidationResult with detailed validation information
- Return type:
- StepConfigResolver¶
alias of
StepConfigResolverAdapter
- class ResolutionPreview(*, node_config_map, config_builder_map, resolution_confidence, ambiguous_resolutions=<factory>, recommendations=<factory>)[source]¶
Bases:
BaseModelPreview of how DAG nodes will be resolved.
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class ConversionReport(*, pipeline_name, steps, resolution_details, avg_confidence, warnings=<factory>, metadata=<factory>)[source]¶
Bases:
BaseModelReport generated after successful pipeline conversion.
- model_config: ClassVar[ConfigDict] = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class ValidationEngine[source]¶
Bases:
objectEngine for validating DAG-config compatibility.
- validate_dag_compatibility(dag_nodes, available_configs, config_map, builder_registry, metadata=None)[source]¶
Validate DAG-config compatibility.
- Parameters:
available_configs (Dict[str, Any]) – Available configuration instances
config_map (Dict[str, Any]) – Resolved node-to-config mapping
metadata (Dict[str, Any] | None) – Optional pipeline metadata; its
config_typesmap (node -> config class) records USER-AUTHORED node→config bindings. The node-vs-config cross-check honors it, so a deliberately off-convention node name explicitly mapped there is not flagged as a misresolution.
- Returns:
ValidationResult with detailed validation information
- Return type:
- validate_pipeline_name(name)[source]¶
Validate that a pipeline name conforms to SageMaker constraints.
- sanitize_pipeline_name(name)[source]¶
Sanitize a pipeline name to conform to SageMaker constraints.
This function: 1. Replaces dots with hyphens 2. Replaces underscores with hyphens 3. Removes any other special characters 4. Ensures the name starts with an alphanumeric character 5. Ensures the name ends with an alphanumeric character
- generate_pipeline_name(base_name, version='1.0')[source]¶
Generate a valid pipeline name with the format: {base_name}-{random_word}-{version}-pipeline
This function ensures the generated name conforms to SageMaker constraints by sanitizing it before returning.
- exception ConfigurationError(message, missing_configs=None, available_configs=None)[source]¶
Bases:
PipelineAPIErrorRaised when configuration-related errors occur.
- exception AmbiguityError(message, node_name=None, candidates=None)[source]¶
Bases:
PipelineAPIErrorRaised when multiple configurations could match a DAG node.
- exception ValidationError(message, validation_errors=None)[source]¶
Bases:
PipelineAPIErrorRaised when DAG-config validation fails.
- exception ResolutionError(message, failed_nodes=None, suggestions=None)[source]¶
Bases:
PipelineAPIErrorRaised when DAG node resolution fails.
- merge_and_save_configs(config_list, output_file, processing_step_config_base_class=None, workspace_dirs=None)[source]¶
Merge and save multiple configs to a single JSON file.
Uses UnifiedConfigManager for streamlined processing with workspace awareness.
- Parameters:
config_list (List[Any]) – List of configuration objects to merge and save
output_file (str) – Path to the output JSON file
processing_step_config_base_class (type | None) – Optional base class to identify processing step configs
workspace_dirs (List[str] | None) – Optional list of workspace directories for step catalog integration
- Returns:
The categorized configuration structure
- Return type:
- Raises:
ValueError – If config_list is empty or contains invalid configs
IOError – If there’s an issue writing to the output file
TypeError – If configs are not serializable
- load_configs(input_file, config_classes=None, workspace_dirs=None)[source]¶
Load multiple configs from a JSON file.
Uses UnifiedConfigManager for streamlined processing with workspace awareness.
- Parameters:
input_file (str) – Path to the input JSON file
config_classes (Dict[str, Type] | None) – Optional dictionary mapping class names to class types If not provided, UnifiedConfigManager discovery will be used
workspace_dirs (List[str] | None) – Optional list of workspace directories for step catalog integration
- Returns:
- A dictionary with the following structure:
- {
“shared”: {shared_field1: value1, …}, “specific”: {
”StepName1”: {specific_field1: value1, …}, “StepName2”: {specific_field2: value2, …}, …
}
}
- Return type:
- Raises:
FileNotFoundError – If the input file doesn’t exist
json.JSONDecodeError – If the input file is not valid JSON
KeyError – If required keys are missing from the file
TypeError – If deserialization fails due to type mismatches
- serialize_config(config)[source]¶
Serialize a configuration object to a JSON-serializable dictionary.
This function serializes a configuration object, preserving its type information and special fields. It embeds metadata including the step name derived from attributes like ‘job_type’, ‘data_type’, and ‘mode’.
- deserialize_config(data, config_classes=None)[source]¶
Deserialize a dictionary back into a configuration object.
This function deserializes a dictionary into a configuration object based on type information embedded in the dictionary. If the dictionary contains the __model_type__ field, it will attempt to reconstruct the original object type using the step catalog system.
- Parameters:
- Returns:
The deserialized configuration object
- Return type:
Any
- Raises:
TypeError – If the data cannot be deserialized to the specified type
- ConfigClassStore¶
alias of
ConfigClassStoreAdapter
- register_config_class(cls)[source]¶
Register a configuration class with the ConfigClassStore.
This is a convenient alias for ConfigClassStore.register decorator.
- class PropertyReference(*, step_name, output_spec)[source]¶
Bases:
BaseModelLazy evaluation reference bridging definition-time and runtime.
- model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- to_runtime_property(step_instances)[source]¶
Create an actual SageMaker property reference using step instances.
This method navigates the property path to create a proper SageMaker Properties object that can be used at runtime.
- Parameters:
step_instances (Dict[str, Any]) – Dictionary mapping step names to step instances
- Returns:
SageMaker Properties object for the referenced property
- Raises:
ValueError – If the step is not found or property path is invalid
AttributeError – If any part of the property path is invalid
- Return type:
- to_sagemaker_property()[source]¶
Convert to SageMaker Properties dictionary format at pipeline definition time.
- output_spec: OutputDecl¶
- class SpecificationRegistry(context_name='default')[source]¶
Bases:
objectContext-aware registry for managing step specifications with isolation.
- class RegistryManager(workspace_context=None)[source]¶
Bases:
objectManager for context-scoped registries with complete isolation and workspace awareness.
This enhanced registry manager now supports: 1. Workspace-aware registry resolution 2. Integration with hybrid registry system 3. Backward compatibility with existing code 4. Thread-local workspace context management
- get_registry(context_name='default', create_if_missing=True)[source]¶
Get the registry for a specific context with workspace awareness.
This enhanced method now supports: 1. Workspace-aware context naming 2. Integration with hybrid registry system 3. Automatic registry population from hybrid sources 4. Backward compatibility with existing code
- Parameters:
- Returns:
Context-specific registry or None if not found and create_if_missing is False
- Return type:
- get_registry(manager=None, context_name='default')[source]¶
Get the registry for a specific context.
- Parameters:
manager (RegistryManager | None) – Registry manager instance
context_name (str) – Name of the context (e.g., pipeline name, environment)
- Returns:
Context-specific registry
- Return type:
- get_pipeline_registry(manager, pipeline_name)[source]¶
Get registry for a pipeline (backward compatibility).
- Parameters:
manager (RegistryManager) – Registry manager instance
pipeline_name (str) – Name of the pipeline
- Returns:
Pipeline-specific registry
- Return type:
- get_default_registry(manager)[source]¶
Get the default registry (backward compatibility).
- Parameters:
manager (RegistryManager) – Registry manager instance
- Returns:
Default registry
- Return type:
- integrate_with_pipeline_builder(pipeline_builder_cls, manager=None)[source]¶
Decorator to integrate context-scoped registries with a pipeline builder class.
This decorator modifies a pipeline builder class to use context-scoped registries.
- Parameters:
pipeline_builder_cls (Any) – Pipeline builder class to modify
manager (RegistryManager | None) – Registry manager instance (if None, a new instance will be created)
- Returns:
Modified pipeline builder class
- Return type:
- list_contexts(manager)[source]¶
Get list of all registered context names.
- Parameters:
manager (RegistryManager) – Registry manager instance
- Returns:
List of context names with registries
- Return type:
- clear_context(manager, context_name)[source]¶
Clear the registry for a specific context.
- Parameters:
manager (RegistryManager) – Registry manager instance
context_name (str) – Name of the context to clear
- Returns:
True if the registry was cleared, False if it didn’t exist
- Return type:
- class UnifiedDependencyResolver(registry, semantic_matcher)[source]¶
Bases:
objectIntelligent dependency resolver using declarative specifications.
- get_resolution_report(available_steps)[source]¶
Generate a detailed resolution report for debugging.
- resolve_step_dependencies(consumer_step, available_steps)[source]¶
Resolve dependencies for a single step.
- exception DependencyResolutionError[source]¶
Bases:
ExceptionRaised when dependencies cannot be resolved.
- create_dependency_resolver(registry=None, semantic_matcher=None)[source]¶
Create a properly configured dependency resolver.
- Parameters:
registry (SpecificationRegistry | None) – Optional specification registry. If None, creates a new one.
semantic_matcher (SemanticMatcher | None) – Optional semantic matcher. If None, creates a new one.
- Returns:
Configured UnifiedDependencyResolver instance
- Return type:
- class SemanticMatcher[source]¶
Bases:
objectSemantic similarity matching for dependency resolution.
- calculate_similarity_with_aliases(name, output_spec)[source]¶
Calculate semantic similarity between a name and an output specification, considering both logical_name and all aliases.
- create_pipeline_components(context_name=None)[source]¶
Create all necessary pipeline components with proper dependencies.
Modules