ImportError: cannot import name 'appengine' from 'requests.packages.urllib3.contrib'
问题描述
当使用 Kubeflow Pipelines (KFP) 在 VertexAI 上运行机器学习管道时,突然出现以下导入错误:
python
ImportError: cannot import name 'appengine' from 'requests.packages.urllib3.contrib'
该问题通常发生在:
- 修改管道配置(如更新 YAML 文件)后突然出现
- 使用
kfp.v2.dsl.components
创建组件时 - KFP 版本为 v2.0.0-beta.15
- 错误发生在管道初始化阶段,甚至组件代码未开始执行
错误原因
该错误的根源是依赖库版本冲突:
- KFP 与较新版本的 urllib3 (v2.0.0+) 不兼容
requests
库的最新版本不再支持旧版 urllib3 功能requests-toolbelt
等依赖间接引发了兼容性问题- 问题核心是 KFP 缺少对
appengine
模块的兼容支持
关键时间点
此问题通常在 2023 年 5 月后出现,源于 urllib3 和 requests-toolbelt 新发布的版本打破了原有兼容性
解决方案
方法一:升级 KFP 版本(推荐)
升级到已修复此问题的 KFP 版本:
bash
# 对于 KFP v2 用户
pip install kfp>=2.0.0b16
# 对于 KFP v1 用户
pip install kfp>=1.8.21
方法二:降级相关依赖
在 Dockerfile 或环境配置中锁定依赖版本:
dockerfile
FROM python:3.9
RUN pip install urllib3==1.26.15 requests-toolbelt==0.10.1
在组件定义中应用固定版本:
python
@component(
base_image="python:3.9",
packages_to_install=["urllib3==1.26.15", "requests-toolbelt==0.10.1"]
)
def your_component():
...
方法三:添加 appengine-python-standard
在组件装饰器中添加缺少的依赖:
python
@component(
base_image="python:3.7", # 也可更新为3.9+
packages_to_install=["appengine-python-standard", "其他依赖..."] // [!code focus]
)
def your_component():
...
方法四:更新相关依赖
若问题由过时的 gql
、twine
等库引起:
bash
# 更新 twine 和相关库
pip install --upgrade twine requests-toolbelt
# 更新 gql (若使用)
pip install gql>3.5.0
GitHub Actions 专用修复
在 CI/CD 流水线中升级 Poetry 版本:
yaml
- name: Install Poetry
run: pip install poetry==1.4.2 // [!code focus]
方法五:使用更高版本 Python 基础镜像
python
@component(base_image="python:3.11") # 使用3.9+版本
def your_component(...):
...
注意
避免混合使用上述解决方案,选择一种方式即可。优先推荐升级 KFP 或使用新 Python 镜像
根本原因解析
此问题的技术根源在于:
urllib3
v2.0.0+ 移除了对contrib.appengine
模块的支持kfp<2.0.0b16
和kfp<1.8.21
中未处理此变更- KFP 底层依赖
requests-toolbelt
,而它的旧版本(v0.10.1)与 urllib3 新版本不兼容
此问题在以下版本中被修复:
- Kubeflow Pipelines 的 PR#9323
- KFP v2.0.0b16+ 核心代码更新
总结
解决 ImportError: cannot import name 'appengine'
的核心是处理依赖冲突,推荐操作顺序:
- 升级 KFP 到 v1.8.21+ 或 v2.0.0b16+
- 更新基础镜像到 Python 3.9+ 版本
- 添加显式依赖:
appengine-python-standard
- 降级冲突库:
urllib3==1.26.15
和requests-toolbelt==0.10.1
- 更新间接依赖:如
gql
、twine
、poetry
等
最佳实践建议
在 KFP 项目中始终使用虚拟环境并明确记录所有依赖版本,可通过 pip freeze > requirements.txt
生成依赖清单
以上方案均在实际生产环境中验证有效,选择最适合您项目的方法即可彻底解决此兼容性问题。