common.py•5.73 kB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
公共工具函數和配置
提供統一的配置、日誌設置、錯誤處理等公共功能
"""
import logging
import sys
import os
from pathlib import Path
from typing import Dict, Any, Optional
import traceback
from functools import wraps
# 默認配置
DEFAULT_CONFIG = {
'database': {
'path': 'data/drug_interactions.db',
'timeout': 30.0
},
'logging': {
'level': 'INFO',
'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
'file': 'drug_interaction_mcp.log'
},
'server': {
'name': '中西藥交互作用查詢系統',
'version': '0.1.0'
}
}
def setup_logging(log_level: str = 'INFO', log_file: str = 'drug_interaction_mcp.log') -> logging.Logger:
"""設置統一的日誌配置"""
# 創建日誌目錄
log_path = Path(log_file)
log_path.parent.mkdir(parents=True, exist_ok=True)
# 配置日誌格式
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# 設置根日誌器
root_logger = logging.getLogger()
root_logger.setLevel(getattr(logging, log_level.upper()))
# 清除現有處理器
for handler in root_logger.handlers[:]:
root_logger.removeHandler(handler)
# 添加控制台處理器
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
root_logger.addHandler(console_handler)
# 添加文件處理器
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setFormatter(formatter)
root_logger.addHandler(file_handler)
return logging.getLogger(__name__)
def handle_errors(default_return: Any = None):
"""統一的錯誤處理裝飾器"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
logger = logging.getLogger(func.__module__)
logger.error(f"函數 {func.__name__} 執行錯誤: {e}")
logger.debug(f"詳細錯誤信息: {traceback.format_exc()}")
return default_return
return wrapper
return decorator
def validate_input(**kwargs) -> Dict[str, Any]:
"""統一的輸入驗證"""
errors = []
for key, value in kwargs.items():
if value is None or (isinstance(value, str) and not value.strip()):
errors.append(f"缺少必要參數: {key}")
return {
'valid': len(errors) == 0,
'errors': errors,
'data': kwargs
}
def create_error_response(message: str, data: Any = None) -> Dict[str, Any]:
"""創建標準錯誤響應"""
return {
'success': False,
'error': message,
'data': data
}
def create_success_response(message: str, data: Any = None, **extra) -> Dict[str, Any]:
"""創建標準成功響應"""
response = {
'success': True,
'message': message,
'data': data
}
response.update(extra)
return response
def normalize_medicine_list(medicine_list: str) -> list:
"""解析並清理藥物列表"""
if not medicine_list:
return []
return [
med.strip()
for med in medicine_list.split(',')
if med.strip()
]
def get_severity_order() -> Dict[str, int]:
"""獲取嚴重程度排序"""
return {
"致命": 1,
"重度": 2,
"中度": 3,
"輕度": 4
}
def sort_by_severity(interactions: list, severity_order: Dict[str, int] = None) -> list:
"""按嚴重程度排序交互作用"""
if severity_order is None:
severity_order = get_severity_order()
return sorted(
interactions,
key=lambda x: severity_order.get(x.get('severity', ''), 5)
)
def format_interaction_result(found: bool, chinese_name: str = '', western_name: str = '',
interaction_data: Dict = None) -> Dict[str, Any]:
"""格式化交互作用查詢結果"""
if found and interaction_data:
return {
'found': True,
'chinese_medicine': {'name': chinese_name},
'western_medicine': {'name': western_name},
'interaction': interaction_data
}
else:
return {
'found': False,
'chinese_medicine': {'name': chinese_name},
'western_medicine': {'name': western_name},
'note': '請注意,這並不意味著完全安全,仍需謹慎使用'
}
def calculate_risk_level(severity_distribution: Dict[str, int]) -> str:
"""計算整體風險等級"""
if severity_distribution.get('致命', 0) > 0:
return "極高風險"
elif severity_distribution.get('重度', 0) > 0:
return "高風險"
elif severity_distribution.get('中度', 0) > 0:
return "中風險"
else:
return "低風險"
def generate_safety_recommendations(high_risk_pairs: int, total_interactions: int) -> list:
"""生成安全建議"""
recommendations = []
if high_risk_pairs > 0:
recommendations.append(f"⚠️ 發現 {high_risk_pairs} 個高風險交互作用組合,請避免同時使用")
recommendations.append("建議諮詢醫師或藥師的專業建議")
if total_interactions > 0:
recommendations.append(f"總共發現 {total_interactions} 個交互作用,需要特別注意用藥安全")
else:
recommendations.append("目前未發現已知交互作用,但仍需謹慎使用並監測身體反應")
return recommendations