feat:完成大部分数据文件上传解析功能
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"""数据文件的接口模型:文件记录、表、列和解析警告,见 docs/screen-agent/data-files.md 5.4、6.6、7
|
||||
|
||||
文件和表各有三层,后一层在前一层上加字段:列表接口返回的 Info、单个文件返回的 Detail、存储用的完整记录
|
||||
接口返回时用对应的模型重新校验存储记录,多出的字段自然丢掉
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, JsonValue
|
||||
|
||||
DataFormat = Literal["csv", "tsv", "xlsx", "xls", "xlsb", "json", "jsonl", "parquet"]
|
||||
|
||||
ColumnType = Literal["text", "number", "date", "datetime", "boolean"]
|
||||
|
||||
WarningCode = Literal[
|
||||
"title_skipped",
|
||||
"note_skipped",
|
||||
"block_dropped",
|
||||
"header_merged",
|
||||
"header_uncertain",
|
||||
"total_rows_removed",
|
||||
"column_renamed",
|
||||
"kept_as_text",
|
||||
"bad_lines_skipped",
|
||||
"json_path_selected",
|
||||
"empty_sheet_skipped",
|
||||
"hidden_sheet_skipped",
|
||||
]
|
||||
|
||||
|
||||
class DataColumn(BaseModel):
|
||||
name: str
|
||||
type: ColumnType
|
||||
# 原文是百分比时为 percent,值已存为小数
|
||||
format: Literal["percent"] | None = None
|
||||
|
||||
|
||||
class ParseWarning(BaseModel):
|
||||
code: WarningCode
|
||||
# 表名;为空表示针对整个文件。解析时还没有分配表名,由上传流程填写
|
||||
table: str | None = None
|
||||
# 可以直接展示的中文说明
|
||||
message: str
|
||||
|
||||
|
||||
class DataTableInfo(BaseModel):
|
||||
# 会话内的表名 t1、t2……,模型写 SQL 时用
|
||||
table: str
|
||||
# 文件名 / sheet,同一 sheet 切出多张表时再加序号
|
||||
label: str
|
||||
sheet: str | None
|
||||
rows: int
|
||||
columns: list[DataColumn]
|
||||
|
||||
|
||||
class DataTableDetail(DataTableInfo):
|
||||
# 前 20 行,顺序与 columns 一致
|
||||
preview: list[list[JsonValue]]
|
||||
|
||||
|
||||
class DataTable(DataTableDetail):
|
||||
# 列概况,给 describe_data 用
|
||||
profile: dict[str, JsonValue]
|
||||
# 文件目录下的 Parquet 文件名
|
||||
parquet: str
|
||||
|
||||
|
||||
class DataFileInfo(BaseModel):
|
||||
file_id: str
|
||||
conversation_id: str
|
||||
name: str
|
||||
format: DataFormat
|
||||
# 文本文件识别出的编码,二进制格式为空
|
||||
encoding: str | None
|
||||
size: int
|
||||
created_at: datetime
|
||||
expires_at: datetime
|
||||
tables: list[DataTableInfo]
|
||||
warnings: list[ParseWarning]
|
||||
|
||||
|
||||
class DataFileDetail(DataFileInfo):
|
||||
tables: list[DataTableDetail]
|
||||
|
||||
|
||||
class DataFileRecord(DataFileDetail):
|
||||
owner_id: int
|
||||
sha256: str
|
||||
tables: list[DataTable]
|
||||
# 删除只做标记,记录留到过期,会话内的表名不会被新文件重复使用
|
||||
deleted: bool = False
|
||||
|
||||
|
||||
class DataFileList(BaseModel):
|
||||
files: list[DataFileInfo]
|
||||
|
||||
|
||||
class DataFileLimits(BaseModel):
|
||||
max_size_mb: int
|
||||
max_files_per_conversation: int
|
||||
formats: list[DataFormat]
|
||||
# 文件选择框的 accept,只用于前端过滤;后端按文件内容识别格式
|
||||
accept: str
|
||||
|
||||
|
||||
class RequestDataTable(DataTableInfo):
|
||||
"""本次请求可用的表:多出工具要用的列概况和 Parquet 路径,不带预览"""
|
||||
|
||||
profile: dict[str, JsonValue]
|
||||
path: str
|
||||
|
||||
|
||||
class RequestDataFile(BaseModel):
|
||||
"""本次请求可用的文件:服务端按会话读取后放进请求,前端传的同名字段会被覆盖"""
|
||||
|
||||
file_id: str
|
||||
name: str
|
||||
# 本轮消息的 attachments 里带了这个文件,通常是刚上传的
|
||||
attached_this_turn: bool
|
||||
tables: list[RequestDataTable]
|
||||
warnings: list[ParseWarning]
|
||||
@@ -3,6 +3,7 @@
|
||||
from pydantic import Field
|
||||
|
||||
from .base import JsonObject
|
||||
from .data_file import RequestDataFile
|
||||
from .request import DesignRequest
|
||||
|
||||
|
||||
@@ -12,3 +13,5 @@ class InputContext(DesignRequest):
|
||||
clarification_history: list[JsonObject] = Field(default_factory=list)
|
||||
# 同一会话此前各轮的用户输入与助手回复,由服务端按 conversation_id 读取并按 token 预算裁剪,按时间从早到晚排列
|
||||
history: list[JsonObject] = Field(default_factory=list)
|
||||
# 本会话里未过期的数据文件,由服务端读取并校验 attachments 后填入
|
||||
data_files: list[RequestDataFile] = Field(default_factory=list)
|
||||
|
||||
@@ -17,5 +17,6 @@ class DesignRequest(ExtensibleModel):
|
||||
prompt: NonBlankString
|
||||
screen: Screen
|
||||
context: RequestContext = Field(default_factory=RequestContext)
|
||||
# 只预留 JSON 描述入口,暂不规定材料种类,也不读取文件或远程资源
|
||||
# 本条消息附带的材料;{"kind": "data_file", "file_id": "..."} 引用本会话上传的数据文件,
|
||||
# 其他种类只原样进入摘要,不读取文件或远程资源
|
||||
attachments: list[JsonObject] = Field(default_factory=list)
|
||||
|
||||
Reference in New Issue
Block a user