# 快速上手

用一个带示例视频的容器先试一试，或者在你的服务器上生成令牌，然后用命令行、TypeScript 或 Python 搜索、上传文件，并给它加上元数据。

## 先在自己电脑上试

还没有服务器和账号？一个容器就能跑起全部服务，里面还有一个放好示例视频的空间可以随便试：

```sh
git clone https://github.com/blendduck/sidespace && cd sidespace
docker build -f deploy/trial/Dockerfile -t sidespace-trial .
docker run --rm -p 8080:8080 -p 8090:8090 -p 8070:8070 -v sidespace-trial:/data sidespace-trial
```

第一次启动会建好一个开发者账号、一个空间 "Film A" 和一个全权令牌（同时是 S3 密钥），打印在日志里，之后每次启动打印同一个。

```sh
export SIDESPACE_URL=http://localhost:8080 SIDESPACE_TOKEN=ssp_…   # 日志里打印的那一行
curl -H "Authorization: Bearer $SIDESPACE_TOKEN" "$SIDESPACE_URL/v1/search?q=storm"
curl -H "Authorization: Bearer $SIDESPACE_TOKEN" "$SIDESPACE_URL/v1/search?q=the+ocean+at+dusk&mode=meaning"
```

- "Film A" 里一开始就有四段示例视频（`/Ep01`、`/Ep02`），已经带着转写和 AI 标签，是 `side.transcribe` 和 `side.tags` 真正跑出来的。背后的模型换成了容器里的替身，回答是固定的，不需要任何 API key。搜索（带说到那个词的时间点）、按意思搜索、动作、流水线和 [MCP](/docs/mcp)（`http://localhost:8080/mcp`）都能直接试。
- 想换成真模型，启动时给 `SIDESPACE_TRANSCRIBE_URL` 和 `_KEY`、`SIDESPACE_ANTHROPIC_API_KEY` 或 `SIDESPACE_EMBED_URL` 和 `_KEY`，配了哪个就用哪个，其余仍用替身。`-e SIDESPACE_DEMO=0` 不放示例视频，也不用替身。
- 别人可以用任意邮箱加验证码 `000000` 登录。它不发邮件、不备份，只用来试，不要放真实素材。删掉 `sidespace-trial` 卷就从头再来。

用试用容器的话，跳过第 1 步，直接用日志里的令牌；本页其余步骤照做，把 `https://side.example.com` 换成 `http://localhost:8080`。

## 1. 生成令牌

先用 CLI 登录一次，再生成个人访问令牌。令牌只显示这一次，记得马上复制。

```sh
export SIDESPACE_SERVER=https://side.example.com   # CLI 连接的服务器
sidespace login you@studio.example
sidespace token create "quickstart" --scope files:write --scope sidecars:write --space "Film A"
# ssp_6Jw…  （只显示一次）
export SIDESPACE_URL=$SIDESPACE_SERVER              # Python SDK 读这个
export SIDESPACE_TOKEN=ssp_6Jw…                    # CLI 和 Python SDK 都读这个
```

`--space` 把令牌限定在一个空间；不加就能访问你加入的所有空间。权限、AI 成员和 OAuth 见[认证](/docs/authentication)。

## 2. 装 SDK（可选）

两个 SDK 都没有依赖，Apache-2.0 许可。它们还没有发布到 npm 和 PyPI：从仓库的检出目录安装，或者把文件夹拷进你的项目。

```sh tab=TypeScript
npm install ./sdks/typescript      # import { SideSpace } from "@sidespace/sdk"
```

```sh tab=Python
pip install ./sdks/python          # from sidespace import SideSpace
```

```sh tab=curl
# 什么都不用装。每次调用带上：-H "Authorization: Bearer $SIDESPACE_TOKEN"
```

## 3. 搜索

搜索覆盖文件名、标签、AI 提示词、转写和审阅评论。命中转写时，结果会带上这句话出现的时间点。

```sh tab=curl
curl -H "Authorization: Bearer $SIDESPACE_TOKEN" "$SIDESPACE_URL/v1/search?q=harbor+night"
```

```ts tab=TypeScript
import { SideSpace } from "@sidespace/sdk";

const side = new SideSpace({ baseUrl: process.env.SIDESPACE_URL!, token: process.env.SIDESPACE_TOKEN! });
for (const hit of await side.search("harbor night")) {
  console.log(hit.space_name, hit.folder, hit.node.name, hit.moments?.[0]?.at_ms);
}
```

```python tab=Python
from sidespace import SideSpace

side = SideSpace()  # 读取 SIDESPACE_URL 和 SIDESPACE_TOKEN
for hit in side.search("harbor night"):
    print(hit["space_name"], hit["folder"], hit["node"]["name"])
```

## 4. 上传文件

保存到已有的路径会多一个版本，不会覆盖任何东西。缺少的文件夹会自动建好。

```ts tab=TypeScript
await side.upload("Film A", "/Ep01/notes.md", "# Notes\n\nPick-ups on Tuesday.\n");
```

```python tab=Python
side.upload("Film A", "/Ep01/notes.md", "# Notes\n\nPick-ups on Tuesday.\n")
with open("A001_C003.mov", "rb") as f:
    side.upload("Film A", "/Ep01/Shots/A001_C003.mov", f)  # 流式上传，不会整个读进内存
```

```sh tab=curl
sidespace put "Film A" ./notes.md Ep01/notes.md
# 直接用 HTTP 上传分三步，见“文件与版本”。
```

## 5. 加上你自己的元数据

结果写进附加信息，而不是在原文件旁边再放一个文件。自定义命名空间以 `x-` 开头。

```ts tab=TypeScript
await side.putSidecar("Film A", "/Ep01/Shots/A001_C003.mov", "x-shotcheck", { focus: "soft", score: 0.42 });
const media = await side.getSidecar("Film A", "/Ep01/Shots/A001_C003.mov", "media");
console.log(media?.duration_s, media?.width, media?.height);
```

```python tab=Python
side.put_sidecar("Film A", "/Ep01/Shots/A001_C003.mov", "x-shotcheck", {"focus": "soft", "score": 0.42})
media = side.get_sidecar("Film A", "/Ep01/Shots/A001_C003.mov", "media")
```

```sh tab=curl
curl -X PUT "$SIDESPACE_URL/v1/spaces/$SPACE/versions/$VERSION/sidecars/x-shotcheck" \
  -H "Authorization: Bearer $SIDESPACE_TOKEN" -H "Content-Type: application/json" \
  -d '{"doc": {"focus": "soft", "score": 0.42}}'
```

现在在应用里打开这个文件，“信息”里能看到你写的字段，搜索也能搜到它们。

## 接下来

- 用 Webhook [跟踪变化](/docs/changes)，不用轮询。
- [运行 AI 处理](/docs/actions)：转写或给视频打标签，然后读取结果。
- [在 Claude 里用](/docs/claude)，或者通过 MCP [接入你自己的 agent](/docs/mcp)。
- [看过去、整体回滚](/docs/history)一个文件夹，或者[只改文件的一部分](/docs/files#只改文件的一部分)。
