Source code for app_utils.app_settings

"""Django settings related utilities."""

import logging
from typing import Any, Optional

from django.conf import settings

logger = logging.getLogger(__name__)


[docs] def clean_setting( name: str, default_value: Any, min_value: Optional[int] = None, max_value: Optional[int] = None, required_type: Optional[type] = None, choices: Optional[list] = None, ) -> Any: """Clean a setting from Django settings. Will use default_value if setting is not defined. Will use minimum or maximum value if respective boundary is exceeded. Args: default_value: value to use if setting is not defined min_value: minimum allowed value (0 assumed for int) max_value: maximum value value required_type: Mandatory if `default_value` is `None`, otherwise derived from default_value Returns: cleaned value for setting This function is designed to be used in a dedicated module like ``app_settings.py`` as layer between the actual settings and all other modules. ``app_settings.py`` will import and clean all settings and all other modules are supposed to import the settings it. Example for app_settings: .. code-block:: python from app_utils.app_settings import clean_setting EXAMPLE_SETTING = clean_setting("EXAMPLE_SETTING", 10) """ if default_value is None and not required_type: raise ValueError("You must specify a required_type for None defaults") if not required_type: required_type_2 = type(default_value) else: required_type_2 = required_type if not isinstance(required_type_2, type): raise TypeError("required_type must be a type when defined") if min_value is None and issubclass(required_type_2, int): min_value = 0 if issubclass(required_type_2, int) and default_value is not None: if min_value is not None and default_value < min_value: raise ValueError("default_value can not be below min_value") if max_value is not None and default_value > max_value: raise ValueError("default_value can not be above max_value") if not hasattr(settings, name): cleaned_value = default_value else: dirty_value = getattr(settings, name) if dirty_value is None or ( isinstance(dirty_value, required_type_2) and (min_value is None or dirty_value >= min_value) and (max_value is None or dirty_value <= max_value) and (choices is None or dirty_value in choices) ): cleaned_value = dirty_value elif ( isinstance(dirty_value, required_type_2) and min_value is not None and dirty_value < min_value ): logger.warning( "You setting for %s it not valid. Please correct it. " "Using minimum value for now: %s", name, min_value, ) cleaned_value = min_value elif ( isinstance(dirty_value, required_type_2) and max_value is not None and dirty_value > max_value ): logger.warning( "You setting for %s it not valid. Please correct it. " "Using maximum value for now: %s", name, max_value, ) cleaned_value = max_value else: logger.warning( "You setting for %s it not valid. Please correct it. " "Using default for now: %s", name, default_value, ) cleaned_value = default_value return cleaned_value