Configuration#
Pydantic-based configuration schemas. Three layers: user-facing defaults
(ParamConfig), user overrides (UserConfig), and the fully-resolved
immutable runtime config (InternalConfig).
ParamConfig: Expert defaults for Adapt pipeline.
This module defines the complete, scientifically-validated default configuration. ALL pipeline parameters must have defaults here. No runtime code should define fallback values - this is the single source of truth for defaults.
Runtime code NEVER reads from ParamConfig directly - it only receives InternalConfig.
- class adapt.configuration.schemas.param.AnalyzerConfig(*, radar_variables=<factory>, exclude_fields=<factory>, adjacency_min_touching_boundary_pixels=1)#
Bases:
AdaptBaseModelCell analysis configuration.
- Parameters:
radar_variables (list[str])
exclude_fields (list[str])
adjacency_min_touching_boundary_pixels (int)
- adjacency_min_touching_boundary_pixels: int#
- exclude_fields: list[str]#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- radar_variables: list[str]#
- class adapt.configuration.schemas.param.CoordNamesConfig(*, time='time', z='z', y='y', x='x')#
Bases:
AdaptBaseModelCoordinate name mappings.
- Parameters:
time (str)
z (str)
y (str)
x (str)
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- time: str#
- x: str#
- y: str#
- z: str#
- class adapt.configuration.schemas.param.DownloaderConfig(*, radar=None, output_dir=None, latest_files=5, latest_minutes=60, poll_interval_sec=300, max_fetch_retries=3, start_time=None, end_time=None, min_file_size=1024, max_queue_size=100, queue_resume_fraction=0.1)#
Bases:
AdaptBaseModelNEXRAD data downloader configuration.
- Parameters:
radar (str | None)
output_dir (str | None)
latest_files (int)
latest_minutes (int)
poll_interval_sec (int)
max_fetch_retries (int)
start_time (str | None)
end_time (str | None)
min_file_size (int)
max_queue_size (int)
queue_resume_fraction (float)
- end_time: str | None#
- latest_files: int#
- latest_minutes: int#
- max_fetch_retries: int#
- max_queue_size: int#
- min_file_size: int#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- output_dir: str | None#
- poll_interval_sec: int#
- queue_resume_fraction: float#
- radar: str | None#
- start_time: str | None#
- class adapt.configuration.schemas.param.FlowParamsConfig(*, pyr_scale=0.5, levels=3, winsize=10, iterations=3, poly_n=7, poly_sigma=1.5, flags=0)#
Bases:
AdaptBaseModelOpenCV optical flow parameters.
- Parameters:
pyr_scale (float)
levels (int)
winsize (int)
iterations (int)
poly_n (int)
poly_sigma (float)
flags (int)
- flags: int#
- iterations: int#
- levels: int#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- poly_n: int#
- poly_sigma: float#
- pyr_scale: float#
- winsize: int#
- class adapt.configuration.schemas.param.GlobalConfig(*, z_level=2000.0, max_scan_gap_minutes=10.0, tracking_field='reflectivity', coord_names=<factory>)#
Bases:
AdaptBaseModelGlobal pipeline settings.
- Parameters:
z_level (float)
max_scan_gap_minutes (float)
tracking_field (str)
coord_names (CoordNamesConfig)
- classmethod coerce_z_level_to_float(v)#
Allow int or float for z_level.
- coord_names: CoordNamesConfig#
- max_scan_gap_minutes: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- tracking_field: str#
- z_level: float#
- class adapt.configuration.schemas.param.LoggingConfig(*, level='INFO')#
Bases:
AdaptBaseModelLogging configuration.
- Parameters:
level (Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'])
- level: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class adapt.configuration.schemas.param.OutputConfig(*, compression='snappy')#
Bases:
AdaptBaseModelOutput file configuration.
- Parameters:
compression (Literal['snappy', 'gzip', 'lz4', 'none'])
- compression: Literal['snappy', 'gzip', 'lz4', 'none']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class adapt.configuration.schemas.param.ParamConfig(*, mode='realtime', source='aws_nexrad', source_dir=None, reader=<factory>, downloader=<factory>, regridder=<factory>, segmenter=<factory>, global_=<factory>, projector=<factory>, analyzer=<factory>, tracker=<factory>, visualization=<factory>, output=<factory>, logging=<factory>)#
Bases:
AdaptBaseModelComplete expert configuration with all defaults.
This is the single source of truth for all pipeline parameters. Every tunable parameter MUST have a default here.
Usage#
This config is NOT used directly by runtime code. It serves as the base layer in config resolution:
internal_cfg = resolve_config(param_cfg, user_cfg, cli_cfg)
Runtime code only sees InternalConfig.
- analyzer: AnalyzerConfig#
- downloader: DownloaderConfig#
- global_: GlobalConfig#
- logging: LoggingConfig#
- mode: Literal['realtime', 'historical']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- output: OutputConfig#
- projector: ProjectorConfig#
- reader: ReaderConfig#
- regridder: RegridderConfig#
- segmenter: SegmenterConfig#
- source: str#
- source_dir: str | None#
- tracker: TrackerConfig#
- visualization: VisualizationConfig#
- Parameters:
mode (Literal['realtime', 'historical'])
source (str)
source_dir (str | None)
reader (ReaderConfig)
downloader (DownloaderConfig)
regridder (RegridderConfig)
segmenter (SegmenterConfig)
global_ (GlobalConfig)
projector (ProjectorConfig)
analyzer (AnalyzerConfig)
tracker (TrackerConfig)
visualization (VisualizationConfig)
output (OutputConfig)
logging (LoggingConfig)
- class adapt.configuration.schemas.param.ProjectorConfig(*, method='adapt_default', max_projection_steps=3, nan_fill_value=0.0, flow_params=<factory>, min_motion_threshold=1.0, max_flow_magnitude=20.0, registration_step_minutes=1, projection_horizon_minutes=15)#
Bases:
AdaptBaseModelCell projection configuration.
- Parameters:
method (Literal['adapt_default'])
max_projection_steps (int)
nan_fill_value (float)
flow_params (FlowParamsConfig)
min_motion_threshold (float)
max_flow_magnitude (float)
registration_step_minutes (int)
projection_horizon_minutes (int)
- flow_params: FlowParamsConfig#
- max_flow_magnitude: float#
- max_projection_steps: int#
- method: Literal['adapt_default']#
- min_motion_threshold: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- nan_fill_value: float#
- classmethod normalize_method_name(v)#
Normalize method names to lowercase.
- projection_horizon_minutes: int#
- registration_step_minutes: int#
- class adapt.configuration.schemas.param.ReaderConfig(*, file_format='nexrad_archive', field_map=<factory>, fields=<factory>)#
Bases:
AdaptBaseModelRadar file reader configuration.
- Parameters:
file_format (Literal['nexrad_archive'])
field_map (dict[str, str])
fields (list[str])
- field_map: dict[str, str]#
- fields: list[str]#
- file_format: Literal['nexrad_archive']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class adapt.configuration.schemas.param.RegridderConfig(*, grid_shape=(41, 301, 301), grid_limits=((0.0, 20000.0), (-150000.0, 150000.0), (-150000.0, 150000.0)), roi_func='dist_beam', min_radius=1750.0, weighting_function='cressman')#
Bases:
AdaptBaseModelPyART regridding configuration.
- Parameters:
grid_shape (tuple[int, int, int])
grid_limits (tuple[tuple[float, float], tuple[float, float], tuple[float, float]])
roi_func (Literal['dist_beam', 'dist'])
min_radius (float)
weighting_function (Literal['cressman', 'barnes', 'nearest'])
- grid_limits: tuple[tuple[float, float], tuple[float, float], tuple[float, float]]#
- grid_shape: tuple[int, int, int]#
- min_radius: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- roi_func: Literal['dist_beam', 'dist']#
- weighting_function: Literal['cressman', 'barnes', 'nearest']#
- class adapt.configuration.schemas.param.SegmenterConfig(*, method='threshold', min_cellsize_gridpoint=5, max_cellsize_gridpoint=None, closing_radius=2, filter_by_size=True, h_maxima=5.0, seed_carry_frames=1, carried_exempt_size_filter=False, seed_carry_min_separation=5, threshold_params=<factory>, conv_strat_raut_params=<factory>, conv_strat_yuter_params=<factory>, feature_detection_params=<factory>, steiner_conv_strat_params=<factory>)#
Bases:
AdaptBaseModelCell segmentation configuration.
The user selects a method; the parameters for that method come from the matching nested block below (Adapt-owned defaults). The shared labeling parameters apply to every method’s convective mask.
- Parameters:
method (Literal['conv_strat_raut', 'conv_strat_yuter', 'feature_detection', 'steiner_conv_strat', 'threshold'])
min_cellsize_gridpoint (int)
max_cellsize_gridpoint (int | None)
closing_radius (int)
filter_by_size (bool)
h_maxima (float)
seed_carry_frames (int)
carried_exempt_size_filter (bool)
seed_carry_min_separation (int)
threshold_params (ThresholdParams)
conv_strat_raut_params (ConvStratRautParams)
conv_strat_yuter_params (ConvStratYuterParams)
feature_detection_params (FeatureDetectionParams)
steiner_conv_strat_params (SteinerConvStratParams)
- carried_exempt_size_filter: bool#
- closing_radius: int#
- conv_strat_raut_params: ConvStratRautParams#
- conv_strat_yuter_params: ConvStratYuterParams#
- feature_detection_params: FeatureDetectionParams#
- filter_by_size: bool#
- h_maxima: float#
- max_cellsize_gridpoint: int | None#
- method: Literal['conv_strat_raut', 'conv_strat_yuter', 'feature_detection', 'steiner_conv_strat', 'threshold']#
- min_cellsize_gridpoint: int#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- seed_carry_frames: int#
- seed_carry_min_separation: int#
- steiner_conv_strat_params: SteinerConvStratParams#
- threshold_params: ThresholdParams#
- class adapt.configuration.schemas.param.TrackerConfig(*, cell_threshold=30.0, polarity=1, growth_max_km=2.0, growth_size_km=12.0, max_overlap_mismatch=0.6, max_link_cost=1.8, residual_weight=0.25, heading_weight=1.0, max_speed_ms=40.0, max_acceleration_ms2=0.04, split_overlap_threshold=0.65, merge_overlap_threshold=0.7, latent_scans=2, identity_intensity_weight=1.0, identity_score_margin=0.33, core_field_threshold=40.0, cell_uid=<factory>)#
Bases:
AdaptBaseModelCell tracking configuration.
- Parameters:
cell_threshold (float)
polarity (Literal[1, -1])
growth_max_km (float)
growth_size_km (float)
max_overlap_mismatch (float)
max_link_cost (float)
residual_weight (float)
heading_weight (float)
max_speed_ms (float)
max_acceleration_ms2 (float)
split_overlap_threshold (float)
merge_overlap_threshold (float)
latent_scans (int)
identity_intensity_weight (float)
identity_score_margin (float)
core_field_threshold (float)
cell_uid (CellUidConfig)
- class CellUidConfig(*, width=10, alphabet='base36_upper')#
Bases:
AdaptBaseModelTrack ID generation configuration.
v2 uids hash (scan_id, cell_label) — deterministic and collision-free by construction; only the token width/alphabet remain configurable.
- Parameters:
width (Annotated[int, Ge(ge=1)])
alphabet (Literal['base36_upper'])
- alphabet: Literal['base36_upper']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- width: int#
- cell_threshold: float#
- cell_uid: CellUidConfig#
- core_field_threshold: float#
- growth_max_km: float#
- growth_size_km: float#
- heading_weight: float#
- identity_intensity_weight: float#
- identity_score_margin: float#
- latent_scans: int#
- max_acceleration_ms2: float#
- max_link_cost: float#
- max_overlap_mismatch: float#
- max_speed_ms: float#
- merge_overlap_threshold: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- polarity: Literal[1, -1]#
- residual_weight: float#
- split_overlap_threshold: float#
- class adapt.configuration.schemas.param.VisualizationConfig(*, enabled=True, dpi=200, figsize=(18.0, 8.0), output_format='png', use_basemap=True, basemap_alpha=0.6, seg_linewidth=0.8, proj_linewidth=1.0, proj_alpha=0.8, flow_scale=0.5, flow_subsample=10, min_reflectivity=10.0, refl_vmin=10.0, refl_vmax=50.0)#
Bases:
AdaptBaseModelVisualization settings.
- Parameters:
enabled (bool)
dpi (int)
figsize (tuple[float, float])
output_format (Literal['png', 'pdf', 'jpeg'])
use_basemap (bool)
basemap_alpha (float)
seg_linewidth (float)
proj_linewidth (float)
proj_alpha (float)
flow_scale (float)
flow_subsample (int)
min_reflectivity (float)
refl_vmin (float)
refl_vmax (float)
- basemap_alpha: float#
- dpi: int#
- enabled: bool#
- figsize: tuple[float, float]#
- flow_scale: float#
- flow_subsample: int#
- min_reflectivity: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- output_format: Literal['png', 'pdf', 'jpeg']#
- proj_alpha: float#
- proj_linewidth: float#
- refl_vmax: float#
- refl_vmin: float#
- seg_linewidth: float#
- use_basemap: bool#
UserConfig: Forgiving, minimal user-facing configuration.
This schema accepts user inputs in a variety of formats, with aliases for common naming patterns (e.g., RADAR_ID → radar, MODE → mode).
UserConfig is intentionally minimal - users only specify what they want to override from the expert defaults. Validation is lenient to accept both uppercase and lowercase keys, integers where floats are expected, etc.
- class adapt.configuration.schemas.user.UserAnalyzerConfig(*, radar_variables=None, exclude_fields=None, **extra_data)#
Bases:
_UserSectionUser-facing analyzer config.
- Parameters:
radar_variables (list[str] | None)
exclude_fields (list[str] | None)
extra_data (Any)
- exclude_fields: list[str] | None#
- model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- radar_variables: list[str] | None#
- class adapt.configuration.schemas.user.UserConfig(*, MODE=None, source=None, source_dir=None, RADAR_ID=None, BASE_DIR=None, LATEST_FILES=None, LATEST_MINUTES=None, POLL_INTERVAL_SEC=None, MAX_FETCH_RETRIES=None, START_TIME=None, END_TIME=None, GRID_SHAPE=None, GRID_LIMITS=None, Z_LEVEL=None, REFLECTIVITY_VAR=None, SEGMENTATION_METHOD=None, MIN_CELLSIZE_GRIDPOINT=None, MAX_CELLSIZE_GRIDPOINT=None, PROJECTION_METHOD=None, MAX_PROJECTION_STEPS=None, radar_variables=None, exclude_fields=None, extensions=<factory>, modules=None, module_params=None, downloader=None, regridder=None, segmenter=None, global_=None, projector=None, analyzer=None, **extra_data)#
Bases:
AdaptBaseModelUser-facing configuration schema.
Minimal, forgiving, and uses common aliases. Users only specify what they want to override from ParamConfig defaults.
This config is converted to internal overrides during resolution.
Usage#
- user_cfg = UserConfig(
mode=”historical”, radar=”KHTX”, base_dir=”/data/adapt”, z_level=2000, threshold=35,
)
internal = resolve_config(param_cfg, user_cfg, cli_cfg)
- analyzer: UserAnalyzerConfig | None#
- base_dir: str | None#
- classmethod coerce_numeric_fields(v)#
Accept int or float for numeric fields.
- downloader: UserDownloaderConfig | None#
- end_time: str | None#
- exclude_fields: list[str] | None#
- extensions: list[str]#
- global_: UserGlobalConfig | None#
- grid_limits: tuple[tuple[float, float], tuple[float, float], tuple[float, float]] | None#
- grid_shape: tuple[int, int, int] | None#
- infer_historical_mode_from_times()#
If times provided but mode not specified, set mode to historical.
This is a schema responsibility: if user config indicates a time range, the mode should automatically be historical.
- latest_files: int | None#
- latest_minutes: int | None#
- max_cellsize_gridpoint: int | None#
- max_fetch_retries: int | None#
- max_projection_steps: int | None#
- min_cellsize_gridpoint: int | None#
- mode: Literal['realtime', 'historical'] | None#
- model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- module_params: dict[str, dict[str, Any]] | None#
- modules: list[str] | None#
- classmethod normalize_method_names(v)#
Normalize method names to lowercase.
- poll_interval_sec: int | None#
- projection_method: str | None#
- projector: UserProjectorConfig | None#
- radar: str | None#
- radar_variables: list[str] | None#
- reflectivity_var: str | None#
- regridder: UserRegridderConfig | None#
- segmentation_method: str | None#
- segmenter: UserSegmenterConfig | None#
- source: str | None#
- source_dir: str | None#
- start_time: str | None#
- to_internal_overrides()#
Convert flat UserConfig to nested InternalConfig structure.
- Returns:
Nested dictionary matching InternalConfig structure
- Return type:
dict
- z_level: float | None#
- Parameters:
MODE (Literal['realtime', 'historical'] | None)
source (str | None)
source_dir (str | None)
RADAR_ID (str | None)
BASE_DIR (str | None)
LATEST_FILES (int | None)
LATEST_MINUTES (int | None)
POLL_INTERVAL_SEC (int | None)
MAX_FETCH_RETRIES (int | None)
START_TIME (str | None)
END_TIME (str | None)
GRID_SHAPE (tuple[int, int, int] | None)
GRID_LIMITS (tuple[tuple[float, float], tuple[float, float], tuple[float, float]] | None)
Z_LEVEL (float | None)
REFLECTIVITY_VAR (str | None)
SEGMENTATION_METHOD (str | None)
MIN_CELLSIZE_GRIDPOINT (int | None)
MAX_CELLSIZE_GRIDPOINT (int | None)
PROJECTION_METHOD (str | None)
MAX_PROJECTION_STEPS (int | None)
radar_variables (list[str] | None)
exclude_fields (list[str] | None)
extensions (list[str])
modules (list[str] | None)
module_params (dict[str, dict[str, Any]] | None)
downloader (UserDownloaderConfig | None)
regridder (UserRegridderConfig | None)
segmenter (UserSegmenterConfig | None)
global_ (UserGlobalConfig | None)
projector (UserProjectorConfig | None)
analyzer (UserAnalyzerConfig | None)
extra_data (Any)
- class adapt.configuration.schemas.user.UserDownloaderConfig(*, radar=None, output_dir=None, latest_files=None, latest_minutes=None, poll_interval_sec=None, max_fetch_retries=None, start_time=None, end_time=None, max_queue_size=None, queue_resume_fraction=None, **extra_data)#
Bases:
_UserSectionUser-facing downloader config.
- Parameters:
radar (str | None)
output_dir (str | None)
latest_files (int | None)
latest_minutes (int | None)
poll_interval_sec (int | None)
max_fetch_retries (int | None)
start_time (str | None)
end_time (str | None)
max_queue_size (int | None)
queue_resume_fraction (float | None)
extra_data (Any)
- end_time: str | None#
- latest_files: int | None#
- latest_minutes: int | None#
- max_fetch_retries: int | None#
- max_queue_size: int | None#
- model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- output_dir: str | None#
- poll_interval_sec: int | None#
- queue_resume_fraction: float | None#
- radar: str | None#
- start_time: str | None#
- class adapt.configuration.schemas.user.UserGlobalConfig(*, z_level=None, max_scan_gap_minutes=None, tracking_field=None, coord_names=None, **extra_data)#
Bases:
_UserSectionUser-facing global config.
- Parameters:
z_level (float | None)
max_scan_gap_minutes (float | None)
tracking_field (str | None)
coord_names (dict[str, str] | None)
extra_data (Any)
- classmethod coerce_z_level(v)#
Accept int or float for z_level.
- coord_names: dict[str, str] | None#
- max_scan_gap_minutes: float | None#
- model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- tracking_field: str | None#
- z_level: float | None#
- class adapt.configuration.schemas.user.UserProjectorConfig(*, method=None, max_projection_steps=None, nan_fill_value=None, flow_params=None, min_motion_threshold=None, max_flow_magnitude=None, registration_step_minutes=None, projection_horizon_minutes=None, **extra_data)#
Bases:
_UserSectionUser-facing projector config.
- Parameters:
method (str | None)
max_projection_steps (int | None)
nan_fill_value (float | None)
flow_params (dict[str, Any] | None)
min_motion_threshold (float | None)
max_flow_magnitude (float | None)
registration_step_minutes (int | None)
projection_horizon_minutes (int | None)
extra_data (Any)
- flow_params: dict[str, Any] | None#
- max_flow_magnitude: float | None#
- max_projection_steps: int | None#
- method: str | None#
- min_motion_threshold: float | None#
- model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- nan_fill_value: float | None#
- classmethod normalize_method(v)#
Normalize method names to lowercase.
- projection_horizon_minutes: int | None#
- registration_step_minutes: int | None#
- class adapt.configuration.schemas.user.UserRegridderConfig(*, grid_shape=None, grid_limits=None, roi_func=None, min_radius=None, weighting_function=None, **extra_data)#
Bases:
_UserSectionUser-facing regridder config.
- Parameters:
grid_shape (tuple[int, int, int] | None)
grid_limits (tuple[tuple[float, float], tuple[float, float], tuple[float, float]] | None)
roi_func (str | None)
min_radius (float | None)
weighting_function (str | None)
extra_data (Any)
- grid_limits: tuple[tuple[float, float], tuple[float, float], tuple[float, float]] | None#
- grid_shape: tuple[int, int, int] | None#
- min_radius: float | None#
- model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- roi_func: str | None#
- weighting_function: str | None#
- class adapt.configuration.schemas.user.UserSegmenterConfig(*, method=None, min_cellsize_gridpoint=None, max_cellsize_gridpoint=None, closing_radius=None, filter_by_size=None, h_maxima=None, seed_carry_frames=None, seed_carry_min_separation=None, carried_exempt_size_filter=None, **extra_data)#
Bases:
_UserSectionUser-facing segmentation config with aliases.
Per-method scientific parameters are not exposed here yet — the user selects only method, and its parameters resolve from ParamConfig. Advanced users may still override a nested <method>_params block, which passes through via this section’s
extra="allow".- Parameters:
method (str | None)
min_cellsize_gridpoint (int | None)
max_cellsize_gridpoint (int | None)
closing_radius (int | None)
filter_by_size (bool | None)
h_maxima (float | None)
seed_carry_frames (int | None)
seed_carry_min_separation (int | None)
carried_exempt_size_filter (bool | None)
extra_data (Any)
- carried_exempt_size_filter: bool | None#
- closing_radius: int | None#
- filter_by_size: bool | None#
- classmethod fold_legacy_closing_kernel(data)#
Accept the retired
closing_kernel: [w, h]rectangle as a disk radius.(1, 1)was a no-op and maps to 0; a w x h rectangle maps tomax(w, h) // 2so the smoothing scale is preserved.
- classmethod fold_legacy_seed_carry(data)#
Accept the retired
seed_carry/seed_carry_max_framespair.One integer replaced them: 0 is off, N carries for N frames. A legacy config maps as
seed_carry: false -> 0andseed_carry: true -> seed_carry_max_frames(default 2, its old default), so existing runs keep their behaviour.
- h_maxima: float | None#
- max_cellsize_gridpoint: int | None#
- method: str | None#
- min_cellsize_gridpoint: int | None#
- model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- classmethod normalize_method(v)#
Normalize method names to lowercase.
- seed_carry_frames: int | None#
- seed_carry_min_separation: int | None#
InternalConfig: Authoritative runtime configuration.
This is the ONLY config schema that runtime code sees. It is fully validated, normalized, and contains NO optional fields that processing code depends on.
All .get() calls, fallback defaults, and validation logic are FORBIDDEN in runtime code - everything is explicit here.
- class adapt.configuration.schemas.internal.InternalAnalyzerConfig(*, radar_variables, exclude_fields, adjacency_min_touching_boundary_pixels)#
Bases:
AdaptBaseModelRuntime analysis configuration.
- Parameters:
radar_variables (list[str])
exclude_fields (list[str])
adjacency_min_touching_boundary_pixels (Annotated[int, Ge(ge=1)])
- adjacency_min_touching_boundary_pixels: int#
- exclude_fields: list[str]#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- radar_variables: list[str]#
- class adapt.configuration.schemas.internal.InternalConfig(*, mode, base_dir, source='aws_nexrad', source_dir=None, run_id=None, output_dirs=None, reader, downloader, regridder, segmenter, global_, projector, analyzer, tracker, visualization, output, logging, processor=<factory>, extensions=<factory>, module_params=<factory>, modules=None, only_modules=None, exclude_modules=None)#
Bases:
AdaptBaseModelAuthoritative runtime configuration.
This is the ONLY configuration schema that processing code sees. It is fully validated, immutable, and contains explicit values for all parameters (no None for fields that runtime depends on).
Usage#
Runtime modules receive InternalConfig and access fields directly:
- def __init__(self, config: InternalConfig):
self.threshold = config.segmenter.threshold # NOT .get() self.z_level = config.global_.z_level
Rules#
NO .get() calls
NO fallback defaults
NO type checking
NO validation
All of that happens during config resolution, not in runtime code.
- analyzer: InternalAnalyzerConfig#
- base_dir: str#
- downloader: InternalDownloaderConfig#
- exclude_modules: list[str] | None#
- extensions: list[str]#
- global_: InternalGlobalConfig#
- logging: InternalLoggingConfig#
- mode: Literal['realtime', 'historical']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True, 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- module_params: dict[str, dict[str, Any]]#
- modules: list[str] | None#
- only_modules: list[str] | None#
- output: InternalOutputConfig#
- output_dirs: dict[str, str] | None#
- processor: InternalProcessorConfig#
- projector: InternalProjectorConfig#
- reader: InternalReaderConfig#
- regridder: InternalRegridderConfig#
- run_id: str | None#
- segmenter: InternalSegmenterConfig#
- source: str#
- source_dir: str | None#
- tracker: InternalTrackerConfig#
- visualization: InternalVisualizationConfig#
- Parameters:
mode (Literal['realtime', 'historical'])
base_dir (str)
source (str)
source_dir (str | None)
run_id (str | None)
output_dirs (dict[str, str] | None)
reader (InternalReaderConfig)
downloader (InternalDownloaderConfig)
regridder (InternalRegridderConfig)
segmenter (InternalSegmenterConfig)
global_ (InternalGlobalConfig)
projector (InternalProjectorConfig)
analyzer (InternalAnalyzerConfig)
tracker (InternalTrackerConfig)
visualization (InternalVisualizationConfig)
output (InternalOutputConfig)
logging (InternalLoggingConfig)
processor (InternalProcessorConfig)
extensions (list[str])
module_params (dict[str, dict[str, Any]])
modules (list[str] | None)
only_modules (list[str] | None)
exclude_modules (list[str] | None)
- class adapt.configuration.schemas.internal.InternalCoordNamesConfig(*, time, z, y, x)#
Bases:
AdaptBaseModelRuntime coordinate name mappings.
- Parameters:
time (str)
z (str)
y (str)
x (str)
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- time: str#
- x: str#
- y: str#
- z: str#
- class adapt.configuration.schemas.internal.InternalDownloaderConfig(*, mode, radar, output_dir, latest_files, latest_minutes, poll_interval_sec, max_fetch_retries, start_time, end_time, min_file_size, max_queue_size=100, queue_resume_fraction=0.1)#
Bases:
AdaptBaseModelRuntime downloader configuration.
- Parameters:
mode (Literal['realtime', 'historical'])
radar (str)
output_dir (str)
latest_files (int)
latest_minutes (int)
poll_interval_sec (int)
max_fetch_retries (int)
start_time (str | None)
end_time (str | None)
min_file_size (int)
max_queue_size (int)
queue_resume_fraction (float)
- end_time: str | None#
- latest_files: int#
- latest_minutes: int#
- max_fetch_retries: int#
- max_queue_size: int#
- min_file_size: int#
- mode: Literal['realtime', 'historical']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- output_dir: str#
- poll_interval_sec: int#
- queue_resume_fraction: float#
- radar: str#
- start_time: str | None#
- class adapt.configuration.schemas.internal.InternalFlowParamsConfig(*, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags)#
Bases:
AdaptBaseModelRuntime optical flow parameters.
- Parameters:
pyr_scale (float)
levels (int)
winsize (int)
iterations (int)
poly_n (int)
poly_sigma (float)
flags (int)
- flags: int#
- iterations: int#
- levels: int#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- poly_n: int#
- poly_sigma: float#
- pyr_scale: float#
- winsize: int#
- class adapt.configuration.schemas.internal.InternalGlobalConfig(*, z_level, max_scan_gap_minutes=10.0, tracking_field, coord_names)#
Bases:
AdaptBaseModelRuntime global settings.
- Parameters:
z_level (float)
max_scan_gap_minutes (Annotated[float, Gt(gt=0)])
tracking_field (str)
coord_names (InternalCoordNamesConfig)
- coord_names: InternalCoordNamesConfig#
- max_scan_gap_minutes: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- tracking_field: str#
- z_level: float#
- class adapt.configuration.schemas.internal.InternalLoggingConfig(*, level, console_level='WARNING', enabled=True, traces=True, metrics=True, json_logs=False, console_logs=True, progress_every=30.0)#
Bases:
AdaptBaseModelRuntime logging + observability configuration.
levelgoverns the full file/JSON log;console_levelkeeps the console quiet independently. The remaining toggles enable/disable the observability subsystem and its pillars; the orchestrator translates these into anObsSettingswhen it builds the provider.- Parameters:
level (Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'])
console_level (Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'])
enabled (bool)
traces (bool)
metrics (bool)
json_logs (bool)
console_logs (bool)
progress_every (Annotated[float, Gt(gt=0)])
- console_level: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']#
- console_logs: bool#
- enabled: bool#
- json_logs: bool#
- level: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']#
- metrics: bool#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- progress_every: float#
- traces: bool#
- class adapt.configuration.schemas.internal.InternalOutputConfig(*, compression)#
Bases:
AdaptBaseModelRuntime output configuration.
- Parameters:
compression (Literal['snappy', 'gzip', 'lz4', 'none'])
- compression: Literal['snappy', 'gzip', 'lz4', 'none']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class adapt.configuration.schemas.internal.InternalProcessorConfig(*, max_history=2, min_file_size=5000, db_filename_pattern='{radar}_cells_statistics.db')#
Bases:
AdaptBaseModelRuntime processor configuration.
- Parameters:
max_history (Annotated[int, Ge(ge=2), Le(le=10)])
min_file_size (Annotated[int, Ge(ge=1000)])
db_filename_pattern (str)
- db_filename_pattern: str#
- max_history: int#
- min_file_size: int#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class adapt.configuration.schemas.internal.InternalProjectorConfig(*, method, max_projection_steps, nan_fill_value, flow_params, min_motion_threshold, max_flow_magnitude, registration_step_minutes, projection_horizon_minutes)#
Bases:
AdaptBaseModelRuntime projection configuration.
- Parameters:
method (str)
max_projection_steps (Annotated[int, Ge(ge=1), Le(le=10)])
nan_fill_value (float)
flow_params (InternalFlowParamsConfig)
min_motion_threshold (float)
max_flow_magnitude (float)
registration_step_minutes (Annotated[int, Ge(ge=1)])
projection_horizon_minutes (Annotated[int, Ge(ge=1)])
- flow_params: InternalFlowParamsConfig#
- max_flow_magnitude: float#
- max_projection_steps: int#
- method: str#
- min_motion_threshold: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- nan_fill_value: float#
- projection_horizon_minutes: int#
- registration_step_minutes: int#
- class adapt.configuration.schemas.internal.InternalReaderConfig(*, file_format, field_map, fields)#
Bases:
AdaptBaseModelRuntime reader configuration.
- Parameters:
file_format (Literal['nexrad_archive'])
field_map (dict[str, str])
fields (list[str])
- field_map: dict[str, str]#
- fields: list[str]#
- file_format: Literal['nexrad_archive']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class adapt.configuration.schemas.internal.InternalRegridderConfig(*, grid_shape, grid_limits, roi_func, min_radius, weighting_function)#
Bases:
AdaptBaseModelRuntime regridding configuration.
- Parameters:
grid_shape (tuple[int, int, int])
grid_limits (tuple[tuple[float, float], tuple[float, float], tuple[float, float]])
roi_func (Literal['dist_beam', 'dist'])
min_radius (float)
weighting_function (Literal['cressman', 'barnes', 'nearest'])
- grid_limits: tuple[tuple[float, float], tuple[float, float], tuple[float, float]]#
- grid_shape: tuple[int, int, int]#
- min_radius: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- roi_func: Literal['dist_beam', 'dist']#
- weighting_function: Literal['cressman', 'barnes', 'nearest']#
- class adapt.configuration.schemas.internal.InternalSegmenterConfig(*, method, min_cellsize_gridpoint, max_cellsize_gridpoint, closing_radius, filter_by_size, h_maxima, seed_carry_frames, seed_carry_min_separation, carried_exempt_size_filter=False, threshold_params, conv_strat_raut_params, conv_strat_yuter_params, feature_detection_params, steiner_conv_strat_params)#
Bases:
AdaptBaseModelRuntime segmentation configuration.
- Parameters:
method (Literal['conv_strat_raut', 'conv_strat_yuter', 'feature_detection', 'steiner_conv_strat', 'threshold'])
min_cellsize_gridpoint (int)
max_cellsize_gridpoint (int | None)
closing_radius (int)
filter_by_size (bool)
h_maxima (float)
seed_carry_frames (int)
seed_carry_min_separation (int)
carried_exempt_size_filter (bool)
threshold_params (ThresholdParams)
conv_strat_raut_params (ConvStratRautParams)
conv_strat_yuter_params (ConvStratYuterParams)
feature_detection_params (FeatureDetectionParams)
steiner_conv_strat_params (SteinerConvStratParams)
- carried_exempt_size_filter: bool#
- closing_radius: int#
- conv_strat_raut_params: ConvStratRautParams#
- conv_strat_yuter_params: ConvStratYuterParams#
- feature_detection_params: FeatureDetectionParams#
- filter_by_size: bool#
- h_maxima: float#
- max_cellsize_gridpoint: int | None#
- method: Literal['conv_strat_raut', 'conv_strat_yuter', 'feature_detection', 'steiner_conv_strat', 'threshold']#
- min_cellsize_gridpoint: int#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- seed_carry_frames: int#
- seed_carry_min_separation: int#
- steiner_conv_strat_params: SteinerConvStratParams#
- threshold_params: ThresholdParams#
- class adapt.configuration.schemas.internal.InternalTrackerConfig(*, cell_threshold, polarity, growth_max_km, growth_size_km, max_overlap_mismatch, max_link_cost, residual_weight, heading_weight, max_speed_ms, max_acceleration_ms2, split_overlap_threshold, merge_overlap_threshold, latent_scans, identity_intensity_weight, identity_score_margin, core_field_threshold, cell_uid)#
Bases:
AdaptBaseModelRuntime tracking configuration.
- Parameters:
cell_threshold (float)
polarity (Literal[1, -1])
growth_max_km (Annotated[float, Ge(ge=0)])
growth_size_km (Annotated[float, Gt(gt=0)])
max_overlap_mismatch (Annotated[float, Gt(gt=0), Le(le=1.0)])
max_link_cost (Annotated[float, Gt(gt=0)])
residual_weight (Annotated[float, Ge(ge=0)])
heading_weight (Annotated[float, Ge(ge=0)])
max_speed_ms (Annotated[float, Gt(gt=0)])
max_acceleration_ms2 (Annotated[float, Ge(ge=0)])
split_overlap_threshold (Annotated[float, Gt(gt=0), Le(le=1.0)])
merge_overlap_threshold (Annotated[float, Gt(gt=0), Le(le=1.0)])
latent_scans (Annotated[int, Ge(ge=0)])
identity_intensity_weight (Annotated[float, Ge(ge=0)])
identity_score_margin (Annotated[float, Ge(ge=0)])
core_field_threshold (float)
cell_uid (InternalCellUidConfig)
- class InternalCellUidConfig(*, width, alphabet)#
Bases:
AdaptBaseModelRuntime cell UID configuration.
- Parameters:
width (Annotated[int, Ge(ge=1)])
alphabet (Literal['base36_upper'])
- alphabet: Literal['base36_upper']#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- width: int#
- cell_threshold: float#
- cell_uid: InternalCellUidConfig#
- core_field_threshold: float#
- growth_max_km: float#
- growth_size_km: float#
- heading_weight: float#
- identity_intensity_weight: float#
- identity_score_margin: float#
- latent_scans: int#
- max_acceleration_ms2: float#
- max_link_cost: float#
- max_overlap_mismatch: float#
- max_speed_ms: float#
- merge_overlap_threshold: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- polarity: Literal[1, -1]#
- residual_weight: float#
- split_overlap_threshold: float#
- class adapt.configuration.schemas.internal.InternalVisualizationConfig(*, enabled, dpi, figsize, output_format, use_basemap, basemap_alpha, seg_linewidth, proj_linewidth, proj_alpha, flow_scale, flow_subsample, min_reflectivity, refl_vmin, refl_vmax)#
Bases:
AdaptBaseModelRuntime visualization settings.
- Parameters:
enabled (bool)
dpi (int)
figsize (tuple[float, float])
output_format (Literal['png', 'pdf', 'jpeg'])
use_basemap (bool)
basemap_alpha (float)
seg_linewidth (float)
proj_linewidth (float)
proj_alpha (float)
flow_scale (float)
flow_subsample (int)
min_reflectivity (float)
refl_vmin (float)
refl_vmax (float)
- basemap_alpha: float#
- dpi: int#
- enabled: bool#
- figsize: tuple[float, float]#
- flow_scale: float#
- flow_subsample: int#
- min_reflectivity: float#
- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_assignment': True}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- output_format: Literal['png', 'pdf', 'jpeg']#
- proj_alpha: float#
- proj_linewidth: float#
- refl_vmax: float#
- refl_vmin: float#
- seg_linewidth: float#
- use_basemap: bool#
Configuration resolution and merging logic.
This module provides the SINGLE AUTHORITATIVE ENTRYPOINT for configuration resolution: resolve_config(). It merges ParamConfig, UserConfig, and CLIConfig in the correct precedence order and returns a validated InternalConfig.
Precedence (highest to lowest): 1. CLIConfig (command-line overrides) 2. UserConfig (user file overrides) 3. ParamConfig (expert defaults)
Merge Semantics: - Nested dictionaries: recursively merged (child keys from higher-priority
configs override lower-priority configs)
Lists: completely REPLACED (higher-priority list replaces entire lower-priority list; no concatenation)
Other values: replaced
Special Cases: - analyzer.exclude_fields: UNIONED (default excludes + user excludes) - projector.max_projection_steps: capped at 10 for safety - mode inference: auto-set to ‘historical’ if start_time/end_time provided
but no explicit mode
Example precedence: - ParamConfig: {“radar_variables”: [“A”, “B”], “threshold”: 30} - UserConfig: {“radar_variables”: [“C”], “threshold”: 40} - Result: {“radar_variables”: [“C”], “threshold”: 40} # List replaced
- adapt.configuration.schemas.resolve.deep_merge(base, *overrides)#
Deep merge multiple dictionaries.
Later dictionaries override earlier ones. Nested dictionaries are merged recursively; other values are replaced.
- Parameters:
base (
dict) – Base dictionary (lowest priority)*overrides (
dict) – Override dictionaries (higher priority, left to right)
- Returns:
Merged dictionary
- Return type:
dict
Examples
>>> base = {"a": 1, "b": {"c": 2, "d": 3}} >>> override = {"b": {"d": 4, "e": 5}, "f": 6} >>> deep_merge(base, override) {'a': 1, 'b': {'c': 2, 'd': 4, 'e': 5}, 'f': 6}
- adapt.configuration.schemas.resolve.resolve_config(param_cfg, user_cfg=None, cli_cfg=None)#
Resolve final runtime configuration from param, user, and CLI configs.
This is the SINGLE ENTRYPOINT for configuration resolution. It validates and merges configs in the correct precedence order, then returns an immutable InternalConfig for runtime use.
Precedence (highest to lowest): 1. CLIConfig (command-line overrides) 2. UserConfig (user file overrides) 3. ParamConfig (expert defaults)
- Parameters:
param_cfg (
dict|ParamConfig) – Expert configuration with complete defaults. Required.user_cfg (
dict|UserConfig|None) – User configuration with overrides. If None or empty, uses only param defaults.cli_cfg (
dict|CLIConfig|None) – Command-line overrides. If None or empty, no CLI overrides applied.
- Returns:
Fully validated, immutable runtime configuration
- Return type:
- Raises:
ConfigError – If any config fails validation — with a clear message naming the offending section/field, its value, and why.
Examples
>>> from adapt.configuration.schemas import resolve_config, ParamConfig, UserConfig >>> >>> # Load expert defaults >>> param = ParamConfig() >>> >>> # User wants higher threshold >>> user = UserConfig(threshold=35, radar="KHTX") >>> >>> # Resolve to internal config >>> config = resolve_config(param, user) >>> config.segmenter.threshold 35.0 >>> config.downloader.radar 'KHTX'
Registry-driven module config engine.
Iterates registered modules and asks each to build its own frozen config from
the resolved InternalConfig via build_config. Returns a dict keyed by the
context key each module declares (<name>_config).
This replaces the hardcoded materialize_module_configs — adding a module
never edits this file. The engine never knows which modules exist; it discovers
them from the registry.
- adapt.configuration.schemas.module_resolver.resolve_module_configs(internal_config)#
Build one frozen config per registered module.
For each registered module, calls
build_config(internal_config). Modules that return None (need no config) contribute no key.- Return type:
dict[str,Any]- Parameters:
internal_config (Any)