Files
my-v0-server/app/datafiles/worker.py
T

51 lines
1.6 KiB
Python

"""解析子进程:python -m app.datafiles.worker <原文件> <输出目录>
stdout 每行一个 JSON:解析过程中是 {"progress": {"stage", "value"}},最后一行是结果,
成功是 {"file": ParsedFile},文件本身的问题是 {"error": {"status", "message"}}
其他异常让进程以非零状态退出,堆栈留在 stderr,由上传流程记日志
"""
import json
import sys
import time
from pathlib import Path
from app.datafiles.base import DataFileError
from app.datafiles.parse import ParseStage, parse_file
# 进度每隔这么久、或变化超过这个量才输出一行,避免逐行解析时刷屏
PROGRESS_INTERVAL = 0.1
PROGRESS_STEP = 0.01
def emit(payload: dict) -> None:
# 只输出 ASCII,不受控制台编码影响
sys.stdout.write(json.dumps(payload) + "\n")
sys.stdout.flush()
class ProgressThrottle:
def __init__(self) -> None:
self._at = 0.0
self._value = -1.0
def __call__(self, stage: ParseStage, value: float) -> None:
now = time.monotonic()
if value - self._value < PROGRESS_STEP or now - self._at < PROGRESS_INTERVAL:
return
self._at, self._value = now, value
emit({"progress": {"stage": stage, "value": value}})
def main(source: str, out_dir: str) -> None:
try:
parsed = parse_file(Path(source), Path(out_dir), ProgressThrottle())
result = {"file": parsed.model_dump(mode="json")}
except DataFileError as error:
result = {"error": {"status": error.status, "message": error.message}}
emit(result)
if __name__ == "__main__":
main(*sys.argv[1:])