# DRF Rack # Библиотека классов расширений для Django REST Framework # # Автор: Николай В. Анохин # Все права защищены. Лицензия: MIT """ Описание класса RackConfig """ import os import sys from pathlib import Path import environ from django.core.exceptions import ImproperlyConfigured from environ import Env from environ import NoValue class RackConfig: """ Содержит базовые параметры для настройки приложения """ __base_dir: str """ Путь к корневой директории приложения """ __debug_mode: bool """ Признак режима отладки приложения """ __is_initialized: bool """ Признак инициализации конфигурации """ __env: Env """ Хранилище переменных окружения """ __env_prefix: str """ Префикс переменных окружения """ __config_files: dict[str, str | None] = {} """ Словарь файлов параметров конфигурации """ @classmethod def initialize(cls, base_dir: str, env_prefix: str = ""): """ Инициализирует конфигурацию приложения :param base_dir: Путь к корневой директории :param env_prefix: Префикс переменных окружения """ cls.__base_dir = base_dir cls.__env = environ.Env() cls.__env_prefix = env_prefix environ.Env.read_env(os.path.join(cls.__base_dir, '.env')) cls._init_configuration_files() cls.__is_initialized = True # Сразу загружаем признак режима отладки cls.__debug_mode = cls.env_bool('DEBUG', False) @classmethod def get_base_dir(cls) -> str: """ Возвращает путь к корневой директории приложения :return: Путь к корневой директории приложения """ cls._check_initialization() return cls.__base_dir @classmethod def get_debug_mode(cls) -> bool: """ Возвращает признак режима отладки приложения :return: Признак режима отладки """ cls._check_initialization() return cls.__debug_mode @classmethod def is_test_mode(cls) -> bool: """ Возвращает признак режима тестирования приложения :return: Признак режима тестирования приложения """ cls._check_initialization() return 'test' in sys.argv @classmethod def is_debug_mode(cls) -> bool: """ Возвращает признак режима отладки приложения :return: Признак режима отладки """ cls._check_initialization() return cls.__debug_mode @classmethod def env(cls) -> Env: """ Возвращает объект для работы с переменными окружения :return: Объект для работы с переменными окружения """ cls._check_initialization() return cls.__env @classmethod def env_str(cls, name: str, default_value: str | NoValue = Env.NOTSET) -> str: """ Возвращает строковое значение переменной окружения :param name: Название переменной окружения :param default_value: Значение по умолчанию :return: Значение переменной окружения """ return cls.env().str(cls.env_name(name), default_value) @classmethod def env_int(cls, name: str, default_value: int | NoValue = Env.NOTSET) -> int: """ Возвращает целочисленное значение переменной окружения :param name: Название переменной окружения :param default_value: Значение по умолчанию :return: Значение переменной окружения """ return cls.env().int(cls.env_name(name), default_value) @classmethod def env_bool(cls, name: str, default_value: bool | NoValue = Env.NOTSET) -> bool: """ Возвращает логическое значение переменной окружения :param name: Название переменной окружения :param default_value: Значение по умолчанию :return: Значение переменной окружения """ return cls.env().bool(cls.env_name(name), default_value) @classmethod def env_str_as_dir(cls, name: str, default_value: str | NoValue = Env.NOTSET) -> str: """ Возвращает значение переменной окружения в виде проверенного имени директории :param name: Название переменной окружения :param default_value: Значение по умолчанию :return: Значение переменной окружения """ dir_path = cls.env_str(name, default_value) os.makedirs(dir_path, exist_ok=True) return dir_path @classmethod def env_str_as_file(cls, name: str, default_value: str | NoValue = Env.NOTSET) -> str: """ Возвращает значение переменной окружения в виде проверенного имени фйала :param name: Название переменной окружения :param default_value: Значение по умолчанию :return: Значение переменной окружения """ file_path = cls.env_str(name, default_value) dir_path = os.path.dirname(file_path) os.makedirs(dir_path, exist_ok=True) return file_path @classmethod def env_str_as_list(cls, name: str, default_value: str | NoValue = Env.NOTSET) -> list[str]: """ Возвращает значение переменной окружения в виде списка строк :param name: Название переменной окружения :param default_value: Значение по умолчанию :return: Значение переменной окружения """ values = cls.env_str(name, default_value) if not values: return [] return [item.strip() for item in values.split(",") if item.strip()] @classmethod def env_name(cls, name: str) -> str: """ Возвращает полное имя переменной окружения :param name: Название переменной окружения :return: Имя переменной окружения """ return f"{cls.__env_prefix}{name}" @classmethod def get_config_files(cls) -> list[str]: """ Возвращает список файлов конфигурации :return: Список файлов конфигурации """ return [file for file in cls.__config_files.values() if file is not None] @classmethod def set_config_file(cls, name: str, full_path: str | None) -> None: """ Устанавливает полный путь к файлу конфигурации :param name: Название файла конфигурации :param full_path: Полный путь к файлу конфигурации """ cls.__config_files[name] = full_path @classmethod def _check_initialization(cls) -> None: """ Проверяет завершение инициализации """ if not cls.__is_initialized: raise ImproperlyConfigured("DRF Rack configuration is not initialized") @classmethod def _init_configuration_files(cls) -> None: """ Инициализирует словарь файлов параметров конфигурации """ root = f"{os.path.dirname(__file__)}/configs" for file in os.listdir(root): if file.endswith(".py") and file != "__init__.py": name = Path(file).stem cls.__config_files[name] = f"{root}/{file}"