feat: 本地 uv 与托管 Python 环境管理
- 新增 uv 管理:只认程序目录副本或指定路径,支持从科大镜像下载并按 sha256 校验 - uv 环境变量(UV_*)可配置,默认相对程序目录(python / uv-cache),同时注入 uv 调用与任务进程 - 新增托管虚拟环境与 Python 版本管理:用 uv 下载解释器、预创建环境、查看已装包 - 新建任务保存时自动创建 .venv,运行期只校验、不再自动装依赖;镜像只在装包时使用 - 前端改为顶部品牌栏 + 三栏工作台,uv / 镜像源 / 虚拟环境各自独立弹窗 - 发布包构建后去掉工作区继承的低完整性标签 - 修复调度集成测试并发时误取 skipped 运行的问题
This commit is contained in:
+532
-1
@@ -89,6 +89,145 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/python/envs": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"python-envs"
|
||||
],
|
||||
"operationId": "list_envs",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Managed virtual environments",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ManagedEnvSummary"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"python-envs"
|
||||
],
|
||||
"operationId": "create_env",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CreateManagedEnvRequest"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Virtual environment created",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ManagedEnvSummary"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Validation or uv failure",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/python/envs/{name}": {
|
||||
"delete": {
|
||||
"tags": [
|
||||
"python-envs"
|
||||
],
|
||||
"operationId": "delete_env",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"description": "Environment name",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "Environment deleted"
|
||||
},
|
||||
"404": {
|
||||
"description": "Environment not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/python/envs/{name}/packages": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"python-envs"
|
||||
],
|
||||
"operationId": "list_env_packages",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"description": "Environment name",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Installed packages",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ManagedEnvPackage"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Environment not found",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/python/mirrors": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -343,6 +482,80 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/python/pythons": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"python-envs"
|
||||
],
|
||||
"operationId": "list_pythons",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Pythons downloaded by uv into the platform directory",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ManagedPython"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "uv unavailable",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"python-envs"
|
||||
],
|
||||
"operationId": "install_python",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/InstallPythonRequest"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Python downloaded; returns the installed list",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ManagedPython"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Validation or uv failure",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/python/venv": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@@ -1160,6 +1373,94 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uv": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"uv"
|
||||
],
|
||||
"operationId": "get_uv_settings",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "uv settings and detected executables",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UvSettingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": [
|
||||
"uv"
|
||||
],
|
||||
"operationId": "update_uv_settings",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UpdateUvSettingsRequest"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "uv settings saved",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UvSettingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Validation failed",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uv/download": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"uv"
|
||||
],
|
||||
"operationId": "download_uv",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "uv downloaded from the mirror and switched to it",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UvSettingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Download, verification or install failed",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@@ -1170,6 +1471,33 @@
|
||||
"skip"
|
||||
]
|
||||
},
|
||||
"CreateManagedEnvRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "目录名,`[A-Za-z0-9._-]`,也是任务里引用它的标识"
|
||||
},
|
||||
"packages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "预装包,每行一个,例如 `numpy==2.1.0`"
|
||||
},
|
||||
"python_version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"description": "创建时使用的 Python 版本,例如 `3.11`;留空由 uv 决定"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CreatePythonMirrorRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -1398,6 +1726,19 @@
|
||||
"POST"
|
||||
]
|
||||
},
|
||||
"InstallPythonRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "要下载的版本,例如 `3.12` 或 `3.12.4`"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"InterpreterKind": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -1427,6 +1768,60 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ManagedEnvPackage": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ManagedEnvSummary": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "虚拟环境根目录的绝对路径"
|
||||
},
|
||||
"python_version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"description": "取自 `pyvenv.cfg` 的 `version_info`"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ManagedPython": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"version",
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "uv 下载到平台目录下的解释器路径"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PythonMirrorResponse": {
|
||||
"type": "object",
|
||||
"description": "一个 Python 包索引镜像(pip / uv)。",
|
||||
@@ -2000,6 +2395,142 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"UpdateUvSettingsRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"source"
|
||||
],
|
||||
"properties": {
|
||||
"custom_path": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"extra_env": {
|
||||
"type": "object",
|
||||
"description": "额外注入给 uv 的环境变量;只允许 `UV_` 前缀",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/components/schemas/UvSource"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"UvCandidate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"source",
|
||||
"path",
|
||||
"available"
|
||||
],
|
||||
"properties": {
|
||||
"available": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/components/schemas/UvSource"
|
||||
},
|
||||
"version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"UvSettingsResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"source",
|
||||
"extra_env",
|
||||
"managed_dir",
|
||||
"python_dir",
|
||||
"cache_dir",
|
||||
"env_defaults",
|
||||
"candidates"
|
||||
],
|
||||
"properties": {
|
||||
"cache_dir": {
|
||||
"type": "string",
|
||||
"description": "实际生效的 uv 缓存目录(绝对路径)"
|
||||
},
|
||||
"candidates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/UvCandidate"
|
||||
},
|
||||
"description": "各来源的探测结果"
|
||||
},
|
||||
"custom_path": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"env_defaults": {
|
||||
"type": "object",
|
||||
"description": "两个路径变量的默认值(相对程序目录),页面用来显示「默认」那一行",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"executable": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"description": "当前设置指向的 uv;不可用时 `version` 为空"
|
||||
},
|
||||
"extra_env": {
|
||||
"type": "object",
|
||||
"description": "额外注入给 uv 的环境变量;只允许 `UV_` 前缀",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"managed_dir": {
|
||||
"type": "string",
|
||||
"description": "程序目录下的 uv 目录"
|
||||
},
|
||||
"python_dir": {
|
||||
"type": "string",
|
||||
"description": "实际生效的 Python 存放目录(绝对路径,相对值按程序目录解析)"
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/components/schemas/UvSource"
|
||||
},
|
||||
"version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"UvSource": {
|
||||
"type": "string",
|
||||
"description": "uv 从哪里来。只用平台自己认的副本,不读系统 PATH:PATH 上的版本和可用性\n会随启动方式变化,不适合当调度器的隐式依赖。",
|
||||
"enum": [
|
||||
"managed",
|
||||
"custom"
|
||||
]
|
||||
},
|
||||
"VenvProbeRequest": {
|
||||
"type": "object",
|
||||
"description": "编辑器在用户填写工作目录时发起的探测请求。",
|
||||
@@ -2041,7 +2572,7 @@
|
||||
"properties": {
|
||||
"can_create": {
|
||||
"type": "boolean",
|
||||
"description": "没有虚拟环境时,是否具备用 uv 创建的条件"
|
||||
"description": "没有虚拟环境时,是否可以用 uv 创建(有 uv 即可,纯标准库脚本会得到一个空环境)"
|
||||
},
|
||||
"display_path": {
|
||||
"type": [
|
||||
|
||||
Reference in New Issue
Block a user