X-AnyLabeling 云端同步 API v2 文档
概述
本文档描述了 X-AnyLabeling 云端同步功能的 API 接口规范(v2 版本)。v2 版本在 v1 基础上增加了多用户支持、工作空间归属、权限控制、用户数据隔离等功能。
认证方式
所有 API 请求需要在 HTTP Header 中携带 API Key:
Token: <your_api_key>
基础 URL
http://<server_host>:<server_port>
通用响应格式
成功响应
{
"success": true,
"data": { ... }
}
错误响应
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Error message"
}
}
错误码表
| 错误码 | HTTP 状态码 | 说明 |
|---|---|---|
| UNAUTHORIZED | 401 | API Key 无效或缺失 |
| FORBIDDEN | 403 | 权限不足 |
| WORKSPACE_ACCESS_DENIED | 403 | 无权访问该工作空间 |
| API_KEY_EXPIRED | 401 | API Key 已过期 |
| WORKSPACE_CONFLICT | 409 | 工作空间名称冲突 |
| CLOUD_DISABLED | 200 | 云端存储未启用 |
| FILE_NOT_FOUND | 200 | 文件不存在 |
| NOT_FOUND | 200 | 资源不存在 |
| LIST_ERROR | 200 | 列表操作失败 |
| UPLOAD_ERROR | 200 | 上传失败 |
| DOWNLOAD_ERROR | 200 | 下载失败 |
| DELETE_ERROR | 200 | 删除失败 |
| CREATE_ERROR | 200 | 创建失败 |
| UPDATE_ERROR | 200 | 更新失败 |
| CHECKSUM_ERROR | 200 | 校验失败 |
| RESOLVE_ERROR | 200 | 解析失败 |
API 端点
1. 用户信息
GET /v1/users/me
获取当前认证用户的信息。
请求
GET /v1/users/me
Token: <api_key>
响应
{
"success": true,
"data": {
"user_id": "zhangsan",
"name": "张三",
"permissions": ["read", "write", "delete"]
}
}
权限要求:无(只需有效 API Key)
2. 连接管理
POST /v1/cloud/connect
验证连接并返回工作空间状态和用户信息。
请求
POST /v1/cloud/connect
Token: <api_key>
响应
{
"success": true,
"data": {
"status": "connected",
"storage_type": "minio",
"user": {
"user_id": "zhangsan",
"name": "张三",
"permissions": ["read", "write", "delete"]
}
}
}
权限要求:无(只需有效 API Key)
POST /v1/cloud/disconnect
断开连接(无状态 API,实际为占位端点)。
请求
POST /v1/cloud/disconnect
Token: <api_key>
响应
{
"success": true,
"data": {
"message": "disconnected"
}
}
权限要求:无
3. 工作空间管理
GET /v1/cloud/workspaces
列出当前用户有权访问的所有工作空间。
请求
GET /v1/cloud/workspaces
Token: <api_key>
响应
{
"success": true,
"data": [
{
"workspace": "project-a",
"owner": "zhangsan",
"local_path": "/data/project-a",
"display_name": "Project A",
"description": "标注项目 A",
"created_at": "2026-06-23T10:00:00+00:00",
"updated_at": "2026-06-23T10:30:00+00:00"
},
{
"workspace": "project-b",
"owner": "zhangsan",
"local_path": "/data/project-b",
"display_name": "Project B",
"description": "标注项目 B",
"created_at": "2026-06-23T09:00:00+00:00",
"updated_at": "2026-06-23T09:30:00+00:00"
}
]
}
字段说明
workspace: 工作空间唯一标识owner: 工作空间所有者 user_idlocal_path: 本地文件夹路径display_name: 显示名称description: 描述created_at: 创建时间(ISO 8601)updated_at: 更新时间(ISO 8601)
权限要求:read
POST /v1/cloud/workspaces
创建新的工作空间。工作空间所有者自动设置为当前用户。
请求
POST /v1/cloud/workspaces?workspace=project-c&local_path=/data/project-c&display_name=Project%20C&description=New%20project
Token: <api_key>
查询参数
workspace(必需): 工作空间唯一标识local_path(可选): 本地文件夹路径display_name(可选): 显示名称description(可选): 描述
响应
{
"success": true,
"data": {
"workspace": "project-c",
"owner": "zhangsan",
"local_path": "/data/project-c",
"display_name": "Project C",
"description": "New project",
"created_at": "2026-06-23T11:00:00+00:00",
"updated_at": "2026-06-23T11:00:00+00:00"
}
}
权限要求:write
PUT /v1/cloud/workspaces/{workspace}
更新工作空间配置。只有工作空间所有者或管理员可以执行此操作。
请求
PUT /v1/cloud/workspaces/project-a?local_path=/new/path&display_name=New%20Name
Token: <api_key>
路径参数
workspace: 工作空间标识
查询参数
local_path(可选): 新的本地文件夹路径display_name(可选): 新的显示名称description(可选): 新的描述
响应
{
"success": true,
"data": {
"workspace": "project-a",
"owner": "zhangsan",
"local_path": "/new/path",
"display_name": "New Name",
"description": "Updated description",
"created_at": "2026-06-23T10:00:00+00:00",
"updated_at": "2026-06-23T12:00:00+00:00"
}
}
权限要求:write + 工作空间所有者或管理员
DELETE /v1/cloud/workspaces/{workspace}
删除工作空间配置(不会删除实际文件)。只有工作空间所有者或管理员可以执行此操作。
请求
DELETE /v1/cloud/workspaces/project-a
Token: <api_key>
响应
{
"success": true,
"data": {
"workspace": "project-a",
"deleted": true
}
}
权限要求:delete + 工作空间所有者或管理员
4. 文件操作
GET /v1/cloud/workspaces/{workspace}/files
列出工作空间中的所有文件。
请求
GET /v1/cloud/workspaces/project-a/files
Token: <api_key>
响应
{
"success": true,
"data": [
{
"name": "image_001.jpg",
"size": 102400,
"checksum": "d41d8cd98f00b204e9800998ecf8427e",
"last_modified": "2026-06-23T10:30:00+00:00"
},
{
"name": "image_001.json",
"size": 2048,
"checksum": "098f6bcd4621d373cade4e832627b4f6",
"last_modified": "2026-06-23T10:35:00+00:00"
}
]
}
字段说明
name: 文件名size: 文件大小(字节)checksum: MD5 校验和last_modified: 最后修改时间(ISO 8601)
权限要求:read + 工作空间访问权限
POST /v1/cloud/workspaces/{workspace}/upload
上传文件到工作空间。支持图片、JSON 标签文件和视频文件。
请求
POST /v1/cloud/workspaces/project-a/upload
Content-Type: multipart/form-data
Token: <api_key>
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="image_002.jpg"
Content-Type: image/jpeg
<file content>
------WebKitFormBoundary
Content-Disposition: form-data; name="filename"
image_002.jpg
------WebKitFormBoundary--
表单字段
file(必需): 文件内容(multipart/form-data)filename(必需): 目标文件名
响应
{
"success": true,
"data": {
"filename": "image_002.jpg",
"size": 102400,
"checksum": "d41d8cd98f00b204e9800998ecf8427e"
}
}
权限要求:write + 工作空间访问权限
GET /v1/cloud/workspaces/{workspace}/download/{filename}
从工作空间下载文件。
请求
GET /v1/cloud/workspaces/project-a/download/image_001.jpg
Token: <api_key>
响应
返回文件内容,Content-Type 为 application/octet-stream。
权限要求:read + 工作空间访问权限
DELETE /v1/cloud/workspaces/{workspace}/files/{filename}
从工作空间删除文件。
请求
DELETE /v1/cloud/workspaces/project-a/files/image_001.jpg
Token: <api_key>
响应
{
"success": true,
"data": {
"filename": "image_001.jpg",
"deleted": true
}
}
权限要求:delete + 工作空间访问权限
GET /v1/cloud/workspaces/{workspace}/checksum/{filename}
获取文件的 MD5 校验和。
请求
GET /v1/cloud/workspaces/project-a/checksum/image_001.jpg
Token: <api_key>
响应
{
"success": true,
"data": {
"filename": "image_001.jpg",
"checksum": "d41d8cd98f00b204e9800998ecf8427e"
}
}
权限要求:read + 工作空间访问权限
6. 工作空间解析
POST /v1/cloud/workspaces/resolve
根据本地路径解析对应的工作空间。用于在打开本地文件夹时自动识别关联的云端工作空间。
请求
POST /v1/cloud/workspaces/resolve?local_path=/data/project-a
Token: <api_key>
查询参数
local_path(必需): 本地文件夹路径
响应
{
"success": true,
"data": {
"workspace": "project-a",
"owner": "zhangsan",
"local_path": "/data/project-a",
"display_name": "Project A",
"description": "标注项目 A",
"created_at": "2026-06-23T10:00:00+00:00",
"updated_at": "2026-06-23T10:30:00+00:00"
}
}
权限要求:read
权限模型
权限级别
| 权限 | 说明 | 可访问的操作 |
|---|---|---|
read |
读取 | list_files, download, checksum, list_workspaces, resolve |
write |
写入 | upload, create_workspace, update_workspace |
delete |
删除 | delete_file, delete_workspace |
admin |
管理 | 所有操作 |
权限检查规则
- 管理员权限:拥有
admin权限的用户可以执行所有操作,绕过所有工作空间访问限制 - 工作空间访问:只有工作空间所有者(
owner)可以访问该工作空间 - 所有者操作:更新、删除工作空间等操作只有工作空间所有者或管理员可以执行
- 向后兼容:当
api_key_enabled=false时,所有权限检查被跳过,保持 v1 行为
审计日志
所有关键操作都会记录审计日志,存储在 MinIO 的 {bucket}-audit 存储桶中。
记录的操作
- 文件上传/下载/删除
- 工作空间创建/更新/删除
日志格式
{
"timestamp": "2026-06-23T11:00:00+00:00",
"user_id": "zhangsan",
"action": "upload",
"workspace": "project-a",
"resource": "image_002.jpg",
"details": {
"size": 102400,
"checksum": "d41d8cd98f00b204e9800998ecf8427e"
}
}
日志路径
{bucket}-audit/{workspace}/{YYYY}/{MM}/{DD}/{timestamp}_{user_id}_{action}.json
向后兼容性
单 API Key 模式
当配置中只有单个 api_key(而非 api_keys 列表)时,系统会自动创建一个默认的 admin 用户:
security:
api_key_enabled: true
api_key: "your_single_key"
# api_keys 列表为空,自动使用 api_key
此时所有请求都被视为 admin 用户,拥有所有权限。
旧工作空间迁移
对于没有 owner 字段的旧工作空间,系统会自动添加:
{
"workspace": "old-project",
"owner": "__system__",
...
}
在单 Key 模式下,所有用户都可以访问这些工作空间。在多 Key 模式下,需要管理员重新分配归属。
配置示例
多用户模式(推荐)
security:
api_key_enabled: true
api_key_header: "Token"
api_keys:
- key: "user_zhangsan_key"
user_id: "zhangsan"
name: "张三"
permissions: ["read", "write", "delete"]
- key: "user_lisi_key"
user_id: "lisi"
name: "李四"
permissions: ["read", "write"]
- key: "admin_key"
user_id: "admin"
name: "管理员"
permissions: ["read", "write", "delete", "admin"]
api_key: "" # 留空
单用户模式(向后兼容)
security:
api_key_enabled: true
api_key: "your_single_key"
api_keys: [] # 空列表
前端集成指南
连接流程
- 用户输入服务器地址和 API Key
- 调用
POST /v1/cloud/connect - 保存返回的
user信息到本地状态 - 在 UI 上显示当前用户名和权限
工作空间列表
- 调用
GET /v1/cloud/workspaces - 后端自动按当前用户的 user_id 过滤,只返回该用户自己的工作空间
- 工作空间列表中所有工作空间都属于当前用户(无需区分角色)
错误处理
- 处理 401 错误:提示用户重新输入 API Key
- 处理 403 错误:提示权限不足或无权访问该工作空间
- 处理其他错误:显示错误消息并提供重试选项
后端改动详细说明(指导客户端修改)
设计背景与目标
v2 后端改动的核心目标是:在保持向后兼容的前提下,为云端同步功能增加多用户支持,使小团队(5-20 人)可以共享同一台服务器,每个用户有独立的身份、工作空间归属和基本权限控制。
设计原则
- 向后兼容:单 API Key 模式仍然可用,旧客户端无需修改即可正常工作
- 最小改动:尽量复用现有 API 结构,减少前端改动量
- 接口文档先行:所有接口变更形成文档,便于前后端同步开发
- 渐进式升级:客户端可以分阶段适配,先适配核心功能
后端架构改动概览
┌─────────────────────────────────────────────────────────────────┐
│ 客户端 (X-AnyLabeling) │
│ - sync_api.py: HTTP 请求层 │
│ - sync_manager.py: 业务逻辑层 │
│ - cloud_sync_widget.py: UI 层 │
└──────────────────────────┬──────────────────────────────────────┘
│ HTTP (Token header)
┌──────────────────────────▼──────────────────────────────────────┐
│ 服务端 API 层 │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ APIKeyMiddleware (middleware.py) │ │
│ │ - 支持多 API Key 映射 │ │
│ │ - 验证后注入 user_id / user_name / permissions 到 state │ │
│ │ - 向后兼容:单 Key 自动映射为 admin 用户 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ cloud.py (API 端点) │ │
│ │ - 所有端点新增权限检查 │ │
│ │ - connect 返回用户信息 │ │
│ │ - list_workspaces 按用户过滤 │ │
│ │ - create_workspace 自动设置 owner │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ deps.py (权限检查工具) │ │
│ │ - check_workspace_access: 检查工作空间访问权限 │ │
│ │ - check_workspace_owner: 检查工作空间所有者 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ users.py (用户 API) │ │
│ │ - GET /v1/users/me: 获取当前用户信息 │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ cloud_storage.py (存储层) │ │
│ │ - 工作空间配置新增 owner 字段 │ │
│ │ - list_workspaces 支持 user_id 过滤 │ │
│ │ - create_workspace 需要 owner 参数 │ │
│ │ - 存储路径改为 {user_id}/{workspace}/{filename} │ │
│ │ - 旧工作空间自动迁移(owner 设为 __system__) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ audit_log.py (审计日志) │ │
│ │ - 记录关键操作到 MinIO audit bucket │ │
│ │ - 客户端无感知,后端内部记录 │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
后端改动文件清单
| 文件 | 改动类型 | 改动内容 |
|---|---|---|
app/core/config.py |
修改 | 新增 APIKeyConfig 类,SecurityConfig 新增 api_keys 列表 |
app/core/middleware.py |
修改 | APIKeyMiddleware 支持多 Key 验证,注入用户信息到 request.state |
app/services/cloud_storage.py |
修改 | 工作空间配置新增 owner,存储路径改为用户级隔离 |
app/api/deps.py |
新增 | 权限检查工具函数 |
app/api/users.py |
新增 | GET /v1/users/me 端点 |
app/api/cloud.py |
修改 | 所有端点添加权限检查,connect 返回用户信息,传递 user_id 给存储层 |
app/services/audit_log.py |
新增 | 审计日志服务 |
app/main.py |
修改 | 注册 users router,初始化 AuditLogger |
configs/server.yaml |
修改 | 新增多 API Key 配置示例 |
核心设计逻辑
1. 多 API Key 认证机制
设计思路:每个 API Key 对应一个用户,Key 中携带用户身份和权限信息。服务端通过中间件统一验证,将用户信息注入到请求上下文中,后续 API 处理函数直接从上下文获取。
配置结构:
security:
api_key_enabled: true
api_keys:
- key: "user_zhangsan_key" # API Key 值
user_id: "zhangsan" # 用户唯一标识
name: "张三" # 用户显示名称
permissions: ["read", "write", "delete"] # 权限列表
expires_at: "2027-01-01T00:00:00+00:00" # 可选过期时间
向后兼容:当 api_keys 列表为空但 api_key 不为空时,自动创建一个默认 admin 用户,所有请求都视为 admin。
客户端影响:
- 连接时
POST /v1/cloud/connect的响应中新增user字段 - 客户端可以解析并显示当前用户信息
- 旧客户端不解析
user字段也不会出错
2. 工作空间归属与数据隔离
设计思路:每个工作空间有一个明确的 owner(创建者),工作空间完全私有,只有 owner 能访问。list_workspaces 接口自动按当前用户过滤,只返回该用户自己的工作空间。存储路径从 {workspace}/{filename} 改为 {user_id}/{workspace}/{filename},实现用户级数据隔离。
工作空间配置结构:
{
"workspace": "project-a",
"owner": "zhangsan", // 归属者 user_id
"local_path": "/data/project-a",
"display_name": "Project A",
"description": "标注项目 A",
"created_at": "2026-06-23T10:00:00+00:00",
"updated_at": "2026-06-23T10:30:00+00:00"
}
过滤逻辑:
- 如果
user_id == owner:返回该工作空间 - 否则:不返回该工作空间
- 如果
api_key_enabled=false(兼容模式):返回所有工作空间
旧工作空间迁移:没有 owner 字段的旧工作空间,自动设置 owner = "__system__"。
客户端影响:
- 工作空间列表响应新增
owner字段 - 工作空间完全私有,列表中只显示当前用户自己的工作空间
- 无需区分角色(不再有 owner/shared 角色区分)
3. 权限控制机制
设计思路:权限分为两层——基础权限(API Key 配置的 permissions 列表)和工作空间访问权限(是否为 owner)。两层都通过才算有权限。
权限检查流程:
请求进入
│
▼
APIKeyMiddleware 验证 Key
│ 无效 → 401 UNAUTHORIZED
▼
注入 user_id / permissions 到 request.state
│
▼
API 处理函数
│
├─ 检查基础权限(permissions 列表是否包含所需权限)
│ │ 不包含 → 403 FORBIDDEN
│ ▼
├─ 检查工作空间访问权限(是否为 owner)
│ │ 不是 → 403 WORKSPACE_ACCESS_DENIED
│ ▼
└─ 执行业务逻辑
特殊规则:
admin权限绕过所有检查- 当
api_key_enabled=false时,跳过所有权限检查(request.state中没有user_id) - 工作空间不存在时,权限检查放行,交给后续业务逻辑返回 NOT_FOUND
各端点权限映射:
| 端点 | 基础权限 | 额外检查 |
|---|---|---|
POST /v1/cloud/connect |
无 | 无 |
POST /v1/cloud/disconnect |
无 | 无 |
GET /v1/users/me |
无 | 无 |
GET /v1/cloud/workspaces |
read | 按用户过滤 |
POST /v1/cloud/workspaces |
write | 无 |
PUT /v1/cloud/workspaces/{ws} |
write | owner 或 admin |
DELETE /v1/cloud/workspaces/{ws} |
delete | owner 或 admin |
GET /v1/cloud/workspaces/{ws}/files |
read | 工作空间访问(owner) |
POST /v1/cloud/workspaces/{ws}/upload |
write | 工作空间访问(owner) |
GET /v1/cloud/workspaces/{ws}/download/{file} |
read | 工作空间访问(owner) |
DELETE /v1/cloud/workspaces/{ws}/files/{file} |
delete | 工作空间访问(owner) |
GET /v1/cloud/workspaces/{ws}/checksum/{file} |
read | 工作空间访问(owner) |
POST /v1/cloud/workspaces/resolve |
read | 无 |
客户端影响:
- 所有文件操作端点可能新增 403 错误
- 客户端需要处理
FORBIDDEN和WORKSPACE_ACCESS_DENIED错误码 - 建议显示友好的权限提示
客户端修改指南
阶段 1:核心适配(必须)
以下修改确保客户端能在新后端下正常工作:
1.1 sync_api.py 修改
连接接口响应解析:
# 旧代码
def connect(self, server_url, api_key):
response = requests.post(f"{server_url}/v1/cloud/connect", headers={"Token": api_key})
data = response.json()
if data["success"]:
self._connected = True
# 旧代码到此结束
# 新代码
def connect(self, server_url, api_key):
response = requests.post(f"{server_url}/v1/cloud/connect", headers={"Token": api_key})
data = response.json()
if data["success"]:
self._connected = True
# 新增:解析用户信息
user_info = data["data"].get("user", {})
self._current_user = {
"user_id": user_info.get("user_id", ""),
"name": user_info.get("name", ""),
"permissions": user_info.get("permissions", []),
}
工作空间列表响应解析:
# 旧代码
def list_workspaces(self):
response = requests.get(f"{self._server_url}/v1/cloud/workspaces", headers=self._headers)
data = response.json()
if data["success"]:
return data["data"] # 列表中只有 workspace, local_path, display_name 等字段
# 新代码
def list_workspaces(self):
response = requests.get(f"{self._server_url}/v1/cloud/workspaces", headers=self._headers)
data = response.json()
if data["success"]:
workspaces = data["data"]
for ws in workspaces:
# 新增字段:owner
ws["owner"] = ws.get("owner", "")
return workspaces
新增用户信息接口:
def get_current_user(self):
"""获取当前用户信息。"""
response = requests.get(f"{self._server_url}/v1/users/me", headers=self._headers)
data = response.json()
if data["success"]:
return data["data"]
return None
1.2 sync_manager.py 修改
# 新增用户信息保存
class CloudSyncManager:
def __init__(self):
self._current_user = None # 新增
def connect(self, server_url, api_key):
# ... 现有连接逻辑 ...
# 连接成功后保存用户信息
self._current_user = self._api.get_current_user()
# 或者从 connect 响应中获取
@property
def current_user(self):
return self._current_user
1.3 cloud_sync_widget.py 修改
显示当前用户:
def _update_connection_ui(self):
"""连接成功后更新 UI。"""
user = self._manager.current_user
if user:
# 在标题栏或状态栏显示用户名
self._user_label.setText(f"用户: {user.get('name', user.get('user_id', ''))}")
# 可选:显示权限信息
permissions = user.get("permissions", [])
self._permissions_label.setText(f"权限: {', '.join(permissions)}")
工作空间列表适配:
def _populate_workspace_list(self, workspaces):
"""填充工作空间列表。"""
self._workspace_combo.clear()
for ws in workspaces:
display_name = ws.get("display_name", ws["workspace"])
owner = ws.get("owner", "")
# 显示归属信息(可选)
if owner:
label = f"{display_name} (归属: {owner})"
else:
label = display_name
self._workspace_combo.addItem(label, ws)
# 所有工作空间都属于当前用户,删除按钮始终可见
current_ws = self._get_current_workspace()
if current_ws:
self._delete_workspace_btn.setVisible(True)
1.4 错误处理适配
def _handle_error(self, error_response):
"""统一错误处理。"""
error = error_response.get("error", {})
code = error.get("code", "")
message = error.get("message", "")
if code == "UNAUTHORIZED":
# API Key 无效,提示重新输入
self._show_error_dialog("认证失败", "API Key 无效,请重新输入")
self._disconnect()
elif code == "API_KEY_EXPIRED":
self._show_error_dialog("Key 已过期", "API Key 已过期,请联系管理员更新")
self._disconnect()
elif code == "FORBIDDEN":
# 权限不足
self._show_error_dialog("权限不足", f"您没有执行此操作的权限\n{message}")
elif code == "WORKSPACE_ACCESS_DENIED":
# 无权访问工作空间
self._show_error_dialog(
"无权访问",
f"您没有访问此工作空间的权限\n{message}"
)
else:
# 其他错误
self._show_error_dialog("操作失败", message)
客户端改动清单汇总
| 文件 | 优先级 | 改动内容 |
|---|---|---|
sync_api.py |
必须 | 解析 connect 响应中的 user 字段 |
sync_api.py |
必须 | 解析 workspaces 响应中的 owner 字段 |
sync_api.py |
必须 | 处理 403 错误码(FORBIDDEN, WORKSPACE_ACCESS_DENIED) |
sync_api.py |
可选 | 新增 get_current_user() 方法 |
sync_manager.py |
必须 | 保存当前用户信息 |
cloud_sync_widget.py |
必须 | 显示当前用户名 |
cloud_sync_widget.py |
必须 | 显示工作空间归属者信息(可选) |
兼容性说明
| 场景 | 客户端行为 | 服务端行为 |
|---|---|---|
| 旧客户端 + 旧服务端 | 正常工作 | 正常 |
| 旧客户端 + 新服务端(单 Key) | 正常工作 | 自动注入 admin 用户,权限检查跳过 |
| 旧客户端 + 新服务端(多 Key) | 正常工作,但看不到用户信息 | 正常验证,user 字段被旧客户端忽略 |
| 新客户端 + 旧服务端 | 正常工作 | user 字段不存在,get() 返回空值 |
| 新客户端 + 新服务端 | 完整功能 | 完整功能 |
关键结论:新旧客户端都可以与新旧服务端正常配合工作。新客户端在连接旧服务端时,
user字段不存在但不会报错(使用get()安全获取)。旧客户端在连接新服务端时,新增字段被忽略,不影响原有功能。
版本历史
v2 (2026-06-23)
- 新增多用户支持
- 新增工作空间归属与数据隔离(存储路径改为
{user_id}/{workspace}/{filename}) - 新增权限控制(read/write/delete/admin)
- 新增审计日志
- 新增
GET /v1/users/me端点 POST /v1/cloud/connect响应新增user字段GET /v1/cloud/workspaces响应新增owner字段- 移除分享功能(工作空间完全私有,只有 owner 能访问)
v1 (2026-06-20)
- 初始版本
- 基础工作空间管理
- 文件上传/下载/删除
- 单 API Key 认证