接入

SDK

TypeScript、Python、Go 和 Rust 客户端,通过同一套测试。用路径代替 id,流式上传和按范围下载,安全写入、局部修改、附加信息、搜索、变更、Webhook 和动作。

查看 Markdown
语言包名目录运行环境
TypeScript / JavaScript@sidespace/sdksdks/typescriptNode 18+、Deno、Bun、浏览器(有 fetch 就行)
Pythonsidespacesdks/pythonPython 3.9+,只用标准库
Gogithub.com/blendduck/sidespace/sdks/gosdks/goGo 1.22+,只用标准库
Rustsidespacesdks/rust异步,基于 reqwest(rustls)和 tokio

四个 SDK 都是 Apache-2.0 许可,文件相关的功能一致。它们还没有发布到 npm、PyPI、Go 模块代理和 crates.io:从仓库的检出目录使用,或者把文件夹拷进你的项目。

npm install ./sdks/typescript

初始化

import { SideSpace } from "@sidespace/sdk";

const side = new SideSpace({ baseUrl: "https://side.example.com", token: process.env.SIDESPACE_TOKEN! });

空间可以用名字或 id,文件用路径。错误里带服务器返回的 status、code 和 message:TypeScript 和 Python 抛出 SideSpaceError;Go 和 Rust 的错误可以用 IsPreconditionFailed / is_precondition_failed() 判断安全写入是否冲突,并拿到当前版本。完整方法列表见各自目录的 README。

覆盖范围

功能TypeScriptPython
空间和文件夹spaces()、space()、node()、list()、mkdir()spaces()、space()、node()、list()、mkdir()
上传和下载upload()、download()、带 range 的 open()upload()(文件对象流式上传)、download()、带 range 的 open()
版本versions()、restoreVersion()versions()、restore_version()
只改一部分edit()、appendText()edit()、append_text()
过去的样子node()、list()、open()、download() 带 asOf;rewind()node()、list()、open() 带 as_of=;rewind()
附加信息getSidecar()、putSidecar()get_sidecar()、put_sidecar()
搜索search(q, { space, type, mode })search(q, space=, type=, mode=)
变更journal()、changes()(异步迭代器)journal()、changes()(生成器)
WebhookcreateWebhook(),@sidespace/sdk/webhooks 里的 verifyWebhookSignature()create_webhook()、verify_webhook_signature()
动作和流水线actions()、run()、startRun()、waitRun()、runs()、createPipeline()actions()、run()、start_run()、wait_run()、runs()、create_pipeline()
评论comments()、addComment()、editComment()、resolveComment()comments()、add_comment()、edit_comment()、resolve_comment()
分支fork()、forks()、forkChanges()、applyFork()fork()、forks()、fork_changes()、apply_fork()
插件installPlugin()、PluginRuninstall_plugin()、PluginRun

Go 和 Rust 覆盖同样的文件操作(空间、路径、流式上传和按范围下载、安全写入、按字节修改、版本、附加信息、搜索、评论、变更、动作和 Webhook),方法名按各自语言的习惯(UploadText、upload_text)。

API 参考里的其他接口,用 request() 一行就能调(Go 里是 Do):

const film = await side.space("Film A");
const presence = await side.request("GET", `/v1/spaces/${film.id}/presence`);

四个 SDK 一套测试

sdks/conformance/cases.json 是一份 34 步的清单(保存、按范围读、安全写入冲突、局部修改、恢复、文件夹、附加信息、评论、搜索和错误),每个 SDK 用自己的执行器对着真实服务器跑一遍,check.py 对比结果,所以四个 SDK 不会各走各的。四个都全部通过。想自己对着开发服务器检查一个:

Shell
SIDESPACE_SERVER=… SIDE_TOKEN=… SPACE=… python3 sdks/conformance/runner.py | python3 sdks/conformance/check.py --sdk python

任何语言的新 SDK,跑通全部步骤就算完成。

完整示例

给 /dailies 里还没打分的每个视频,用你自己的模型打分(只读每个文件的前 8 MB),结果存进附加信息:

import { SideSpace, SideSpaceError } from "@sidespace/sdk";

const side = new SideSpace({ baseUrl: process.env.SIDESPACE_URL!, token: process.env.SIDESPACE_TOKEN! });

for (const file of await side.list("Film A", "/dailies")) {
  if (!file.mime?.startsWith("video/")) continue;
  const path = `/dailies/${file.name}`;
  const done = await side.getSidecar("Film A", path, "x-mymodel").catch((e) => {
    if (e instanceof SideSpaceError && e.status === 404) return null;
    throw e;
  });
  if (done) continue;
  const head = await side.open("Film A", path, { range: [0, 8 * 1024 * 1024 - 1] });
  const score = await myModel(await head.arrayBuffer());
  await side.putSidecar("Film A", path, "x-mymodel", { score, model: "mymodel-2" });
}

要随着新素材到来持续处理,把同样的代码放进 Webhook 处理函数,或者打包成插件再配一条流水线:两者都会记住进度并自动重试。