Skip to content

dj_settings: Project Settings the UNIX Way

build lint tests license codecov readthedocs pypi downloads build automation: yam Lint: ruff

dj_settings provides a robust, UNIX-inspired approach to managing application configuration. It reads settings from multiple locations with a clear priority order, supporting environment variables, .d directory overrides, and multiple configuration formats.

Originally designed for Django projects, it has evolved into a versatile configuration management solution suitable for any Python application.

Key Features

  • UNIX-style configuration hierarchy: Read from /etc/, ~/.config/, project directory, and environment variables
  • .d directory overrides: Override configuration files with drop-in directories (e.g., config.yml.d/*.yml)
  • Multiple format support: YAML, TOML, JSON, INI, and environment files
  • Type-safe settings classes: Create typed configuration objects with decorators
  • Environment variable integration: Seamlessly blend file-based and environment-based configuration
  • Array merging: Optionally merge arrays instead of overwriting them

Quick Start

from pathlib import Path
from dj_settings import get_setting

# Get a setting with fallback chain
database_url = get_setting(
    "DATABASE_URL",
    use_env="DATABASE_URL",
    project_dir=Path("/path/to/project"),
    filename="config.yml",
    sections=["database"],
    default="sqlite:///db.sqlite3"
)

Or use type-safe settings classes:

from pathlib import Path
from dj_settings import config_value, settings_class

@settings_class(project_dir=Path("/path/to/project"), filename="config.yml")
class Settings:
    debug: bool = config_value("DEBUG", use_env=True, default=False)
    database_url: str = config_value("DATABASE_URL", sections=["database"])
    allowed_hosts: list[str] = config_value(
        "ALLOWED_HOSTS",
        sections=["server"],
        merge_arrays=True,
        default=["localhost"]
    )

settings = Settings()
print(settings.debug)  # Type-safe access

Documentation

Why dj_settings?

Managing configuration across different environments (development, staging, production) is challenging. dj_settings solves this by:

  1. Following UNIX conventions: Uses the well-understood pattern of system-wide (/etc/), user-specific (~/.config/), and project-local configuration
  2. Supporting overrides: The .d directory pattern allows incremental configuration without modifying base files
  3. Being format-agnostic: Works with YAML, TOML, JSON, INI, and environment variables
  4. Providing type safety: Modern Python type hints and dataclasses for better IDE support and error detection