news 2026/9/16 10:21:35

Unstract FileManagement API:面向组织的文件列表、下载与上传 REST 接口全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Unstract FileManagement API:面向组织的文件列表、下载与上传 REST 接口全解析

Unstract FileManagement API:面向组织的文件列表、下载与上传 REST 接口全解析

【免费下载链接】unstractLLM-Driven Extraction of Unstructured Data — Built for API Deployments & ETL Pipeline Workflows项目地址: https://gitcode.com/GitHub_Trending/un/unstract

本文以仓库中的 FileManagement API 文档 为主体,系统讲解 Unstract 后端中面向组织(Organization)的文件管理接口:列出文件(List File)、下载文件(Download)、上传文件(Upload)。读完本文,你不仅能掌握这三个 REST 接口的完整调用方式、参数与响应结构,还能结合 backend/file_management/views.py 与 backend/file_management/file_management_helper.py 等源码,理解接口背后如何通过 Connector 与UnstractFileSystem抽象对接不同的文件存储后端,以及文件上传的格式与大小限制是如何在序列化器层被强制校验的。

接口总览

backend/file_management/api_doc.md 中定义了三个核心接口,均挂载在组织作用域路径/unstract/<org_id>/之下:

功能方法路径说明
List File(列出文件)GET/unstract/<org_id>/fileconnector_idpath列出指定目录下的文件
Download(下载文件)GET/unstract/<org_id>/file/download以流式响应返回指定文件内容
Upload(上传文件)POST/unstract/<org_id>/file/upload向指定目录上传一个或多个文件

三个接口都以connector_id为关键参数——Unstract 通过 Connector 实例抽象不同的文件存储后端(本地存储、Google Drive、S3 等),文件操作实际是委托给对应 Connector 的文件系统实现的。

组织作用域路由:URL 中的<org_id>如何生效

接口路径中的<org_id>(如示例中的org_KIYj2cJ9Yisdewi4)并不由file_management应用自己解析。从源码结构看,backend/middleware/organization_middleware.py 中的OrganizationMiddleware使用正则^/api/(?P<version>v[12])/unstract/(?P<org_id>[^/]+)/匹配请求路径,将org_id写入request.organization_id,并把路径改写为/api/{version}/unstract/前缀后的相对路径。随后 backend/backend/urls_v2.py 第 29 行将file_management.urls挂载到根路径,file/file/download等子路由便自然衔接在后。

因此,api_doc.md 中的完整示例 URL 实际对应:

<base_url>/unstract/org_KIYj2cJ9Yisdewi4/file?connector_id=11&path=/

其中<org_id>是组织标识,用于多租户隔离与鉴权上下文;connector_idpath是业务查询参数。

List File:列出目录下的文件

请求

GET /unstract/<org_id>/file?connector_id=<id>&path=<path>

Sample URL(原文档示例):

<base_url>/unstract/org_KIYj2cJ9Yisdewi4/file?connector_id=11&path=/

查询参数由 backend/file_management/serializer.py 中的FileListRequestSerializer校验:

  • connector_idUUIDField,必填,对应数据库中ConnectorInstance主键;
  • pathCharField,必填,要列出的目录路径,根目录可传/

响应结构

返回的每个条目由FileInfoSerializer序列化,字段固定为 5 个:

{ "name": "文件/目录名", "type": "file 或 directory", "modified_at": "最后修改时间", "content_type": "MIME 类型", "size": 10240 }

这些字段的取值逻辑可以在 backend/file_management/file_management_dto.py 的FileInformation数据类中确认:name来自文件系统返回的条目名(经os.path.normpath归一化),modified_at解析LastModified字段,content_type优先使用后端返回的ContentType,缺失时由mimetypes.guess_type推断(见 file_management_helper.py 中get_files方法)。

源码实现要点

backend/file_management/views.py 中FileManagementViewSet.list的调用链为:

  1. connector_id查询ConnectorInstance,不存在则抛出 404(ConnectorInstanceNotFound);
  2. FileManagerHelper.get_file_system(connector_instance)根据 Connector 类型构造对应的UnstractFileSystem实例;
  3. FileManagerHelper.list_files(file_system, path)内部通过fs.ls(file_path, detail=True)递归读取一级目录条目,并过滤掉与目录自身同名的条目。

值得注意的是,当path为空或为/时,实现会回退使用file_system.path(Connector 元数据中配置的根路径),因此对配置了固定根路径的 Connector,path=/实际列出的是该根路径下的内容。

Download:以流式响应下载文件

请求

GET /unstract/<org_id>/file/download?connector_id=<id>&path=<path>

Sample URL(原文档示例):

<base_url>/unstract/org_KIYj2cJ9Yisdewi4/file/download?connector_id=12&path=root/MaskTwo-design

查询参数与 List 相同,由FileListRequestSerializer校验(见 views.py 中get_serializer_classdownloadaction 的映射)。

流式下载的实现细节

download_file位于 backend/file_management/file_management_helper.py,其关键行为对调用方有三点实际影响:

  • 类型校验:先调用fs.info(file_path)获取元数据,若type不是file(例如传入了目录路径),抛出InvalidFileType(404),即该接口只能下载单个文件;
  • Content-Type 推断:优先取后端返回的ContentType;若无,先试mimetypes.guess_type;仍无法确定时读取文件前 500 字节,用python-magicmagic.from_buffer)嗅探真实 MIME 类型,再设置到响应的content_type
  • 流式返回:使用 Django 的StreamingHttpResponse包装文件流,并设置Content-Disposition: attachment; filename=<base_name>,使浏览器按附件下载,文件名为路径中的 basename。

对 Google Drive 一类后端,若底层抛出ApiRequestError(如 OAuth 凭证失效),则转换为 400 的ConnectorApiRequestError("Failed to stream file")返回给客户端。

Upload:上传文件(含格式与大小限制)

请求

POST /unstract/<org_id>/file/upload

Sample URL(原文档示例):

<base_url>/unstract/org_KIYj2cJ9Yisdewi4/file/upload

原文档给出的 Body 结构为:

{ "file": "<multiple files>", "connector_id": "<Connector Id>", "path": "<File location>" }

需要说明的是,从序列化器定义看,file字段是ListField(child=FileField())(见 backend/file_management/serializer.py),因此实际请求应使用multipart/form-data编码:file可重复传多个文件,connector_idpath作为表单字段提交。

上传限制:PDF 与 200 MB

FileUploadSerializerfile字段挂接了FileValidator,其约束常量定义在 backend/file_management/constants.py:

约束项取值含义
FILE_UPLOAD_ALLOWED_EXT["pdf"]允许上传的文件扩展名,当前仅 PDF
FILE_UPLOAD_ALLOWED_MIME["application/pdf"]允许的 MIME 类型
FILE_UPLOAD_MAX_SIZE200 * 1024 * 1024(约 200 MB)单个文件最大字节数
min_size0不设最小尺寸

也就是说,当前版本的上传接口面向 PDF 文件设计(与 Unstract 以 PDF 为主要非结构化数据源的场景一致),且单文件上限为 200 MB。校验不通过会在序列化器层面直接拒绝请求,不会触达存储后端。

上传的实现

views.py 的uploadaction 遍历serializer.validated_data.get("file")中的每个上传文件,逐个调用FileManagerHelper.upload_file。后者在 file_management_helper.py 中的行为:

  1. 与 List 相同的回退逻辑:path为空或/时使用file_system.path作为实际目录;
  2. 拼接path + "/" + file_name,通过fs.open(file_path, mode="wb")以二进制写入远程文件系统;
  3. 兼容bytes与文件对象两种输入。

全部写入成功后,接口返回:

{ "message": "Files are uploaded successfully!" }

错误码速查

backend/file_management/exceptions.py 定义了该模块对外可见的错误语义,调用方可以据此做分支处理:

异常状态码消息典型触发场景
ConnectorInstanceNotFound404Connector instance does not existconnector_id在数据库中不存在
ConnectorClassNotFound404Connector class does not existConnector 类型无对应文件系统实现
ConnectorOAuthError401Unauthorized client during OAuthOAuth 访问令牌刷新失败(List 场景)
ConnectorApiRequestError400Failed to stream file底层存储 API 请求失败(如 Drive 的ApiRequestError
InvalidFileType404Invalid file type下载路径指向的是目录而非文件
FileListError500Error occured while listing files列目录时底层fs.ls抛错
MissingConnectorParams400Missing params in connector metadataConnector 缺少必需的路径元数据

其中 List 接口的异常映射在 views.py 中可以逐一对应:DoesNotExist→ 404、HttpAccessTokenRefreshError→ 401、ConnectorError→ 500 的FileListError

底层抽象:Connector 到文件系统的映射

三个接口共同依赖FileManagerHelper.get_file_system,其逻辑为:读取ConnectorInstance.connector_metadata,在unstract.connectors.filesystemsconnectors注册表中按connector.connector_id查找,找到后以元数据为配置实例化对应的UnstractFileSystem子类,未找到则抛ConnectorClassNotFound。该注册表定义于 unstract/filesystem 包(unstract/connectors/filesystems)。从源码结构看,这套抽象使得上层 API 对具体存储无感知——同一套/file端点既可以操作本地存储,也可以操作云端文件服务,差异被封装在 Connector 实例的元数据与对应的文件系统实现中。

相关扩展端点

除了原文档描述的三个接口,backend/file_management/urls.py 中还注册了file/deleteGET,按document_id删除 Prompt Studio 文档记录及对应文件),并在prompt_studio相关 URL 模块中映射了upload_for_idefetch_contents_idelist_ide等 IDE 场景端点(见 views.py)。这些端点服务于 Prompt Studio 的本地文档管理链路,与面向 Connector 的通用文件接口在参数模型上不同:删除接口使用FileInfoIdeSerializerdocument_idtool_id),路径由FileManagerHelper.handle_sub_directory_for_tenantsorg_id / user_id / tool_id分层解析。理解这一分层路径结构,有助于把握 Unstract 对多租户文件目录的隔离设计。

小结

  • 三个接口的调用形态与参数约束以 backend/file_management/api_doc.md 为准:List 与 Download 均为GET+connector_id/path查询参数,Upload 为POSTmultipart 请求;
  • 上传接口当前仅允许 PDF、单文件上限 200 MB(constants.py);
  • 响应与错误语义可在 serializer.py、exceptions.py 中逐一对照;
  • 若要在自定义集成中使用这些接口,建议优先处理 401/404/400 三类状态码,分别对应 OAuth 失效、资源不存在与请求/流式错误。

【免费下载链接】unstractLLM-Driven Extraction of Unstructured Data — Built for API Deployments & ETL Pipeline Workflows项目地址: https://gitcode.com/GitHub_Trending/un/unstract

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 10:20:49

STM32直驱舵机的PWM时序、电源与校准三大硬约束

简介&#xff1a;本资源是一份面向嵌入式初学者与机器人开发者的舵机控制实践代码包&#xff0c;聚焦C语言环境下PWM信号生成与舵机角度精确调控的核心技能。压缩包共14个文件&#xff0c;含主程序源码&#xff08;main.c&#xff09;、编译输出文件&#xff08;.hex、.obj、.l…

作者头像 李华
网站建设 2026/9/16 10:19:37

2026固态硬盘选购实战指南:协议、兼容性与真实性能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 10:19:31

本科生论文写作AI工具对比:千笔与笔捷AI

1. 本科生论文写作工具对比&#xff1a;千笔写作工具与笔捷AI作为一名经历过本科论文写作的过来人&#xff0c;我深知论文写作对本科生来说是个不小的挑战。最近市面上出现了两款专门针对本科生论文写作的AI工具——千笔写作工具和笔捷AI&#xff0c;它们都号称能帮助本科生高效…

作者头像 李华
网站建设 2026/9/16 10:19:26

MATLAB路面裂缝检测系统:图像处理流水线设计与实现

简介&#xff1a;这是一套面向MATLAB环境的路面裂缝检测识别系统设计资源&#xff0c;融合深度学习与图像处理技术&#xff0c;适合正在学习CNN图像分类、MATLAB GUI开发或道路损伤自动化检测的工程师及高校学生。压缩包内共18个文件&#xff0c;包含14个.m源码文件、1个.fig界…

作者头像 李华
网站建设 2026/9/16 10:19:25

餐饮品牌无形资产构建与价值评估实战解析

1. 项目背景解析&#xff1a;烤肉行业的价值重构"明月三千里"这个品牌名称本身就蕴含着丰富的文化意象——"明月"象征高洁品质&#xff0c;"三千里"则让人联想到朝鲜半岛的别称&#xff0c;暗示着品牌与韩式烤肉的深厚渊源。当这样一个充满诗意的…

作者头像 李华