星海智算开发文档
应用开发SDK 与 HTTP 参考

应用与版本操作

开发者应用、角色、版本、同版本变更、镜像导入、PKCE 和 SDK 凭据的逐操作 HTTP 参考。

本文覆盖个人开发者 owned-app 范围内的应用、角色、版本、源文件、请求、同版本变更、镜像导入和开发工具凭据。运行会话、组织目录和 AppGrant 见RuntimeSession 与应用间授权参考,HTTP 总索引见应用中心 HTTP API 参考,完整路径合同见 OpenAPI 3.1 YAML。不包含媒体生成。

1. 地址、身份和投影边界

Base URL:https://app-api.jusuanhub.com:10443。开发者控制面使用已登录浏览器会话,或由 PKCE exchange 得到、绑定 app/version 的 CLI 短期 Bearer。每个单应用操作先校验当前开发者 ownership;不存在和越权统一受控 404,不要通过错误差异枚举其它应用。请求建议带 X-Request-ID;版本创建、镜像导入和其它可重试写操作使用稳定幂等键。

平台只向开发者返回 AppProduct/AppVersion 的公开投影,不返回 Chart、namespace、ServiceAccount、内部 repository、Secret 或平台部署地址。应用目录由平台管理,开发者不能获得 Harbor、Kubernetes、Helm 或平台数据库权限。

2. 应用和角色

GET /api/v1/appstore/developer/publishers

分页读取当前个人开发者投影。可选 pagepageSize;成功 200 返回 itemstotal 等分页字段。未登录为 401,依赖不可用为 503。publisher 是平台投影身份,不是 Harbor/组织管理员身份。

GET /api/v1/appstore/developer/apps

分页读取当前账号拥有的应用。成功 200 返回应用列表和总数;分页参数为 pagepageSize。未登录/无开发者角色为 401/403

POST /api/v1/appstore/developer/apps

请求体:{publisherId,app:{id?,appKey,name,...}}id 为空时服务端生成;appKey/name/publisher ownership 必须满足 AppProduct 合同。成功 200 返回应用投影;冲突为 409,目录 provisioner 不可用为 503。目录创建失败必须补偿,不留下孤儿 ownership。

GET /api/v1/appstore/developer/apps/{appId}

读取 owned app 详情,无 body,成功 200,不存在/越权 404

GET /api/v1/appstore/developer/apps/{appId}/roles

读取应用角色定义,成功 200 返回角色数组:roleCodedisplayNamedescriptiondefinitionVersionstatus。不存在/越权 404

PUT /api/v1/appstore/developer/apps/{appId}/roles

提交完整角色数组,成功 200 返回最新定义。roleCode 不可变,definitionVersion 必须递增;非法角色/版本或 ownership 失败为 400/404。角色只作用于当前应用,不能借此赋予平台角色。

3. 版本与源文件

POST /api/v1/appstore/developer/apps/{appId}/submissions:validate

只解析和校验 AppSubmission,不创建版本。支持 JSON submission;成功 200 返回校验/解析投影,非法 submission 为 400,应用不存在/越权为 404。不得提交 artifact.verified=true 自证平台信任。

POST /api/v1/appstore/developer/apps/{appId}/versions

创建明确的新草稿版本。JSON 形态为 {submission,idempotencyKey};兼容 multipart 形态包含 submissionidempotencyKeyfile。源文件必须与规范化 submission 完全一致。成功返回新 AppVersion(通常 201/由 handler 投影),相同幂等键相同正文复用;相同键不同正文为 409;校验失败为 400,ownership 为 404

GET /api/v1/appstore/developer/apps/{appId}/versions

分页读取版本,参数 pagepageSize,成功 200 返回 itemstotal。版本状态、运行投影和当前请求由服务端生成,不由客户端拼接。

GET /api/v1/appstore/developer/apps/{appId}/versions/{versionId}

读取版本详情、源文件收据、平台识别的入口/组件/资源/镜像和当前请求。成功 200;不存在/越权 404

PUT /api/v1/appstore/developer/apps/{appId}/versions/{versionId}

编辑草稿版本的公开字段,成功 200 返回版本投影。已审核或已上架版本不能直接改线上快照,应建立同版本 change proposal;状态冲突为 409,不存在/越权为 404

DELETE /api/v1/appstore/developer/apps/{appId}/versions/{versionId}

请求删除非 active 版本,成功返回删除请求/状态投影;active 版本删除被拒绝,版本不存在/越权 404,状态冲突 409。这是 tombstone/生命周期动作,不等于物理删除数据库、对象存储、Redis 或业务数据。

源文件操作

方法与路径请求/成功响应失败与恢复
PUT .../versions/{versionId}/sourceJSON 原始 AppSubmission 或服务端定义的源更新投影;成功 200非法源 400;已上架直接修改应 409;重复提交用同一规范正文重试
POST .../versions/{versionId}/source/uploadmultipart 完整源文件;成功返回源文件收据/版本投影缺 file/解析失败 400;上传超时查询版本,不猜测是否成功
GET .../source/content认证 JSON 内联原始源内容,成功 200404;不提供匿名下载
GET .../source/download认证附件下载原始源文件,成功 200404;响应中的 URL/文件名只作展示,不作为平台存储路径

4. 版本请求与同版本变更

POST .../versions/{versionId}/requests

请求体 {kind,reason?};reason 可为空。kind 使用当前页面允许的 deletepublishunpublish 等动作。成功 200 返回 VersionRequest;相同版本同 kind 仅允许一个在途请求,冲突为 409,ownership/版本不存在 404

GET .../versions/{versionId}/requests

返回历史与最新请求及状态,成功 200,响应为 itemstotal。不要用旧 Package 列表推导版本请求。

POST .../versions/{versionId}/requests/{requestId}/cancel

撤回仍待审核请求。成功 200;已批准、已应用或不存在为 404/409。取消不删除审计。

POST .../versions/{versionId}/changes

创建或恢复同版本工作副本,成功 200 返回 request 和 proposal。它不创建第二个可见版本,也不直接改变线上快照;跨 app/version/request 绑定为 404/409

同版本 change source/image/submit

方法与路径请求/成功响应失败与恢复
POST .../changes/{requestId}/source/uploadmultipart 上传新的完整 AppSubmission;成功 200 返回 proposal/解析差异缺文件或解析失败 400;用同一 request 查询当前 proposal 后修复
GET .../changes/{requestId}/source/content内联工作副本 JSON,成功 200三元绑定不匹配统一 404
GET .../changes/{requestId}/source/download下载工作副本原文件,成功 200404;不暴露对象存储地址
POST .../changes/{requestId}/image-importsimage import 请求,成功 201 返回导入 session404 ownership/binding;下游导入失败由 image import 错误返回
POST .../changes/{requestId}/submit{reason?},成功返回 request/proposal;reason 可空无实际差异或状态不允许为 409

审核批准不会立即替换线上版本;管理员后续执行受控 apply,成功后才原子替换同一 AppVersion 快照。

5. 镜像导入

创建 session

路径为 POST /api/v1/appstore/developer/apps/{appId}/image-imports(应用级)或 POST .../versions/{versionId}/image-imports(绑定草稿),同样支持 change 路径。JSON 字段:

字段类型/要求
fileName非空文件名
sizeBytes正数;下游拒绝 <=0
sha256请求字段名;格式校验未在当前 service 证实,勿伪造摘要
archiveType空/oci 归一为 oci-archive;空/tar/docker 归一为 docker-archive;最终仅支持两种规范值
component组件标识,按 AppProject 组件绑定
displayVersion版本显示值;绑定版本时与版本事实校验
idempotencyKey用于恢复/复用;当前 service 未找到非空格式校验,客户端仍必须稳定提供

缺版本、非法 archiveType、空文件名或非正 size 为 400(上层可能包装为 502 IMAGE_IMPORT_FAILED);ownership/版本不匹配 404。成功 201 返回受控 session:imageImportIdstatuspartSizeBytespartCountuploadParts[]uploadedParts[]expiresAt,不依赖 repository/tag 等内部字段。

分片上传与完成

客户端对 session 的每个 uploadParts[].url 执行返回的 method(当前为短期 PUT),记录 ETag 和 size,再调用:

POST .../apps/{appId}/image-imports/{imageImportId}/complete

或版本/change 对应路径。请求体:{parts:[{partNumber,etag,sizeBytes?}]};成功 200 返回 imageImportId/status/imageAssetId/repository?/digest?/architecture?/sizeBytes?/importedAt? 的受控结果。完成失败为 502 IMAGE_IMPORT_FAILED;绑定版本/change proposal 失败为 409 VERSION_IMAGE_BIND_FAILEDVERSION_CHANGE_IMAGE_BIND_FAILED。断线先 GET .../{imageImportId} 查询 session 状态,再使用同一幂等事实恢复,不要用新 key 重复创建。

查询 session

GET .../apps/{appId}/image-imports/{imageImportId} 及版本变体成功 200 返回当前 session;不存在、越权或版本绑定不匹配 404。状态包括 pendinguploadingimportingcompletedfailed;失败响应可带 errorCode/errorMessage

6. PKCE 与 SDK 凭据

POST /api/v1/appstore/developer/apps/{appId}/cli-authorizations

浏览器会话批准 CLI 配对。请求字段 codeChallengeredirectUri、可选 versionIdtestAccountId。联网调试必须指定版本;testAccountId 只能来自下方该应用的授权名单,省略表示本人。它是测试授权记录 ID,不是任意用户 ID。成功 200 返回五分钟内有效、仅用一次的 authorizationCodeexpiresAt;身份缺失 401 CLI_AUTHORIZATION_IDENTITY_MISSING,app/version 不存在 404,非法参数 400 CLI_AUTHORIZATION_INVALID,测试身份不可用 403 TEST_IDENTITY_NOT_AUTHORIZED

GET /api/v1/appstore/developer/apps/{appId}/test-accounts

仅已登录且拥有该应用的开发者可读。成功 200 返回 {"items":[{"id":"授权记录ID","appId":"应用ID","accountId":"账号ID","organizationId":"组织ID","displayName":"测试经理","organizationName":"测试组织","createdAt":"ISO时间"}]}。空名单返回空数组;不返回密码、登录 session 或联系人资料。名单由超管维护,签发和实际调用时仍重新核对有效权限。

POST /api/v1/appstore/developer/cli-sessions:exchange

不需要已有浏览器登录令牌;请求体 authorizationCodecodeVerifier。成功 200 返回 accessTokenexpiresAt、绑定的 appId/appKey/appVersionId/runtimeSessionIdscopes、运行/中转/上传 base URL。配对码、verifier 错误、重放或授权已撤销为 401 CLI_AUTHORIZATION_INVALID。交换与会话落库同事务;失败不会遗留半条会话。版本级调试凭据 1 小时有效,只授予运行、任务、临时素材及应用间调用权限,不能上传镜像、提交版本、审核、上线或续期成正式会话。

POST /api/v1/appstore/developer/sdk/python/credentials

开发者控制面签发 Python/CLI 私有包索引短期凭据。成功 200 返回 tokenexpiresAtindexURL 和当前 jusp-cli/jusp-platform-sdk 稳定版本;索引未配置为 503 SDK_INDEX_NOT_CONFIGURED,包尚未发布为 503 SDK_RELEASE_NOT_READY。token 只能下载包,不能调用 Runtime。

获取 SDK 安装凭据

应用开发者使用返回的 indexURL 及短期 token 访问 /api/v1/appstore/sdk/python/simple/;GET/HEAD root、package 和 files 路径返回私有 simple index/文件,缺认证或过期为 401,未配置为 503。平台 SDK 与 CLI 的发行由平台维护,应用开发者只有安装授权。凭据和展开后的安装 URL 不写入源代码、锁文件、日志或镜像层。

本页目录