> This page is for 平台, version 旧版.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 实验版: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - 旧版: https://next.developer.frame.io/platform/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# 读取文件树

## 概述




无论最终目标是发布、编辑资产还是将资产推送到工作流的某个阶段，许多与 Frame.io 的深度集成都将涉及列出用户上下文，并最终呈现目录视图。





以下是 Frame.io 中资源（或文件）的基本层级结构：





#### 帐户 &gt; 团队 &gt; 项目 &gt; 资产





本文介绍如何通过顺序调用 API 来与文件树进行交互。处理文件的一种常见策略是：首先访问一个项目，列出文件夹，然后处理其中包含的资产和版本堆栈。





## 重要概念




### 每个项目都有一个唯一的根资产

RESTful API 通常使用唯一标识符来描述资源；`root_asset_id` 是项目资产树的唯一标识符。将其视为一个充当项目根节点的特殊结构：其余资产在根节点之下以向下树状结构堆叠。<img alt="root-asset-id" src="/_fern-img/ea24ed6ff53d93cf1dab9e154c289f816238abca823e8127f367cdee1eb2a8cc.webp" />

在常见的工作流程中，API 用户需要向下遍历树状结构，以便与文件层级中更深层的资产进行交互。





### 协作者和共享项目

**协作者**是 Frame.io 中的关键用户角色之一：此类用户可以访问项目工作区，但可能不属于该项目的上级帐户。暂且不论[协作者和团队成员](https://support.frame.io/en/articles/6067-difference-between-team-members-vs-collaborators)之间不同的权限，主要区别在于：*协作者的成员身份严格隶属于某个项目，可能与某个团队无关。*。

这对于那些目录列表至关重要的工作流程来说，会造成一个小问题。虽然上述基本层级结构（帐户 &gt; 团队 &gt; 项目 &gt; 资产）适用于大多数使用场景，但它无法描述这样一种情况：经过身份验证的用户是某个项目的协作者，却不是该项目的团队成员。为了在列出目录时绕过这个问题，您可以：




* 获取用户的共享项目，拆解团队和帐户层级结构，然后将所有内容组合在一起；或者
* 获取用户的共享项目，然后将它们作为一个独立的上下文一并列出。




两种方法都可以；后者稍微简单一些，但前者更接近 Frame.io Web 应用程序呈现类似信息的方式。无论如何，本指南中涵盖的方法都适用于这两种情况。





## 列出目录




### 1. 获取用户帐户

`GET https://api.frame.io/v2/accounts`

使用有效的持有者令牌发起上述调用，以获取用户的帐户。您将收到用户在其中拥有团队成员、团队经理或管理员身份的每一个帐户。您也可能收到用户具有计费/管理员权限但么可以团队访问权限的团队，但这种情况很少见，并且会在下一步中被筛选掉。





帐户请求的负载相当冗长，以下是您可能希望从响应中获取的重要数据摘要：




* `id`
* `display_name`
* `所有者`（`电子邮件`，`姓名`）
* （可选）`图像`



<Info title="帐户图像是临时 URL">
  


*注意：* 我们的 API 返回的帐户图像将是一个预签名的 S3 密钥，因此返回的 URL 大约一天后就会“失效”。为了解决此问题，您应该在每次服务加载时重新获取该图像，或者最好将其存储在本地。



</Info>
请注意，`id` 和 `owner.email` 是用户帐户上仅有的必填字段。如果您要在其他应用程序中显示用户，请考虑编写用于呈现用户帐户的条件逻辑。我们的建议是进行检查，如果不是 *null*，则按照以下优先顺序显示帐户：
1. &quot;`display_name`&quot;
2. “`owner.name` 的帐户”
3. “`owner.email` 的帐户”





一旦您的用户选择了一个帐户，您可能希望显示团队，而这需要额外的 API 请求。





### 2. 获取帐户内的团队

`GET https://api.frame.io/v2/accounts/{{account_id}}/teams` Frame.io 中的团队可以是“公开”（即，帐户中的任何团队成员都可发现）或“私有”（仅特定团队成员可发现）。API 将为您处理上下文，因此您只需在上述请求中指定 `account_id` 并进行有效调用即可。
<Info title="不要忘记进行分页">
  


虽然一位用户不太可能存在于多个帐户中，但团队是一种可能会迅速膨胀的资源。Frame.io 的 API 速率限制相当高，但最好始终检查响应标头，并在必要时进行分页。



</Info>
您可以通过阅读[分页和错误](/docs/troubleshooting/troubleshooting)来找到更多关于分页的信息。**从每个团队中，获取以下属性：**
* `id`
* `name`
* （可选）`team_image`




选择一个团队后，您需要显示其中包含的项目。

**注意**：如果愿意，您也可以 `GET https://api.frame.io/v2/teams` 来获取某个用户的信息，我们的 API 将返回用户所属的每个团队，无论帐户上下文如何。虽然这从技术上讲是可行的，但您面临丢失上下文的风险，除非您再采取额外步骤：
1. 通过在每个团队旁边显示对应的帐户名称来重新建立上下文
2. 允许您的用户搜索列表中的文本

如果您要从帐户级别向下列出共享项目，您需要对 `GET https://api.frame.io/v2/projects/shared` 进行额外调用。响应中返回的每个项目都将包含以下属性，您在构建目录时可以沿用这些属性：
* 项目自身的 `id`
* `team_id`
* `team.account_id`




或者，您也可以通过将“共享项目”作为“团队”添加到任何选定的帐户上下文中，来为其提供一个入口。如果您选择这样做，那么在视觉上将共享项目与真正的团队范围项目区分开会对最终用户有帮助，因为单一的共享项目列表在底层可能包含许多不同的真正帐户和团队上下文。





### 3. 获取团队的项目

`GET https://api.frame.io/v2/teams/{{team_id}}/projects`

接下来，发起上述调用并获取团队内的所有项目。

**对于每个项目，您需要获取：**
* `id`
* `name`
* `root_asset_id`
* （可选）`private`，以便您希望在 UI 中为用户进行区分时使用

正如文章开头所述，`root_asset_id` 是 Frame.io 资源架构中的一个重要组成部分，因为它允许您在项目内导航文件和文件夹目录。
<Info title="列出文件夹和资产">
  


让我们快速回顾一下到目前为止所做的工作：我们已经确立了以下组合上下文：



</Info>


| * 帐户




| * 团队




| * 团队项目（和 root_asset_ids）




| * 共享项目（和 root_asset_ids）




| 这就是我们创建或获取资产所需的全部内容。





## 列出文件夹和资产





### 4. 构建初始文件夹结构

`GET https://api.frame.io/v2/assets/{{root_asset_id}}/children?type=folder` 这将从 `root_asset_id` 开始，列出项目中的所有文件夹。如果没有文件夹，您将收到一个空列表。如果您想要同时包含文件和文件夹（例如，若您的下一步是从 Frame.io `获取`一个资产），只需省略查询字符串参数即可。

type 参数可用的其他两个筛选选项是 file 和 version_stack。这三个筛选选项互相排斥，不带筛选条件的调用将返回所有三种类型混合在一起的结果。





### 5. 遍历目录树

**对于返回的每个文件夹，您需要获取：**
* `id`
* `name`




由于每个文件夹都是一个资产，因此您遍历文件夹结构的工作流程将如下所示：




1. `GET https://api.frame.io/v2/assets/{{root_asset_id}}/children?type=folder`


    

1. 在列表中渲染出文件夹名称


    

2. 当用户点击某个文件夹时，将该文件夹的 ID 传递到以下查询：



2. `GET https://api.frame.io/v2/assets/{{folder_id}}/children?type=folder`





### 6. 创建和上传

**上传到文件夹：** `POST https://api.frame.io/v2/{{folder_id}}/children` 一旦您获得了要上传到其中的文件夹的 ID，只需根据资源文档和指南对其次项发起一个 `POST` 请求即可。这将创建一个占位符资产，并且（根据您选择的方法）返回：
* 一个用于跟踪用例的 `uuid`
* 一个 upload_urls 列表，可用于将文件直接 PUT 到 Frame.io 的后端数据存储中。

**上传到版本堆栈：**版本堆栈提供了类似的工作流程，但多了一个步骤，[本指南](doc:managing-version-stacks)对此进行了说明，总结如下。关键在于记住：版本堆栈是一个容器，它看起来像一个资产，但行为像一个文件夹；并且您必须首先上传您的资产，然后将其作为单独的操作堆叠到您的版本堆栈中。因此，**如果您想要将某个资产上传到版本堆栈中，您需要：**
* 版本堆栈的 `id`
* 版本堆栈的 `parent_id`（例如，它所在的文件夹或项目根目录）

首先，`POST https://api.frame.io/v2/assets/{{parent_id}}/children` 来创建新资产。在响应中捕获新的 `id`。现在，您可以使用新资产的 ID 和 `POST https://api.frame.io/v2/assets/{{version_stack_id}}/version`，并附带以下请求体负载：

```json
{
  "next_asset_id": "<new-asset-id>"
}
```