cursus.api.factory¶
DAG Configuration Factory API
This module provides interactive pipeline configuration generation through a step-by-step workflow. The system leverages existing Pydantic field definitions and the three-tier configuration system to create user-friendly configuration interfaces for pipeline development.
Key Components: - DAGConfigFactory: Main interactive factory for step-by-step configuration generation - ConfigClassMapper: Maps DAG nodes to configuration classes using registry system - ConfigurationGenerator: Generates final configuration instances with base config inheritance - Field requirement extraction utilities for Pydantic classes
- Usage:
from cursus.api.factory import DAGConfigFactory
# Create factory from DAG factory = DAGConfigFactory(dag)
# Get base configuration requirements base_requirements = factory.get_base_config_requirements()
# Set base configuration factory.set_base_config(**base_values)
# Configure steps interactively for step_name in factory.get_pending_steps():
step_requirements = factory.get_step_requirements(step_name) factory.set_step_config(step_name, **step_values)
# Generate final configurations configs = factory.generate_all_configs()
- class DAGConfigFactory(dag, project_root=None, anchor_file=None)[source]¶
Bases:
objectInteractive factory for step-by-step pipeline configuration generation.
This class provides a user-friendly interface for creating pipeline configurations by guiding users through the process of setting base configurations and step-specific configurations in a structured workflow.
Workflow: 1. Analyze DAG to get config class mapping 2. Collect base configurations first 3. Guide user through step-specific configurations 4. Generate final config instances with inheritance
- auto_configure_step_if_possible(step_name)[source]¶
Auto-configure a step if it only has tier 2+ (optional) fields besides inherited fields.
This method checks if a step can be configured with just the inherited base config fields, without requiring any tier 1 (essential) step-specific fields.
- can_auto_configure_step(step_name)[source]¶
Check if a step can be auto-configured (only has tier 2+ fields besides inherited).
- configure_step_if_present(step_name, **kwargs)[source]¶
Configure a step, but WARN (not raise) if it is not a DAG node — a non-silent replacement for the ubiquitous
if "X" in pending_steps: set_step_config("X", ...)notebook guard.The bare guard silently skips a mistyped/renamed step name because
pending_stepsis derived from the DAG nodes — hiding real typos (the campaign found leftover template cells in ~7 projects this way). This wrapper resolves the name (bare→suffixed included) and, when it matches no DAG node, logs a WARNING and returnsNoneinstead of quietly doing nothing.
- generate_all_configs()[source]¶
Generate final list of config instances.
Automatically configures steps that only have tier 2+ fields, then validates that all essential steps are configured before generating final instances.
- get_base_config_requirements()[source]¶
Get base configuration requirements directly from Pydantic class definition.
Extracts field requirements directly from BasePipelineConfig Pydantic class definition.
- Returns:
- {
‘name’: str, # Field name ‘type’: str, # Field type as string ‘description’: str, # Field description from Pydantic Field() ‘required’: bool, # True for required fields, False for optional ‘default’: Any # Default value (only for optional fields)
}
- Return type:
List of field requirement dictionaries with format
- get_base_processing_config_requirements()[source]¶
Get base processing configuration requirements.
Returns only the non-inherited fields specific to BaseProcessingStepConfig. Inherited fields from BasePipelineConfig can be obtained by calling get_base_config_requirements().
Uses cached field requirements computed during initialization for instant response.
- get_pending_steps()[source]¶
Get list of steps that still need configuration.
Steps with only tier 2+ (optional) fields besides inherited fields are considered auto-configurable and not pending.
- get_step_requirements(step_name)[source]¶
Get step-specific requirements excluding inherited base config fields.
Uses cached field requirements computed during initialization for instant response. This avoids the expensive field extraction process (~200+ operations) on every call.
- is_dag_step(step_name, job_type=None)[source]¶
Return True if
step_name(bare or suffixed, optionally + job_type) is a DAG node.Lets callers replace the silent
if "X" in pending_steps:guard with an explicit, resolution-aware check that honours the same bare→suffixed logic as set_step_config.
- load_partial_state(file_path)[source]¶
Load previously saved factory state.
- Parameters:
file_path (str) – Path to the saved state file
- save_partial_state(file_path)[source]¶
Save current factory state for later restoration.
- Parameters:
file_path (str) – Path to save the state file
- set_base_config(**kwargs)[source]¶
Set base pipeline configuration from user inputs.
- Parameters:
**kwargs – Base configuration field values
- set_base_processing_config(**kwargs)[source]¶
Set base processing configuration from user inputs.
- Parameters:
**kwargs – Base processing configuration field values
- set_step_config(step_name, **kwargs)[source]¶
Set configuration for a specific step with immediate validation.
Creates and validates the config instance immediately using the proper from_base_config pattern, providing early feedback to users.
- Parameters:
step_name (str) – Name of the step to configure
**kwargs – Step-specific configuration field values
- Returns:
The created and validated config instance
- Raises:
ValueError – If configuration is invalid or prerequisites not met
- Return type:
- update_step_config(step_name, **kwargs)[source]¶
Update existing step configuration with new values.
- Parameters:
step_name (str) – Name of the step to update
**kwargs – New configuration values to merge
- Returns:
Updated and validated config instance
- Raises:
ValueError – If step not configured yet or update fails
- Return type:
- validate_dag_config_alignment(raise_on_error=True)[source]¶
Assert the DAG↔config invariant: every DAG node resolves to a config whose derived save-key equals the node name, and every configured instance keys back to a DAG node.
This catches the class of latent drift the multi-pipeline validation campaign found — a DAG node whose step TYPE has no matching config (e.g. DAG
BedrockBatchProcessing_trainingvs config classBedrockProcessing), which otherwise only surfaces at pipeline-compile time as an opaque “no config for node”. We check it at generate/save time instead.The saved config key is
{registry_step_name}[_{job_type}](see config_derive_step_name); it MUST equal the DAG node key the factory stored the instance under. A mismatch means the configured config class is the wrong step TYPE for that node.
- class ConfigClassMapper[source]¶
Bases:
objectMaps DAG nodes to configuration classes using existing registry system.
This class provides the bridge between DAG structure and configuration classes, enabling automatic discovery of which configuration class should be used for each step in a pipeline DAG.
- map_dag_to_config_classes(dag)[source]¶
Map DAG node names to configuration classes (not instances).
- register_manual_mapping(node_name, config_class)[source]¶
Manually register a mapping between node name and configuration class.
This is useful for cases where automatic resolution fails or for custom configuration classes not in the registry.
- resolve_node_to_config_class(node_name)[source]¶
Resolve a single DAG node to its configuration class.
- class ConfigurationGenerator(base_config, base_processing_config=None)[source]¶
Bases:
objectGenerates final configuration instances with base config inheritance.
This class handles the complex task of combining base pipeline configurations with step-specific configurations, ensuring proper inheritance and validation.
- generate_all_instances(config_class_map, step_configs)[source]¶
Generate all configuration instances with proper inheritance.
- generate_config_instance(config_class, step_inputs)[source]¶
Generate config instance using base config inheritance.
- exception ConfigurationIncompleteError[source]¶
Bases:
ExceptionException raised when essential configuration fields are missing.
- extract_field_requirements(config_class)[source]¶
Extract field requirements directly from Pydantic V2 class definition.
- Parameters:
config_class (Type[BaseModel]) – Pydantic V2 model class to extract fields from
- Returns:
- {
‘name’: str, # Field name ‘type’: str, # Field type as string ‘description’: str, # Field description from Pydantic Field() ‘required’: bool, # True for required fields, False for optional ‘default’: Any # Default value (only for optional fields)
}
- Return type:
List of field requirement dictionaries with format
- categorize_field_requirements(requirements)[source]¶
Categorize field requirements into required and optional groups.
Modules
Configuration Class Mapper |
|
Configuration Generator |
|
DAG Configuration Factory |
|
Field Requirement Extraction Utilities |