Initial commit: AI tagging images project

This commit is contained in:
2026-01-30 18:30:05 +08:00
commit 2882852cd2
20 changed files with 3310 additions and 0 deletions

4
config/__init__.py Normal file
View File

@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from .settings import settings, Settings
__all__ = ['settings', 'Settings']

142
config/settings.py Normal file
View File

@@ -0,0 +1,142 @@
# -*- coding: utf-8 -*-
"""
配置管理模块
支持环境变量和默认值,统一管理所有配置项
"""
import os
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class DatabaseConfig:
"""数据库配置"""
host: str = "localhost"
port: int = 3306
user: str = "root"
password: str = "liang20020523" # 数据库密码
database: str = "ai_article"
charset: str = "utf8mb4"
pool_size: int = 5
@dataclass
class QwenConfig:
"""千问大模型配置"""
api_key: str = "sk-e6a38204022a4b538b8954f0584712af"
vision_model: str = "qwen-vl-max" # 视觉模型
text_model: str = "qwen-turbo" # 文本模型
max_retries: int = 3 # 最大重试次数
retry_delay: float = 1.0 # 重试间隔(秒)
timeout: int = 60 # 超时时间(秒)
@dataclass
class TagDeriveConfig:
"""标签衍生配置"""
batch_size: int = 3 # 每批处理图片数
min_derived_tags: int = 5 # 最少衍生标签数
max_derived_tags: int = 10 # 最多衍生标签数
max_tag_length: int = 10 # 单个标签最大长度
max_total_tags: Optional[int] = 8 # 合并后总标签数量上限None表示不限制
image_cdn_base: str = "http://images11.bxmkb.cn/Images/" # 图片CDN基础URL
@dataclass
class LogConfig:
"""日志配置"""
level: str = "INFO"
format: str = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
file_path: Optional[str] = None # 日志文件路径None表示只输出到控制台
@dataclass
class Settings:
"""全局配置"""
db: DatabaseConfig = field(default_factory=DatabaseConfig)
qwen: QwenConfig = field(default_factory=QwenConfig)
tag_derive: TagDeriveConfig = field(default_factory=TagDeriveConfig)
log: LogConfig = field(default_factory=LogConfig)
# API服务配置
api_host: str = "0.0.0.0"
api_port: int = 8000
debug: bool = False
@classmethod
def from_env(cls) -> 'Settings':
"""从环境变量加载配置,环境变量优先,否则使用默认值"""
settings = cls()
# 数据库配置
settings.db.host = os.getenv("DB_HOST", settings.db.host)
settings.db.port = int(os.getenv("DB_PORT", settings.db.port))
settings.db.user = os.getenv("DB_USER", settings.db.user)
settings.db.password = os.getenv("DB_PASSWORD", settings.db.password)
settings.db.database = os.getenv("DB_DATABASE", settings.db.database)
settings.db.pool_size = int(os.getenv("DB_POOL_SIZE", settings.db.pool_size))
# 千问配置
settings.qwen.api_key = os.getenv("DASHSCOPE_API_KEY", settings.qwen.api_key)
settings.qwen.vision_model = os.getenv("QWEN_VISION_MODEL", settings.qwen.vision_model)
settings.qwen.text_model = os.getenv("QWEN_TEXT_MODEL", settings.qwen.text_model)
settings.qwen.max_retries = int(os.getenv("QWEN_MAX_RETRIES", settings.qwen.max_retries))
settings.qwen.retry_delay = float(os.getenv("QWEN_RETRY_DELAY", settings.qwen.retry_delay))
# 标签衍生配置
settings.tag_derive.batch_size = int(os.getenv("BATCH_SIZE", settings.tag_derive.batch_size))
settings.tag_derive.min_derived_tags = int(os.getenv("MIN_DERIVED_TAGS", settings.tag_derive.min_derived_tags))
settings.tag_derive.max_derived_tags = int(os.getenv("MAX_DERIVED_TAGS", settings.tag_derive.max_derived_tags))
settings.tag_derive.image_cdn_base = os.getenv("IMAGE_CDN_BASE", settings.tag_derive.image_cdn_base)
max_total = os.getenv("MAX_TOTAL_TAGS")
if max_total:
settings.tag_derive.max_total_tags = int(max_total)
# 日志配置
settings.log.level = os.getenv("LOG_LEVEL", settings.log.level)
settings.log.file_path = os.getenv("LOG_FILE_PATH", settings.log.file_path)
# API配置
settings.api_host = os.getenv("API_HOST", settings.api_host)
settings.api_port = int(os.getenv("API_PORT", settings.api_port))
settings.debug = os.getenv("DEBUG", "false").lower() == "true"
return settings
# 全局配置实例
settings = Settings.from_env()
# ============== 便捷访问 ==============
def get_db_config() -> dict:
"""获取数据库配置字典"""
return {
"host": settings.db.host,
"port": settings.db.port,
"user": settings.db.user,
"password": settings.db.password,
"database": settings.db.database,
"charset": settings.db.charset,
"collation": "utf8mb4_general_ci",
"autocommit": True,
"pool_name": "ai_article_pool",
"pool_size": settings.db.pool_size
}
def get_qwen_api_key() -> str:
"""获取千问API Key"""
return settings.qwen.api_key
if __name__ == "__main__":
print("=" * 50)
print("配置信息")
print("=" * 50)
print(f"数据库: {settings.db.host}:{settings.db.port}/{settings.db.database}")
print(f"千问模型: {settings.qwen.vision_model}")
print(f"批量大小: {settings.tag_derive.batch_size}")
print(f"日志级别: {settings.log.level}")
print(f"API端口: {settings.api_port}")