diff --git a/backend/app/modules/data_process/__init__.py b/backend/app/modules/data_process/__init__.py index 3da002b..0bfd2c1 100644 --- a/backend/app/modules/data_process/__init__.py +++ b/backend/app/modules/data_process/__init__.py @@ -1 +1,16 @@ -"""Data processing module.""" +"""数据处理模块。 + +本模块已重构为多个子模块以提高可维护性: + +- store/: 数据持久层,拆分自原 store.py (2869行 → 8个文件) +- algorithms/: 算法和解析器,拆分自原 algorithms.py (3330行 → 11个文件) + +使用方式: + from app.modules.data_process.store import DataProcessStore + from app.modules.data_process.algorithms import estimate_token_count +""" + +# 注意:为了避免循环导入,不在此处导入所有内容 +# 请直接从子模块导入所需功能 + +__all__ = ["store", "algorithms"] diff --git a/backend/app/modules/data_process/algorithms.py b/backend/app/modules/data_process/algorithms.py deleted file mode 100644 index a0204dd..0000000 --- a/backend/app/modules/data_process/algorithms.py +++ /dev/null @@ -1,3330 +0,0 @@ -"""数据处理模块使用的无副作用算法。 - -本模块不访问数据库、文件系统或网络,便于 API、后台任务和测试共同复用。 -所有偏移量均为 Python 字符串偏移量。 -""" - -from __future__ import annotations - -import csv -import hashlib -import io -import json -import math -import re -import unicodedata -import xml.etree.ElementTree as ET -import zipfile -from collections import Counter -from collections.abc import Iterable, Mapping, Sequence -from copy import deepcopy -from dataclasses import dataclass -from datetime import date, datetime, time -from decimal import Decimal -from pathlib import Path, PurePosixPath -from typing import Any, Literal -from urllib.parse import unquote, urlsplit - -from docx import Document -from docx.oxml.table import CT_Tbl -from docx.oxml.text.paragraph import CT_P -from docx.table import Table -from docx.text.paragraph import Paragraph -from openpyxl import load_workbook -from openpyxl.utils.cell import range_boundaries -from pptx import Presentation -from pypdf import PdfReader - -from app.modules.data_process.constants import MAX_QA_PAIRS_PER_ITEM - -TextFormat = Literal[ - "json", - "jsonl", - "csv", - "markdown", - "txt", - "pdf", - "docx", - "xlsx", - "pptx", -] -DatasetSplit = Literal["train", "validation", "test"] -StructuredPreprocessOption = Literal[ - "clean_invalid", - "detect_structure", - "deduplicate", - "normalize_format", - "filter_anomaly", - "desensitize", -] - -SUPPORTED_TEXT_FORMATS: tuple[TextFormat, ...] = ( - "json", - "jsonl", - "csv", - "markdown", - "txt", - "pdf", - "docx", - "xlsx", - "pptx", -) - -_FORMAT_ALIASES: dict[str, TextFormat] = { - "json": "json", - "jsonl": "jsonl", - "ndjson": "jsonl", - "csv": "csv", - "tsv": "csv", - "md": "markdown", - "markdown": "markdown", - "txt": "txt", - "text": "txt", - "pdf": "pdf", - "docx": "docx", - "xlsx": "xlsx", - "pptx": "pptx", -} -_LEGACY_OFFICE_FORMATS: dict[str, str] = { - "doc": "docx", - "xls": "xlsx", - "ppt": "pptx", -} -_OFFICE_OPEN_XML_FORMATS = {"docx", "xlsx", "pptx"} -_MAX_ARCHIVE_ENTRIES = 10_000 -_MAX_ARCHIVE_UNCOMPRESSED_BYTES = 512 * 1024 * 1024 -_MAX_ARCHIVE_ENTRY_BYTES = 128 * 1024 * 1024 -_MAX_ARCHIVE_COMPRESSION_RATIO = 200 -_MAX_EXTRACTED_TEXT_CHARS = 20_000_000 -_MAX_PDF_PAGES = 2_000 -_MAX_PRESENTATION_SLIDES = 2_000 -_MAX_WORKBOOK_SHEETS = 100 -_MAX_WORKBOOK_ROWS = 100_000 -_MAX_WORKBOOK_SCANNED_ROWS = 200_000 -_MAX_WORKBOOK_COLUMNS = 256 -_MAX_WORKBOOK_CELLS = 2_000_000 -_MAX_WORKBOOK_HEADER_ROWS = 8 -_MAX_WORKBOOK_HEADER_SCAN_ROWS = 64 -_MAX_WORKBOOK_MERGED_RANGES = 100_000 -_MAX_STRUCTURED_FIELDS = 1_024 -_MAX_STRUCTURED_DEPTH = 16 -_MAX_JSON_DEPTH = 64 -_MAX_ANOMALY_TEXT_CHARS = 1_000_000 -_STRUCTURED_OPTIONS = { - "clean_invalid", - "detect_structure", - "deduplicate", - "normalize_format", - "filter_anomaly", - "desensitize", -} -_IDENTITY_FIELD_PATTERN = re.compile(r"(?:^|[._])(?:id|uuid|key|code)$|(?:^|[._]).+_id$") -_MOJIBAKE_MARKERS = ("\ufffd", "锟斤拷", "烫烫烫", "屯屯屯", "Ã", "Â", "â€") -_JSON_RECORD_ARRAY_KEYS = ("records", "data", "items", "rows") -_JSON_ENVELOPE_KEYS = ("response", "payload") -_JSON_WRAPPER_METADATA_KEYS = frozenset( - { - "page", - "page_size", - "pageSize", - "per_page", - "perPage", - "total", - "total_count", - "totalCount", - "count", - "offset", - "limit", - "cursor", - "next_cursor", - "nextCursor", - "has_more", - "hasMore", - } -) -_JSON_RESPONSE_METADATA_KEYS = _JSON_WRAPPER_METADATA_KEYS | { - "success", - "status", - "code", - "message", - "error", -} -_NAME_FIELD_NAMES = { - "name", - "full_name", - "fullname", - "real_name", - "contact_name", - "customer_name", - "recipient_name", - "姓名", - "中文姓名", - "真实姓名", - "联系人", - "联系人姓名", - "客户姓名", - "收件人", - "收件人姓名", -} - -_EMAIL_PATTERN = re.compile( - r"(?姓名|真实姓名|联系人(?:姓名)?|收件人)" - r"(?P\s*(?:[::=]|为)\s*|\s+)" - r"(?P[\u3400-\u4dbf\u4e00-\u9fff·]{2,8})" -) -_ENGLISH_NAME_CONTEXT_PATTERN = re.compile( - r"(?im)(?P