Files
multi_camera/app/config.py

181 lines
5.4 KiB
Python
Raw Normal View History

"""
配置文件
支持YAML配置和.env环境变量
"""
import os
from typing import Any, Dict, List, Optional
from urllib.parse import urlparse
import yaml
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# 配置文件路径
CONFIG_FILE = os.getenv("CONFIG_FILE", "config.yaml")
def _validate_url(url: str, field_name: str) -> None:
"""验证URL格式"""
if not url:
raise ValueError(f"环境变量 {field_name} 未设置")
parsed = urlparse(url)
if not all([parsed.scheme, parsed.netloc]):
raise ValueError(f"{field_name} 格式不正确: {url}")
def _load_yaml_config() -> Optional[Dict[str, Any]]:
"""加载YAML配置文件"""
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
return yaml.safe_load(f)
return None
def _get_config_value(
yaml_config: Optional[Dict[str, Any]],
env_key: str,
yaml_path: List[str],
default: Any = None,
validator: Optional[callable] = None
) -> Any:
"""获取配置值,优先级:环境变量 > YAML配置 > 默认值"""
# 1. 优先从环境变量获取
env_value = os.getenv(env_key)
if env_value is not None:
return env_value
# 2. 其次从YAML配置获取
if yaml_config:
value = yaml_config
for key in yaml_path:
if isinstance(value, dict) and key in value:
value = value[key]
else:
value = None
break
if value is not None:
if validator:
validator(value)
return value
# 3. 使用默认值
return default
def _get_int_value(yaml_config: Optional[Dict[str, Any]], env_key: str, yaml_path: List[str], default: int) -> int:
"""获取整数配置值"""
value = _get_config_value(yaml_config, env_key, yaml_path, str(default))
try:
return int(value)
except (ValueError, TypeError):
return default
def _get_bool_value(yaml_config: Optional[Dict[str, Any]], env_key: str, yaml_path: List[str], default: bool) -> bool:
"""获取布尔配置值"""
value = _get_config_value(yaml_config, env_key, yaml_path, str(default).lower())
# 如果值已经是布尔类型,直接返回
if isinstance(value, bool):
return value
# 如果是字符串,转换为布尔值
if isinstance(value, str):
return value.lower() == "true"
# 其他类型转换为布尔值
return bool(value)
# 加载YAML配置
yaml_config = _load_yaml_config()
# 验证并获取BASE_URL
BASE_URL = os.getenv("BASE_URL")
if BASE_URL is None and yaml_config:
BASE_URL = _get_config_value(yaml_config, "BASE_URL", ["camera", "base_url"])
_validate_url(BASE_URL, "BASE_URL")
CAMERA_URL = f"{BASE_URL}/adaops/blank-layout/camera-view"
# 摄像头配置
def _load_cameras() -> List[Dict[str, Any]]:
"""加载摄像头配置"""
if yaml_config and "cameras" in yaml_config:
cameras = yaml_config["cameras"]
# 如果cameras中没有url字段自动生成
for camera in cameras:
if 'url' not in camera:
room = camera.get('room', '')
cam = camera.get('camera', 'mixed')
camera['url'] = f"{CAMERA_URL}?room={room}&camera={cam}"
return cameras
# 硬编码后备配置(不推荐使用)
return [
{
'id': 1,
'room': 'cnfzhjyg-igv-251',
'camera': 'mixed',
'name': '1号车',
'url': f"{CAMERA_URL}?room=cnfzhjyg-igv-251&camera=mixed"
},
{
'id': 2,
'room': 'cnfzhjyg-igv-2',
'camera': 'mixed',
'name': '2号车',
'url': f"{CAMERA_URL}?room=cnfzhjyg-igv-2&camera=mixed"
},
{
'id': 3,
'room': 'cnfzhjyg-igv-3',
'camera': 'mixed',
'name': '3号车',
'url': f"{CAMERA_URL}?room=cnfzhjyg-igv-3&camera=mixed"
},
{
'id': 4,
'room': 'cnfzhjyg-igv-5',
'camera': 'mixed',
'name': '5号车',
'url': f"{CAMERA_URL}?room=cnfzhjyg-igv-5&camera=mixed"
},
{
'id': 5,
'room': 'cnfzhjyg-igv-6',
'camera': 'mixed',
'name': '6号车',
'url': f"{CAMERA_URL}?room=cnfzhjyg-igv-6&camera=mixed"
},
{
'id': 6,
'room': 'cnfzhjyg-igv-7',
'camera': 'mixed',
'name': '7号车',
'url': f"{CAMERA_URL}?room=cnfzhjyg-igv-7&camera=mixed"
}
]
CAMERAS: List[Dict[str, Any]] = _load_cameras()
# Flask配置
DEBUG: bool = _get_bool_value(yaml_config, "FLASK_DEBUG", ["app", "debug"], False)
PORT: int = _get_int_value(yaml_config, "PORT", ["app", "port"], 5000)
HOST: str = _get_config_value(yaml_config, "HOST", ["app", "host"], "0.0.0.0")
# 验证HOST
if not HOST:
raise ValueError("环境变量 HOST 未设置")
# 日志配置
LOG_LEVEL: str = _get_config_value(yaml_config, "LOG_LEVEL", ["logging", "level"], "INFO")
LOG_FILE: str = _get_config_value(yaml_config, "LOG_FILE", ["logging", "file"], "logs/multi_camera.log")
LOG_MAX_BYTES: int = _get_int_value(yaml_config, "LOG_MAX_BYTES", ["logging", "max_bytes"], 10485760)
LOG_BACKUP_COUNT: int = _get_int_value(yaml_config, "LOG_BACKUP_COUNT", ["logging", "backup_count"], 10)