Skip to content

Support nested path specification in yaml_config_section #772

@hugo-romero-mm

Description

@hugo-romero-mm

Summary

Currently, yaml_config_section only supports loading a single top-level key from YAML files. This limitation prevents loading settings from deeply nested configuration structures, which is a common pattern in complex applications. I propose extending yaml_config_section to support dot-notation paths (e.g., config.app.settings) to access nested sections at any depth.

Motivation

Many real-world YAML configuration files organize settings hierarchically under multiple nested keys. For example:

config:
  app:
    settings:
      database_url: "postgresql://..."
      api_key: "secret"
  logging:
    level: "INFO"

With the current implementation, there's no clean way to load settings directly without either:

  1. Restructuring the YAML file (not always feasible with shared/external configs)
  2. Creating nested Pydantic models and loading the parent section
  3. Writing custom source implementations with manual traversal

These workarounds add unnecessary complexity for a common use case.

Proposed Solution

Extend yaml_config_section to accept dot-separated paths:

from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        yaml_file='config.yaml',
        yaml_config_section='config.app.settings'  # New: nested path support
    )
    
    database_url: str
    api_key: str

This would behave similarly to how other configuration libraries handle nested paths, making pydantic-settings more flexible for complex configuration scenarios.

Implementation Notes

The change would primarily affect pydantic_settings/sources/providers/yaml.py, modifying the section extraction logic to:

  1. Split the path on dots
  2. Traverse nested dictionaries sequentially
  3. Raise a clear KeyError if any part of the path is missing

Backward Compatibility

This is fully backward compatible, existing single-key usage would work unchanged. The implementation would only split on dots when present.

Additional Context


I am willing to implement this feature myself and submit a PR with comprehensive tests following the existing patterns in tests/test_source_yaml.py if you give the green light on this approach.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions