huoyan-enterprise/backend/services/file_progress.py

84 lines
2.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
文件/长任务处理进度:阶段常量与上报助手。
进度约定:
- 030HTTP 上传(主要由前端 onUploadProgress 展示;入库后后端从 30 起)
- 3090解析 / OCR / 分块 / 向量化
- 90100摘要与收尾
"""
from __future__ import annotations
from typing import Awaitable, Callable, Optional, Type
import asyncpg
# ---------- 阶段 ----------
STAGE_UPLOADING = "uploading"
STAGE_PROCESSING = "processing"
STAGE_DOWNLOADING = "downloading"
STAGE_PARSING = "parsing"
STAGE_OCR = "ocr"
STAGE_SPLITTING = "splitting"
STAGE_EMBEDDING = "embedding"
STAGE_SUMMARIZING = "summarizing"
STAGE_EXTRACTING = "extracting"
STAGE_INDEXING = "indexing"
STAGE_COMPLETED = "completed"
STAGE_FAILED = "failed"
ProgressCallback = Callable[[int, str], Awaitable[None]]
STAGE_LABELS: dict[str, str] = {
STAGE_UPLOADING: "上传中",
STAGE_PROCESSING: "处理中",
STAGE_DOWNLOADING: "下载文件",
STAGE_PARSING: "解析文档",
STAGE_OCR: "文字识别",
STAGE_SPLITTING: "文本分块",
STAGE_EMBEDDING: "向量化",
STAGE_SUMMARIZING: "生成摘要",
STAGE_EXTRACTING: "抽取实体关系",
STAGE_INDEXING: "建立索引",
STAGE_COMPLETED: "已完成",
STAGE_FAILED: "失败",
}
async def _noop_progress(_percent: int, _stage: str) -> None:
pass
class FileProgressReporter:
"""节流上报,避免同一进度重复写库。"""
def __init__(self, callback: Optional[ProgressCallback] = None):
self._callback = callback or _noop_progress
self._last_percent = -1
async def report(self, percent: int, stage: str) -> None:
percent = max(0, min(100, int(percent)))
if percent <= self._last_percent:
return
self._last_percent = percent
await self._callback(percent, stage)
def make_db_progress_callback(
pool,
file_id: int,
service_cls: Type,
) -> ProgressCallback:
"""为知识库/聊天文件创建写库进度回调。"""
async def _callback(percent: int, stage: str) -> None:
async with pool.acquire() as conn:
await service_cls.update_file_progress(conn, file_id, percent, stage)
return _callback
def stage_label(stage: Optional[str]) -> str:
if not stage:
return "处理中"
return STAGE_LABELS.get(stage, stage)