245 lines
9.5 KiB
Python
245 lines
9.5 KiB
Python
import os
|
|
from dotenv import load_dotenv
|
|
from urllib.parse import quote_plus
|
|
from typing import List, Optional
|
|
from pathlib import Path
|
|
|
|
# 加载环境变量
|
|
load_dotenv()
|
|
|
|
# 导入embedding配置
|
|
try:
|
|
from config.embedding_config import EmbeddingConfig
|
|
_embedding_config = None # 延迟加载
|
|
except ImportError:
|
|
_embedding_config = None
|
|
|
|
|
|
class Settings:
|
|
"""应用配置类"""
|
|
|
|
# 应用基础配置
|
|
APP_NAME: str = os.getenv("APP_NAME", "KUMI Service")
|
|
DEBUG: bool = os.getenv("DEBUG", "False").lower() == "true"
|
|
HOST: str = os.getenv("HOST", "0.0.0.0")
|
|
PORT: int = int(os.getenv("PORT", "8000"))
|
|
|
|
ADMIN_USER_NAME: str = os.getenv("ADMIN_USER_NAME", "admin")
|
|
ADMIN_PASSWORD: str = os.getenv("ADMIN_PASSWORD", "KUMI-admin-123456")
|
|
|
|
test_host: str = os.getenv("TEST_HOST", "127.0.0.1")
|
|
test_port: int = int(os.getenv("TEST_PORT", "8001"))
|
|
debug: bool = os.getenv("DEBUG", "False").lower() == "true"
|
|
|
|
# 资源目录配置
|
|
RESOURCE_BASE_DIR: str = os.getenv("RESOURCE_BASE_DIR", "resources")
|
|
DDL_EXPORT_DIR: str = os.getenv("DDL_EXPORT_DIR", "ddl_exports")
|
|
|
|
# 服务控制 - 控制哪些API服务启用
|
|
ENABLE_KNOWLEDGE_API: bool = os.getenv("ENABLE_KNOWLEDGE_API", "true").lower() == "true"
|
|
ENABLE_DOCUMENT_CONVERSION_API: bool = os.getenv("ENABLE_DOCUMENT_CONVERSION_API", "true").lower() == "true"
|
|
|
|
# MarkItDown配置
|
|
MARKITDOWN_ENABLE_PLUGINS: bool = os.getenv("MARKITDOWN_ENABLE_PLUGINS", "false").lower() == "true"
|
|
MARKITDOWN_MAX_FILE_SIZE: int = int(os.getenv("MARKITDOWN_MAX_FILE_SIZE", str(50 * 1024 * 1024))) # 50MB
|
|
|
|
# 知识库上传文件大小限制
|
|
KNOWLEDGE_UPLOAD_MAX_FILE_SIZE: int = int(os.getenv("KNOWLEDGE_UPLOAD_MAX_FILE_SIZE", str(100 * 1024 * 1024))) # 100MB
|
|
|
|
# 支持的文件扩展名(从环境变量读取,用逗号分隔)
|
|
_allowed_extensions = os.getenv("MARKITDOWN_ALLOWED_EXTENSIONS",
|
|
".pdf,.docx,.pptx,.xlsx,.xls,.txt,.md,.html,.csv,.wav,.mp3")
|
|
MARKITDOWN_ALLOWED_EXTENSIONS: List[str] = [ext.strip() for ext in _allowed_extensions.split(",")]
|
|
|
|
# Chroma向量数据库配置
|
|
vector_db_type: str = os.getenv('VECTOR_DB_TYPE', 'chroma')
|
|
|
|
# Milvus Configuration
|
|
milvus_host: str = os.getenv('MILVUS_HOST', 'localhost')
|
|
milvus_port: int = int(os.getenv('MILVUS_PORT', '19530'))
|
|
milvus_user: str = os.getenv('MILVUS_USER', 'root')
|
|
milvus_password: str = os.getenv('MILVUS_PASSWORD', 'Milvus')
|
|
|
|
# ChromaDB Configuration
|
|
chroma_host: str = os.getenv('CHROMA_HOST', 'localhost')
|
|
chroma_port: int = int(os.getenv('CHROMA_PORT', '8000'))
|
|
|
|
# Embedding配置文件路径
|
|
_EMBEDDING_CONFIG_PATH: str = os.getenv('EMBEDDING_CONFIG_PATH', 'config/embedding_providers.yaml')
|
|
|
|
VERIFY_TOKEN: str = os.getenv('VERIFY_TOKEN', 'NOTPOSSIBLEADMINp0ss')
|
|
|
|
# PATH
|
|
PROJECT_ROOT: str = str(Path(__file__).parent.parent.absolute())
|
|
|
|
# 如果需要自定义项目根目录,可以通过环境变量覆盖
|
|
_custom_root = os.getenv('PROJECT_ROOT')
|
|
if _custom_root:
|
|
PROJECT_ROOT = str(Path(_custom_root).absolute())
|
|
|
|
# 相对于项目根目录的路径配置
|
|
_CSV_TEST_RELATIVE_PATH: str = os.getenv('CSV_TEST_RELATIVE_PATH', 'dataset/dataset_csv_test')
|
|
_YAML_EVALUATE_RELATIVE_PATH: str = os.getenv('YAML_EVALUATE_RELATIVE_PATH', 'dataset/yaml_eval')
|
|
_YAML_EVALUATE_TEMPLATES_RELATIVE_PATH: str = os.getenv('YAML_EVALUATE_TEMPLATES_RELATIVE_PATH',
|
|
'dataset/yaml_eval_templates')
|
|
|
|
_WORKFLOWS_CONFIG_RELATIVE_PATH: str = os.getenv('WORKFLOWS_CONFIG_RELATIVE_PATH', 'dataset/workflows.json')
|
|
_TABLE_FOLDER_RELATIVE_PATH: str = os.getenv('TABLE_FOLDER_RELATIVE_PATH', 'dataset/dataset_csv_test')
|
|
_TEMP_RESULTS_RELATIVE_PATH: str = os.getenv('TEMP_RESULTS_RELATIVE_PATH', 'output/temp_results')
|
|
_EVALUATION_RESULTS_RELATIVE_PATH: str = os.getenv('EVALUATION_RESULTS_RELATIVE_PATH', 'output/evaluation_results')
|
|
_YAML_RULES_RELATIVE_PATH: str = os.getenv('YAML_RULES_RELATIVE_PATH', 'dataset/yaml_eval')
|
|
|
|
# LLM配置
|
|
OPENAI_API_KEY: Optional[str] = os.getenv("OPENAI_API_KEY")
|
|
OPENAI_BASE_URL: Optional[str] = os.getenv("OPENAI_BASE_URL")
|
|
CLAUDE_API_KEY: Optional[str] = os.getenv("CLAUDE_API_KEY")
|
|
DEFAULT_LLM_PROVIDER: str = os.getenv("DEFAULT_LLM_PROVIDER", "openai")
|
|
DEFAULT_MODEL: str = os.getenv("DEFAULT_MODEL", "gpt-4.1-mini")
|
|
DEFAULT_TEMPERATURE: float = float(os.getenv("DEFAULT_TEMPERATURE", "0.4"))
|
|
DEFAULT_MAX_TOKENS: int = int(os.getenv("DEFAULT_MAX_TOKENS", "1000"))
|
|
|
|
API_API_KEY: Optional[str] = os.getenv("API_API_KEY")
|
|
|
|
# KUMI API URL(用于 UMAP 可视化服务调用主服务)
|
|
KUMI_API_URL: str = os.getenv("KUMI_API_URL", "http://localhost:8000")
|
|
|
|
# UMAP 缓存目录(Embedding Atlas 兼容格式)
|
|
_UMAP_CACHE_DIR: Optional[str] = os.getenv("UMAP_CACHE_DIR")
|
|
|
|
# 日志配置
|
|
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
|
|
LOG_FILE: Optional[str] = os.getenv("LOG_FILE")
|
|
|
|
# 生成绝对路径
|
|
@property
|
|
def CSV_TEST_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._CSV_TEST_RELATIVE_PATH)
|
|
|
|
@property
|
|
def YAML_EVALUATE_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._YAML_EVALUATE_RELATIVE_PATH)
|
|
|
|
@property
|
|
def YAML_EVALUATE_TEMPLATES_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._YAML_EVALUATE_TEMPLATES_RELATIVE_PATH)
|
|
|
|
@property
|
|
def WORKFLOWS_CONFIG_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._WORKFLOWS_CONFIG_RELATIVE_PATH)
|
|
|
|
@property
|
|
def TABLE_FOLDER_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._TABLE_FOLDER_RELATIVE_PATH)
|
|
|
|
@property
|
|
def TEMP_RESULTS_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._TEMP_RESULTS_RELATIVE_PATH)
|
|
|
|
@property
|
|
def EVALUATION_RESULTS_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._EVALUATION_RESULTS_RELATIVE_PATH)
|
|
|
|
@property
|
|
def YAML_RULES_PATH(self) -> str:
|
|
return str(Path(self.PROJECT_ROOT) / self._YAML_RULES_RELATIVE_PATH)
|
|
|
|
def get_absolute_path(self, relative_path: str) -> str:
|
|
"""
|
|
根据相对路径获取绝对路径
|
|
|
|
Args:
|
|
relative_path: 相对于项目根目录的路径
|
|
|
|
Returns:
|
|
str: 绝对路径
|
|
"""
|
|
return str(Path(self.PROJECT_ROOT) / relative_path)
|
|
|
|
def create_directories(self):
|
|
"""创建所有配置的目录"""
|
|
directories = [
|
|
self.CSV_TEST_PATH,
|
|
self.YAML_EVALUATE_PATH,
|
|
self.YAML_EVALUATE_TEMPLATES_PATH,
|
|
self.TABLE_FOLDER_PATH,
|
|
self.TEMP_RESULTS_PATH,
|
|
self.EVALUATION_RESULTS_PATH,
|
|
self.YAML_RULES_PATH,
|
|
# 配置文件的目录
|
|
str(Path(self.WORKFLOWS_CONFIG_PATH).parent)
|
|
]
|
|
|
|
for directory in directories:
|
|
Path(directory).mkdir(parents=True, exist_ok=True)
|
|
|
|
def print_config(self):
|
|
"""打印当前配置信息"""
|
|
print("⚙️ 当前路径配置:")
|
|
print(f" 项目根目录: {self.PROJECT_ROOT}")
|
|
print(f" 工作流配置: {self.WORKFLOWS_CONFIG_PATH}")
|
|
print(f" 表格文件夹: {self.TABLE_FOLDER_PATH}")
|
|
print(f" 临时结果: {self.TEMP_RESULTS_PATH}")
|
|
print(f" 评测结果: {self.EVALUATION_RESULTS_PATH}")
|
|
print(f" YAML规则: {self.YAML_RULES_PATH}")
|
|
|
|
|
|
@property
|
|
def chroma_url(self) -> str:
|
|
"""构建Chroma连接URL"""
|
|
return f"http://{self.CHROMA_HOST}:{self.CHROMA_PORT}"
|
|
|
|
@property
|
|
def resource_dir(self) -> str:
|
|
"""获取资源目录完整路径"""
|
|
return os.path.abspath(self.RESOURCE_BASE_DIR)
|
|
|
|
@property
|
|
def ddl_export_path(self) -> str:
|
|
"""获取DDL导出目录完整路径"""
|
|
return os.path.join(self.resource_dir, self.DDL_EXPORT_DIR)
|
|
|
|
@property
|
|
def EMBEDDING_CONFIG_PATH(self) -> str:
|
|
"""获取embedding配置文件完整路径"""
|
|
return str(Path(self.PROJECT_ROOT) / self._EMBEDDING_CONFIG_PATH)
|
|
|
|
@property
|
|
def UMAP_CACHE_DIR(self) -> str:
|
|
"""
|
|
获取 UMAP 缓存目录(Embedding Atlas 兼容格式)
|
|
|
|
默认值按平台:
|
|
- Windows: %LOCALAPPDATA%\\embedding_atlas\\projections\\
|
|
- Linux: ~/.cache/embedding_atlas/projections/
|
|
- macOS: ~/Library/Caches/embedding_atlas/projections/
|
|
"""
|
|
if self._UMAP_CACHE_DIR:
|
|
return self._UMAP_CACHE_DIR
|
|
|
|
import sys
|
|
if sys.platform == 'win32':
|
|
local_app_data = os.environ.get('LOCALAPPDATA', '')
|
|
if local_app_data:
|
|
return str(Path(local_app_data) / 'embedding_atlas' / 'projections')
|
|
return str(Path.home() / 'AppData' / 'Local' / 'embedding_atlas' / 'projections')
|
|
elif sys.platform == 'darwin':
|
|
return str(Path.home() / 'Library' / 'Caches' / 'embedding_atlas' / 'projections')
|
|
else:
|
|
return str(Path.home() / '.cache' / 'embedding_atlas' / 'projections')
|
|
|
|
def get_embedding_config(self) -> 'EmbeddingConfig':
|
|
"""
|
|
获取embedding配置实例(单例模式)
|
|
|
|
Returns:
|
|
EmbeddingConfig实例
|
|
"""
|
|
global _embedding_config
|
|
if _embedding_config is None:
|
|
from config.embedding_config import EmbeddingConfig
|
|
_embedding_config = EmbeddingConfig(self.EMBEDDING_CONFIG_PATH)
|
|
return _embedding_config
|
|
|
|
|
|
# 创建全局配置实例
|
|
settings = Settings() |