Skip to content

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
  • 错误发生在管道初始化阶段,甚至组件代码未开始执行

错误原因

该错误的根源是依赖库版本冲突:

  1. KFP 与较新版本的 urllib3 (v2.0.0+) 不兼容
  2. requests 库的最新版本不再支持旧版 urllib3 功能
  3. requests-toolbelt 等依赖间接引发了兼容性问题
  4. 问题核心是 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():
    ...

方法四:更新相关依赖

若问题由过时的 gqltwine 等库引起:

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 镜像

根本原因解析

此问题的技术根源在于:

  1. urllib3 v2.0.0+ 移除了对 contrib.appengine 模块的支持
  2. kfp<2.0.0b16kfp<1.8.21 中未处理此变更
  3. KFP 底层依赖 requests-toolbelt,而它的旧版本(v0.10.1)与 urllib3 新版本不兼容

此问题在以下版本中被修复:

  • Kubeflow Pipelines 的 PR#9323
  • KFP v2.0.0b16+ 核心代码更新

总结

解决 ImportError: cannot import name 'appengine' 的核心是处理依赖冲突,推荐操作顺序:

  1. 升级 KFP 到 v1.8.21+ 或 v2.0.0b16+
  2. 更新基础镜像到 Python 3.9+ 版本
  3. 添加显式依赖appengine-python-standard
  4. 降级冲突库urllib3==1.26.15requests-toolbelt==0.10.1
  5. 更新间接依赖:如 gqltwinepoetry

最佳实践建议

在 KFP 项目中始终使用虚拟环境并明确记录所有依赖版本,可通过 pip freeze > requirements.txt 生成依赖清单

以上方案均在实际生产环境中验证有效,选择最适合您项目的方法即可彻底解决此兼容性问题。