Tests/config/environment.py
2026-01-19 23:32:11 +04:00

152 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import sys
from pathlib import Path
from typing import Optional, Dict, Any
from dotenv import load_dotenv, find_dotenv
import logging
logger = logging.getLogger(__name__)
class EnvironmentLoader:
"""Класс для загрузки переменных окружения из .env файлов"""
# Порядок загрузки файлов .env (от более специфичного к общему)
ENV_FILES_ORDER = [
'.env.local', # Локальные переопределения (не в git)
f'.env.{os.getenv("ENV", "development")}', # Окружение: .env.test, .env.production
'.env', # Основной файл
]
@classmethod
def load_environment(cls, env_file: Optional[str] = None):
"""
Загрузка переменных окружения.
Args:
env_file: Конкретный файл для загрузки (если None, используется порядок из ENV_FILES_ORDER)
"""
if env_file:
# Загрузка конкретного файла
env_path = Path(env_file)
if env_path.exists():
logger.info(f"Loading environment from specified file: {env_path}")
load_dotenv(dotenv_path=env_path, override=True)
else:
logger.warning(f"Specified env file not found: {env_path}")
return
# Автоматическая загрузка в определенном порядке
env_loaded = False
for env_filename in cls.ENV_FILES_ORDER:
env_path = find_dotenv(env_filename, usecwd=True)
if env_path:
logger.info(f"Loading environment from: {env_path}")
load_dotenv(dotenv_path=env_path, override=True)
env_loaded = True
if not env_loaded:
logger.warning("No .env files found, using system environment variables")
@classmethod
def get_env_variable(cls, key: str, default: Any = None, required: bool = False) -> Any:
"""
Получение переменной окружения с проверкой.
Args:
key: Ключ переменной окружения
default: Значение по умолчанию, если переменная не найдена
required: Обязательна ли переменная (вызывает исключение, если не найдена)
Returns:
Значение переменной окружения
Raises:
ValueError: Если переменная required=True и не найдена
"""
value = os.getenv(key)
if value is None:
if required:
raise ValueError(f"Required environment variable '{key}' is not set")
return default
# Автоматическое преобразование типов
if value.lower() in ('true', 'false'):
return value.lower() == 'true'
elif value.isdigit():
return int(value)
elif cls._is_float(value):
return float(value)
elif value.startswith('[') and value.endswith(']'):
# Список значений, разделенных запятыми
return [item.strip() for item in value[1:-1].split(',') if item.strip()]
return value
@staticmethod
def _is_float(value: str) -> bool:
"""Проверка, можно ли преобразовать строку в float"""
try:
float(value)
return True
except ValueError:
return False
@classmethod
def validate_environment(cls):
"""Валидация обязательных переменных окружения"""
required_vars = [
# 'API_BASE_URL',
# 'UI_BASE_URL',
]
missing_vars = []
for var in required_vars:
if not os.getenv(var):
missing_vars.append(var)
if missing_vars:
raise EnvironmentError(
f"Missing required environment variables: {', '.join(missing_vars)}\n"
f"Please set them in .env file or system environment."
)
@classmethod
def print_environment_info(cls):
"""Вывод информации о текущем окружении (для отладки)"""
env_info = {
'ENV': os.getenv('ENV', 'development'),
'API_BASE_URL': os.getenv('API_BASE_URL'),
'UI_BASE_URL': os.getenv('UI_BASE_URL'),
'DEBUG': os.getenv('DEBUG', 'False'),
'LOG_LEVEL': os.getenv('LOG_LEVEL', 'INFO'),
}
logger.info("Current environment configuration:")
for key, value in env_info.items():
logger.info(f" {key}: {value}")
@classmethod
def get_all_env_variables(cls, prefix: str = '') -> Dict[str, Any]:
"""
Получение всех переменных окружения с опциональным префиксом.
Args:
prefix: Фильтр по префиксу (например, 'API_' для всех API настроек)
Returns:
Словарь переменных окружения
"""
env_vars = {}
for key, _ in os.environ.items():
if len(prefix) == 0 and not key.startswith(prefix):
continue
env_vars[key] = cls.get_env_variable(key)
return env_vars
# Инициализация при импорте модуля
EnvironmentLoader.load_environment()