You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions部署Azure Python函数:已安装依赖运行时无法找到

优化Azure Python函数部署:无需打包依赖解决ModuleNotFoundError

问题核心

GitHub Actions部署Azure Python函数时,依赖包在Runner环境安装成功,但函数运行时抛出ModuleNotFoundError: No module named 'sftplib'。临时方案是将依赖打包到.python_packages目录,但会导致部署包体积暴涨、耗时增加,需要更高效的解决方法。

原因分析

原部署流程中,依赖被安装在GitHub Runner的系统Python路径中,但Azure/functions-action@v1默认仅打包当前目录的代码文件,不会将Runner中的依赖包含到部署包中。Azure函数运行环境无法访问Runner的依赖路径,因此出现模块找不到的错误。

优化解决方案

方案1:启用Azure Oryx远程构建(推荐)

利用Azure函数内置的Oryx构建工具,部署时自动读取requirements.txt并在Azure环境中安装依赖,无需本地打包。

修改后的deploy.yaml配置

steps:
  - name: Checkout
    uses: actions/checkout@v4
  - name: 'Azure Login'
    uses: azure/login@v2
    with:
      client-id: ${{ env.ARM_CLIENT_ID }}
      subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}
      tenant-id: ${{ env.ARM_TENANT_ID }}
  - name: 'Download Azure Function publishing profile'
    env:
      AZURE_SUBSCRIPTION_ID: ${{ env.ARM_SUBSCRIPTION_ID }}
      FUNCTION_APP_RESOURCE_GROUP: ${{ env.ARM_RESOURCE_GROUP_NAME }}
      FUNCTION_APP_NAME: fa-${{ env.APP_NAME }}
    run: |
      echo "FUNCTION_APP_PUB_PROFILE=$(az functionapp deployment list-publishing-profiles --subscription $AZURE_SUBSCRIPTION_ID --resource-group $FUNCTION_APP_RESOURCE_GROUP --name $FUNCTION_APP_NAME --xml)" >> $GITHUB_ENV
  - name: "Deploy function"
    uses: Azure/functions-action@v1
    with:
      app-name: fa-${{ env.APP_NAME }}
      publish-profile: ${{ env.FUNCTION_APP_PUB_PROFILE }}
      package: '.'
      enable-oryx-build: true # 强制启用Oryx远程构建

关键配置验证

  • 确保函数应用的运行时版本与代码兼容:在Azure Portal的函数应用配置 > 应用程序设置中,设置FUNCTIONS_WORKER_RUNTIME_VERSION为3.9(与你指定的Python版本一致)。
  • Oryx默认会读取根目录的requirements.txt,无需额外路径配置。

方案2:替换小众依赖包

注意到你使用的sftplib是一个版本仅为0.0.2的小众包,标准Python生态中通常使用paramiko实现SFTP功能(维护更活跃、兼容性更好)。

  1. 修改requirements.txt:
    azure-functions
    matplotlib
    numpy
    paramiko # 替换sftplib
    pandas
    python-dateutil
    azure-identity
    azure-keyvault-secrets
    Office365-REST-Python-Client
    
  2. 更新函数代码中的导入:
    # 替换import sftplib为
    import paramiko
    # 使用paramiko的SFTP客户端示例
    transport = paramiko.Transport(("hostname", 22))
    transport.connect(username="user", password="pass")
    sftp = paramiko.SFTPClient.from_transport(transport)
    

这个改动不仅能避免小众包的兼容性问题,还能让Oryx构建更顺畅。

方案3:使用虚拟环境优化本地构建(可选)

如果需要在本地验证依赖,但不想打包到部署包,可以利用虚拟环境隔离依赖,同时让部署工具忽略虚拟环境目录:

steps:
  - name: Checkout
    uses: actions/checkout@v4
  - name: 'Azure Login'
    uses: azure/login@v2
    with:
      client-id: ${{ env.ARM_CLIENT_ID }}
      subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}
      tenant-id: ${{ env.ARM_TENANT_ID }}
  - name: Set up Python
    uses: actions/setup-python@v4
    with:
      python-version: '3.9.20'
  - name: Install dependencies in virtual env
    run: |
      python -m venv .venv
      source .venv/bin/activate
      pip install --upgrade pip
      pip install -r requirements.txt
  - name: 'Download Azure Function publishing profile'
    env:
      AZURE_SUBSCRIPTION_ID: ${{ env.ARM_SUBSCRIPTION_ID }}
      FUNCTION_APP_RESOURCE_GROUP: ${{ env.ARM_RESOURCE_GROUP_NAME }}
      FUNCTION_APP_NAME: fa-${{ env.APP_NAME }}
    run: |
      echo "FUNCTION_APP_PUB_PROFILE=$(az functionapp deployment list-publishing-profiles --subscription $AZURE_SUBSCRIPTION_ID --resource-group $FUNCTION_APP_RESOURCE_GROUP --name $FUNCTION_APP_NAME --xml)" >> $GITHUB_ENV
  - name: "Deploy function"
    uses: Azure/functions-action@v1
    with:
      app-name: fa-${{ env.APP_NAME }}
      publish-profile: ${{ env.FUNCTION_APP_PUB_PROFILE }}
      package: '.'
      # 让部署工具跳过虚拟环境目录
      exclude-files: '.venv/'

注:此方案仍需依赖Oryx远程安装依赖,虚拟环境仅用于本地验证,不会被打包部署。

总结

  • 优先选择方案1+方案2:启用Oryx远程构建减少部署包体积,替换小众依赖包提升稳定性。
  • 无需再将依赖安装到.python_packages目录,部署速度会大幅提升,同时避免依赖冗余。

内容的提问来源于stack exchange,提问作者mbieren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:52:02