refactor: 优化配置管理和异常处理
- 添加YAML配置文件支持 - 改进camera_manager异常处理 - 添加类型提示和URL验证 - 完善依赖注入支持测试 - 新增健康检查API端点
This commit is contained in:
@@ -2,18 +2,51 @@
|
||||
摄像头管理器
|
||||
处理摄像头配置和URL生成
|
||||
"""
|
||||
import requests
|
||||
import logging
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import requests
|
||||
from requests.adapters import HTTPAdapter
|
||||
from urllib3.util.retry import Retry
|
||||
|
||||
from .config import BASE_URL, CAMERA_URL, CAMERAS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CameraManager:
|
||||
def __init__(self):
|
||||
self.base_url = BASE_URL
|
||||
self.camera_url = CAMERA_URL
|
||||
self.session = requests.Session()
|
||||
self.cameras = CAMERAS
|
||||
"""摄像头管理器"""
|
||||
|
||||
def __init__(self, cameras: Optional[List[Dict[str, Any]]] = None) -> None:
|
||||
"""
|
||||
初始化摄像头管理器
|
||||
|
||||
Args:
|
||||
cameras: 摄像头配置列表,如果为None则使用全局配置
|
||||
"""
|
||||
self.base_url: str = BASE_URL
|
||||
self.camera_url: str = CAMERA_URL
|
||||
self.cameras: List[Dict[str, Any]] = cameras if cameras is not None else CAMERAS.copy()
|
||||
|
||||
# 初始化请求会话,配置连接池和重试策略
|
||||
self.session: requests.Session = requests.Session()
|
||||
|
||||
# 配置重试策略
|
||||
retry_strategy = Retry(
|
||||
total=3,
|
||||
backoff_factor=1,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
allowed_methods=["HEAD", "GET", "OPTIONS"]
|
||||
)
|
||||
|
||||
# 配置适配器
|
||||
adapter = HTTPAdapter(
|
||||
max_retries=retry_strategy,
|
||||
pool_connections=10,
|
||||
pool_maxsize=10
|
||||
)
|
||||
self.session.mount("http://", adapter)
|
||||
self.session.mount("https://", adapter)
|
||||
|
||||
# 配置请求头
|
||||
self.session.headers.update({
|
||||
@@ -24,8 +57,20 @@ class CameraManager:
|
||||
'Connection': 'keep-alive',
|
||||
})
|
||||
|
||||
def get_camera_url(self, camera_id, camera_number='mixed'):
|
||||
"""根据摄像头ID和编号生成URL"""
|
||||
def get_camera_url(self, camera_id: int, camera_number: str = 'mixed') -> str:
|
||||
"""
|
||||
根据摄像头ID和编号生成URL
|
||||
|
||||
Args:
|
||||
camera_id: 摄像头ID
|
||||
camera_number: 摄像头编号,默认为'mixed'
|
||||
|
||||
Returns:
|
||||
摄像头URL
|
||||
|
||||
Raises:
|
||||
ValueError: 摄像头ID不存在
|
||||
"""
|
||||
camera = next((c for c in self.cameras if c['id'] == camera_id), None)
|
||||
if not camera:
|
||||
raise ValueError(f"摄像头ID {camera_id} 不存在")
|
||||
@@ -36,19 +81,73 @@ class CameraManager:
|
||||
else:
|
||||
return f"{self.camera_url}?room={room}&camera=camera-{camera_number}"
|
||||
|
||||
def refresh_camera(self, camera_id):
|
||||
"""刷新指定摄像头(模拟操作)"""
|
||||
def refresh_camera(self, camera_id: int) -> bool:
|
||||
"""
|
||||
刷新指定摄像头(模拟操作)
|
||||
|
||||
Args:
|
||||
camera_id: 摄像头ID
|
||||
|
||||
Returns:
|
||||
是否成功
|
||||
"""
|
||||
logger.info(f"刷新摄像头 {camera_id}")
|
||||
return True
|
||||
|
||||
def get_all_cameras(self):
|
||||
"""返回所有摄像头配置"""
|
||||
def get_all_cameras(self) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
返回所有摄像头配置
|
||||
|
||||
Returns:
|
||||
摄像头配置列表
|
||||
"""
|
||||
return self.cameras
|
||||
|
||||
def check_connection(self):
|
||||
"""检查连接状态"""
|
||||
def check_connection(self, timeout: int = 5) -> bool:
|
||||
"""
|
||||
检查连接状态
|
||||
|
||||
Args:
|
||||
timeout: 超时时间(秒)
|
||||
|
||||
Returns:
|
||||
连接是否正常
|
||||
"""
|
||||
try:
|
||||
response = self.session.get(self.base_url, timeout=5)
|
||||
response = self.session.get(
|
||||
self.base_url,
|
||||
timeout=timeout,
|
||||
allow_redirects=True
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.status_code == 200
|
||||
except:
|
||||
return False
|
||||
except requests.exceptions.Timeout as e:
|
||||
logger.warning(f"连接超时: {e}")
|
||||
return False
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
logger.warning(f"连接错误: {e}")
|
||||
return False
|
||||
except requests.exceptions.HTTPError as e:
|
||||
logger.warning(f"HTTP错误: {e}")
|
||||
return False
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"请求异常: {e}")
|
||||
return False
|
||||
|
||||
def get_camera_by_id(self, camera_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
根据ID获取摄像头配置
|
||||
|
||||
Args:
|
||||
camera_id: 摄像头ID
|
||||
|
||||
Returns:
|
||||
摄像头配置,如果不存在返回None
|
||||
"""
|
||||
return next((c for c in self.cameras if c['id'] == camera_id), None)
|
||||
|
||||
def close(self) -> None:
|
||||
"""
|
||||
关闭会话
|
||||
"""
|
||||
self.session.close()
|
||||
|
||||
Reference in New Issue
Block a user