# 函数依赖库安装 PRD


## 关联设计


- Design: [沙箱集成计划设计](../../design/features/sandbox_integration_plan.md)

## 背景

### 当前现状
执行工厂（Execution Factory）支持通过沙箱环境执行用户编写的 Python 函数算子。目前的沙箱环境仅包含基础镜像中预置的有限标准库和常用库。

### 痛点与问题
1. **依赖缺失导致运行失败**：用户在编写业务逻辑时，经常需要使用第三方库（如 `pandas` 进行数据处理，`requests` 进行网络请求等）。如果这些库未预置，代码执行将直接报错（`ImportError`）。
2. **无法动态扩展**：目前缺乏机制让用户在运行时或定义时指定所需的额外依赖，导致沙箱能力受限，无法满足复杂业务场景。
3. **内网/特定源需求**：在企业级环境或特定网络环境下，用户可能需要从内部搭建的 PyPI 镜像源拉取依赖，而当前系统不支持自定义安装源。

### 结论
需要通过本需求实现“函数级动态依赖安装”能力，允许用户定义函数所需的依赖列表及安装源，由系统在执行前自动完成环境准备。

## 目标

1. **支持依赖配置**：允许用户在创建/编辑函数算子时，配置 Python 依赖列表（包名及版本）和 PyPI 安装源（Index URL）。
2. **自动化安装**：在沙箱执行代码前，系统能够识别元数据中的依赖配置，并自动在沙箱会话中完成依赖安装。
3. **版本辅助**：提供查询 PyPI 包版本的能力，辅助前端用户准确选择可用的依赖版本。
4. **兼容性**：确保未配置依赖的旧有函数能继续正常运行；支持公共执行和内部调用两种链路。

## 非目标

1. **多语言支持**：本期仅支持 Python 语言的依赖安装，暂不涉及 Node.js、Go 等其他语言环境。
2. **复杂依赖治理**：不支持依赖冲突的自动解决（完全依赖 `pip` 的解析机制）；不支持复杂的依赖树可视化。
3. **私有源认证**：暂不支持需要用户名/密码认证的私有 PyPI 仓库，仅支持公开或免密访问的镜像源。
4. **依赖源格式**：版本查询辅助功能仅支持提供 `/pypi/{package}/json` JSON API 的镜像源（如 PyPI 官方、清华 TUNA 等）。对于仅提供 HTML 索引的源（如阿里云、腾讯云），**不支持手动输入版本号**，即无法指定特定版本依赖。
5. **依赖缓存优化**：本期不重点优化依赖下载的缓存机制，每次 Session 重建可能需要重新下载（依赖沙箱层的实现）。



## 用户与场景

### 目标用户
- **数据开发工程师**：在数据处理流程中编写自定义 Python 脚本，需要使用 `pandas`、`numpy` 等数据分析库。
- **算法工程师**：集成机器学习模型推理逻辑，需要依赖 `scikit-learn`、`torch` 等特定版本的算法库。
- **业务逻辑开发者**：调用外部服务，需要 `requests` 或特定 SDK。

### 核心场景
1. **场景一：公网依赖安装**
   用户在编辑器中编写数据清洗函数，发现原生成环境缺少 `dateutil` 库。用户在“依赖库配置”面板中添加依赖 `python-dateutil>=2.8.0`。保存并点击“测试运行”，系统在沙箱中自动下载并安装该库，随后函数执行成功。

2. **场景二：企业内网环境**
   某金融客户部署在纯内网环境，无法访问公网 PyPI。用户在函数配置中指定依赖源为企业内部搭建的 Nexus 或 Artifactory 镜像（需支持 JSON API，如 `http://nexus.internal/repository/pypi-group`），并添加内部封装的加解密库 `corp-crypto==1.0.0`。执行时系统从内网源拉取包信息及文件，确保数据安全合规。

3. **场景三：版本选择辅助**
   用户不确定 `pandas` 的最新稳定版本。在依赖配置输入框输入 `pandas`，系统自动联想并列出最近的可用版本号（如 `2.0.1`, `1.5.3`），用户直接选择，避免版本号拼写错误。

## 需求范围

### 功能需求
| 模块 | 功能点 | 描述 | 优先级 |
| :--- | :--- | :--- | :--- |
| **元数据管理** | 依赖字段存储 | 支持在函数元数据中存储 `dependencies` (列表) 和 `dependencies_url` (字符串)。 | P0 |
| **前端交互** | 依赖配置面板 | 提供界面供用户添加/删除依赖包名及版本约束。 | P0 |
| | 依赖源配置 | 提供输入框配置 PyPI 源 URL，支持设置为默认值。<br> **交互提示**：在输入框附近提示 “必须使用支持 JSON API 的镜像源（如 PyPI 官方、清华源）。不支持的源（如阿里云）无法配置特定版本”。 | P1 |
| | 版本查询 | 根据输入的包名，调用后端接口（通过依赖源 JSON API）查询 PyPI 上的可用版本列表。<br> **异常提示**：若接口返回不支持或解析失败，前端应提示 “当前源不支持 JSON API，请更换镜像源”。 | P2 |
| **执行引擎** | 动态安装 | 在沙箱 Session 启动或复用时，检测并执行 `pip install` 命令。 | P0 | | 错误处理 | 依赖安装失败时仅记录错误日志，**不阻塞**后续代码执行（Best Effort 模式）。 | P1 |

### 接口边界
- **输入**：执行请求中携带 `dependencies` 数组和 `dependencies_url`。
- **输出**：执行日志中包含依赖安装的标准输出/错误流（stdout/stderr），便于用户排查安装问题。

## 验收标准

1. **元数据持久化**：
   - 创建/编辑函数算子，添加依赖 `requests==2.28.0` 和自定义源，保存后再次打开，配置回显正确。
2. **执行成功性**：
   - 编写一段引用 `requests` 的代码。
   - 未配置依赖时，执行报错 `ModuleNotFoundError`。
   - 配置依赖后，执行成功，且日志中可见 `Successfully installed requests-2.28.0`。
3. **版本辅助**：
   - 前端输入 `numpy`，能从后端获取到版本列表（基于 PyPI 数据）。
4. **异常处理**：
   - 配置不存在的包名或版本（如 `pandas==999.9.9`），依赖安装失败并记录日志，函数尝试继续执行（若代码中引用了该库则抛出 `ModuleNotFoundError`）。
   - 配置无法访问的依赖源 URL，依赖安装超时失败并记录日志，函数尝试继续执行。

## 风险与待确认项

### 风险
1. **执行延时**：依赖安装涉及网络下载和编译，会显著增加函数首次执行（或冷启动）的耗时。
   - *对策*：建议用户尽量使用预置镜像中已有的库；系统层面后续考虑 Session 级缓存或构建包含常用库的“胖镜像”。
2. **网络稳定性**：公网 PyPI 源在国内环境下可能不稳定。
   - *对策*：推荐默认配置为国内镜像源（如清华 TUNA），或通过代理访问。
3. **安全性**：用户可能通过依赖安装引入恶意包。
   - *对策*：沙箱环境本身具备网络隔离和权限控制；后续可考虑增加依赖包白名单机制。

### 待确认项
- [ ] **默认源配置**：是否需要在系统级别配置一个全局默认的 PyPI 源（覆盖 `pypi.org`），以适应纯内网部署场景。

## 附录：常见镜像源兼容性说明

以下为常见公共镜像源对 JSON API 的支持情况测试结果（截至文档更新时）：

| 镜像源 | Simple 索引地址 | JSON API 支持 | 备注 |
| :--- | :--- | :--- | :--- |
| **PyPI 官方** | `https://pypi.org/simple/` | ✅ 支持 | 标准实现 |
| **清华 TUNA** | `https://pypi.tuna.tsinghua.edu.cn/simple/` | ✅ 支持 | 完整镜像 JSON 接口 |
| **中科大 USTC** | `https://pypi.mirrors.ustc.edu.cn/simple/` | ✅ 支持 | 完整镜像 JSON 接口 |
| **阿里云** | `https://mirrors.aliyun.com/pypi/simple/` | ❌ 不支持 | 仅提供 Simple HTML 索引 |
| **腾讯云** | `https://mirrors.cloud.tencent.com/pypi/simple/` | ❌ 不支持 | 仅提供 Simple HTML 索引 |
| **华为云** | `https://repo.huaweicloud.com/repository/pypi/simple/` | ❌ 不支持 | 仅提供 Simple HTML 索引 |

> **注意**：对于不支持 JSON API 的源，仅影响前端的“版本选择辅助”功能；且由于无法校验版本有效性，系统**不支持手动输入版本号**。建议用户统一使用支持标准 JSON API 的镜像源。