""" External API Service. Provides business logic for external system integration. """ import uuid import json import logging import random from datetime import datetime from typing import Optional, List, Dict, Any from database import get_db_connection from schemas.external import ( TaskType, ProjectInitRequest, ProjectInitResponse, ProgressResponse, AnnotatorProgress, ExternalExportFormat, ExternalExportRequest, ExternalExportResponse, TaskDataItem, TagItem ) logger = logging.getLogger(__name__) def generate_random_color() -> str: """ 生成随机颜色 Returns: str: #RRGGBB 格式的颜色字符串 """ return f"#{random.randint(0, 0xFFFFFF):06x}" # 预定义的颜色列表,用于生成更美观的颜色 PRESET_COLORS = [ "#FF5733", "#33FF57", "#3357FF", "#FF33F5", "#F5FF33", "#33FFF5", "#FF8C33", "#8C33FF", "#33FF8C", "#FF338C", "#5733FF", "#57FF33", "#FF3357", "#33F5FF", "#F533FF", "#8CFF33", "#338CFF", "#FF338C", "#33FF57", "#5733FF" ] def get_color_for_tag(index: int, specified_color: Optional[str] = None) -> str: """ 获取标签颜色 Args: index: 标签索引,用于从预设颜色中选择 specified_color: 指定的颜色,如果有则直接使用 Returns: str: #RRGGBB 格式的颜色字符串 """ if specified_color: return specified_color if index < len(PRESET_COLORS): return PRESET_COLORS[index] return generate_random_color() # 默认XML配置模板(不含标签,由管理员后续配置) DEFAULT_CONFIGS = { TaskType.TEXT_CLASSIFICATION: """ """, TaskType.IMAGE_CLASSIFICATION: """ """, TaskType.OBJECT_DETECTION: """ """, TaskType.NER: """ """, TaskType.POLYGON: """ """ } def generate_config_with_tags(task_type: TaskType, tags: Optional[List[TagItem]] = None) -> str: """ 根据任务类型和标签生成XML配置 Args: task_type: 任务类型 tags: 标签列表,可选 Returns: str: 生成的XML配置字符串 """ if not tags or len(tags) == 0: # 没有标签,返回默认配置 return DEFAULT_CONFIGS.get(task_type, DEFAULT_CONFIGS[TaskType.TEXT_CLASSIFICATION]) # 根据任务类型生成带标签的配置 if task_type == TaskType.TEXT_CLASSIFICATION: labels_xml = "\n".join([ f' ' for i, tag in enumerate(tags) ]) return f""" {labels_xml} """ elif task_type == TaskType.IMAGE_CLASSIFICATION: labels_xml = "\n".join([ f' ' for i, tag in enumerate(tags) ]) return f""" {labels_xml} """ elif task_type == TaskType.OBJECT_DETECTION: labels_xml = "\n".join([ f'