使用诗歌来在Azure Functions管道中安装依赖项。

huangapple go评论67阅读模式
英文:

Using poetry to install dependencies in Azure Functions pipeline

问题

目标
使用poetry和pyproject.toml文件部署一个包括函数应用的Python项目。指定的模块应该可以被Python文件访问。

背景
我的项目托管在Azure DevOps存储库中。通过Azure YAML管道,它使用poetry install进行“构建”,创建一个包含所有依赖项的子文件夹.venv,并打包成一个zip文件。该存档被存储为一个构件,并在部署步骤中拉取到虚拟机上,我在那里解压它,以便.venv文件夹再次存在。
我原本期望通过使用poetry env use .venv/bin/python.exesource .venv/bin/activate来激活虚拟环境就足够了。这两个步骤都有效并且可以激活虚拟环境,但虚拟环境不会保持激活状态,Python脚本中无法访问模块。在本地运行poetry install就足够了,而且效果非常好。

挑战
A)poetry将依赖项安装到与可访问位置不同的位置
通常的解决方法是使用pip install并使用参数--target将依赖项放在文件夹./.python_packages/lib/site-packages中。不幸的是,poetry没有这样的功能。

B)激活虚拟环境只在流水线的单个步骤中有效,并且之后会丢失
使用source venv/bin/activate激活poetry环境运行得很好,作为激活和pip list结合的步骤示例:

- bash: |
    source .venv/bin/activate
    pip list

--> 列出了使用poetry install安装的所有依赖项

- bash: |
    source .venv/bin/activate
- bash: |
    pip list

--> 仅列出Azure基本虚拟环境的依赖项(即没有pandas)

C)因此,运行函数应用会导致异常:ModuleNotFoundError:找不到模块'pandas'

问题
如何在Azure流水线中使用poetry,以便Python脚本可以访问已安装的依赖项?

英文:

Goal
Deploy a python project including a function app using poetry and the pyproject.toml file. The specified modules should be accessible by the python files.

Background
My project is hosted in a Azure DevOps repository. With an Azure YAML Pipeline it is "built" with poetry install, creating a sub-folder .venv with all dependencies, and bundled into a zip file. The archive is stored as an artifact and pulled onto the VM in the deploy step, where I extract it, so that the .venv folder is present again.
My expectation was that activating the venv with poetry env use .venv/bin/python.exe or source .venv/bin/activate was sufficient. Both steps work and do activate the venv, but it does not stick and modules are not accessible in python scripts. Locally, running poetry install is sufficient and works very well.

Challenges
A) poetry installs dependencies in a different location than what is accessible
Usually the solution is to use pip install with the argument --target to place dependencies in the folder ./.python_packages/lib/site-packages. poetry does not have a functionality like this, unfortunately.

B) activating virtual environments is only valid in a single steps of pipelines and gets lost afterwards
With source venv/bin/activate activating the poetry environment works fine, as a combined step with activation and pip list demonstrates:

- bash: |
    source .venv/bin/activate
    pip list

--> lists all dependecies that were installed using poetry install

- bash: |
    source .venv/bin/activate
- bash: |
    pip list

--> lists only dependecies of the Azure base virtual environment (i.e. no pandas)

C) as consequence, running the function app leads to Exception: ModuleNotFoundError: No module named 'pandas'

Question
How can I use poetry in Azure pipelines, so that installed dependencies are accessible by python scripts?

答案1

得分: 0

您可以使用下面的YAML脚本来使用poetry安装依赖并运行函数。

我的存储库:-

使用诗歌来在Azure Functions管道中安装依赖项。

我的pyproject.toml代码:-

[tool.poetry]
name = "your-project"
version = "0.1.0"
description = "Your project description"
authors = ["Your Name <your-email@example.com>"]

[tool.poetry.dependencies]
python = "^3.9"
pandas = "^1.3.0"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

代码:-

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.x'
    addToPath: true

- script: |
    pip install poetry
    poetry install
    poetry add azure-functions    

  displayName: '使用Poetry安装依赖'

- script: |
    source $HOME/.poetry/env
    source .venv/bin/activate
    poetry run python HttpTrigger1/__init__.py    
  displayName: '运行Azure函数'

输出:-

使用诗歌来在Azure Functions管道中安装依赖项。

使用诗歌来在Azure Functions管道中安装依赖项。

英文:

You can make use of below YAML script to install dependencies using poetry and run function.

My Repository:-

使用诗歌来在Azure Functions管道中安装依赖项。

My pyproject.toml code:-

[tool.poetry]
name = "your-project"
version = "0.1.0"
description = "Your project description"
authors = ["Your Name <your-email@example.com>"]

[tool.poetry.dependencies]
python = "^3.9"
pandas = "^1.3.0"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

Code:-

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.x'
    addToPath: true

- script: |
    pip install poetry
    poetry install
    poetry add azure-functions    

  displayName: 'Install dependencies with Poetry'

- script: |
    source $HOME/.poetry/env
    source .venv/bin/activate
    poetry run python HttpTrigger1/__init__.py    
  displayName: 'Run Azure Function'

Output:-

使用诗歌来在Azure Functions管道中安装依赖项。

使用诗歌来在Azure Functions管道中安装依赖项。

答案2

得分: 0

以下是您提供的文本的中文翻译:

解决此问题涉及两个部分。

  1. 确保在 Azure 流水线期间正确安装依赖项到虚拟机。

  2. 在正确的位置安装依赖项,以便 Python 脚本可以实际访问它们。

对于第一部分,我最终没有在我的 pipeline.yml 中使用构建和依赖项步骤,而是只使用一个部署步骤。这样只初始化一个虚拟机,我只需要安装一次 poetry。

对于第二部分,将其导出到 requirements.txt 并使用 pip --target 进行安装是在我的情况下使其正确运行的唯一方法。请注意,有一个 poetry 扩展旨在解决这个问题(https://github.com/python-poetry/poetry-plugin-bundle)。

以下是包含所有相关部分的流水线:

trigger:
- main

variables:
  pythonVersion: 3.10
  azureSubscription: <YOUR_SUBSCRIPTION_CODE>
  functionAppName: <YOUR_FUNCTION_APP_NAME>
  vmImageName: 'ubuntu-latest'
  workingDirectory: '$(System.DefaultWorkingDirectory)'
jobs:
- deployment: Deploy
  environment: <YOUR_ENV_NAME>
  pool:
    vmImage: $(vmImageName)
  strategy:
    runOnce:
      deploy:
        steps:
        - checkout: self
        - task: UsePythonVersion@0
          inputs:
            versionSpec: $(pythonVersion)
        - bash: |
            curl -sSL https://install.python-poetry.org | python -
            export PATH=$PATH:$HOME/.poetry/bin            
          displayName: 'Install poetry'
        - bash: |
            poetry lock --no-update
            poetry install --no-root --without dev,local            
          displayName: 'Update lock file and install dependencies'
        - bash: |
                        poetry env use /home/vsts/work/1/s/.venv/bin/python
          displayName: 'Activate virtual environment'
        - bash: |
            poetry export -f requirements.txt --output requirements.txt
            pip install --target="./.python_packages/lib/site-packages" -r ./requirements.txt            
          displayName: 'Export poetry dependencies and install'
        - task: ArchiveFiles@2
          inputs:
            rootFolderOrFile: '$(workingDirectory)'
            includeRootFolder: false
            archiveType: zip
            archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
            replaceExistingArchive: true
          displayName: 'Archive files'
        - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
          artifact: drop
          displayName: 'Publish artifact'
        - task: AzureFunctionApp@2
          inputs:
            azureSubscription: '$(azureSubscription)'
            appType: functionAppLinux
            appName: $(functionAppName)
            package: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
            deploymentMethod: 'auto'
          displayName: 'Deploy Azure function app'

如果您有关于详细信息和特定步骤的任何问题,请随时提问。

英文:

Solving the issue involved two parts.

  1. Making sure the dependencies get installed to the correct VM during the Azure pipeline.

  2. Getting the dependencies installed at the correct location, so that Python scripts can actually access them.

For 1., I ended up not using a build and dependency step in my pipeline.yml, but to only use a single step, with a deployment step. That way only one VM is initialized and I only have to install poetry once.

For 2., exporting to a requirements.txt and installing with pip --target was the only way to get it to run correctly in my situation. Note that there is a poetry extension that aims to solve this (https://github.com/python-poetry/poetry-plugin-bundle).

Here is the pipeline with all relevant parts:

trigger:
- main

variables:
  pythonVersion: 3.10
  azureSubscription: &lt;YOUR_SUBSCRIPTION_CODE&gt;
  functionAppName: &lt;YOUR_FUNCTION_APP_NAME&gt;
  vmImageName: &#39;ubuntu-latest&#39;
  workingDirectory: &#39;$(System.DefaultWorkingDirectory)&#39;
jobs:
- deployment: Deploy
  environment: &lt;YOUR_ENV_NAME&gt;
  pool:
    vmImage: $(vmImageName)
  strategy:
    runOnce:
      deploy:
        steps:
        - checkout: self
        - task: UsePythonVersion@0
          inputs:
            versionSpec: $(pythonVersion)
        - bash: |
            curl -sSL https://install.python-poetry.org | python -
            export PATH=$PATH:$HOME/.poetry/bin
          displayName: &#39;Install poetry&#39;
        - bash: |
            poetry lock --no-update
            poetry install --no-root --without dev,local
          displayName: &#39;Update lock file and install dependencies&#39;
        - bash: |
            poetry env use /home/vsts/work/1/s/.venv/bin/python
          displayName: &#39;Activate virtual environment&#39;
        - bash: |
            poetry export -f requirements.txt --output requirements.txt
            pip install --target=&quot;./.python_packages/lib/site-packages&quot; -r ./requirements.txt
          displayName: &#39;Export poetry dependencies and install&#39;
        - task: ArchiveFiles@2
          inputs:
            rootFolderOrFile: &#39;$(workingDirectory)&#39;
            includeRootFolder: false
            archiveType: zip
            archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
            replaceExistingArchive: true
          displayName: &#39;Archive files&#39;
        - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
          artifact: drop
          displayName: &#39;Publish artifact&#39;
        - task: AzureFunctionApp@2
          inputs:
            azureSubscription: &#39;$(azureSubscription)&#39;
            appType: functionAppLinux
            appName: $(functionAppName)
            package: &#39;$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip&#39;
            deploymentMethod: &#39;auto&#39;
          displayName: &#39;Deploy Azure function app&#39;

Feel free to ask any questions you have about details and particular steps.

huangapple
  • 本文由 发表于 2023年6月29日 16:56:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579548.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定