skip to Main Content

I developing a Python Azure Function app and I use a Custom Package for this project. because of the custom package I build and install all dependencies in my CI/CD pipeline before making zip file and deploying it on Azure based on this documentation. my problem is when the app deployed successfully, I got an error about the Custom Package is not found when I run the app. The full error message is

Result: Failure Exception: ModuleNotFoundError: No module named ‘{custom package name}’. Cannot find module. Please check the requirements.txt file for the missing module.

I check this documentation and double check my artifact. the only thing I found based was on documentation the package name format must be ‘<package-name>-<version>-dist-info‘ but in my artifact is ‘<package-name>-<version>.dist-info‘.

Also, I try these configurations in Azure Function but it does not make a difference.

Configurations:

  • BUILD_FLAGS=UseExpressBuild

  • PYTHON_ISOLATE_WORKER_DEPENDENCIES=0

  • SCM_DO_BUILD_DURING_DEPLOYMENT=true

  • ENABLE_ORYX_BUILD=true

2

Answers


  1. ModuleNotFoundError: No module named ‘{custom package name}’. Cannot find module.

    ModuleNotFoundError occurs when your package is not listed in the requirements.txt of your Function App, If you want to install your package separately, You will have to add apt-get package-name command or pip install package-name command in the startup command section of Azure Function DevOps task seperately.

    Startup command in yaml:-

              - task: AzureFunctionApp@1
                displayName: 'Azure functions app deploy'
                inputs:
                  azureSubscription: 'xxxxxx (xxxxxx)'
                  appType: 'functionAppLinux'
                  appName: 'siliconfuncv2'
                  package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
                  startUpCommand: 'apt-get update apt-get install libgstreamer1.0-0 libunwind-dev gstreamer1.0-pulseaudio'
    

    There are two ways you can install Custom packages in your Linux Function app.

    Refer my SO answer1 where I have added the Custom packages in the Source code Folder and then added the Folder name as path in the requirements.txt while Deployment of the Web App the packages inside the Folder are added automatically. You can use same concept to Deploy custom package to your Function App.

    Refer SO answer2 where you can upload your custom packages in Github and then use this git+https://[email protected]/sid24desai/pycode.git@main url with your Github PAT token/githuborg/repository/ in your requirements.txt like below:-

    This is my requirements.txt:-

    azure-functions
    git+https://[email protected]/sid24desai/pycode.git@main
    

    My Azure Devops yaml pipeline:-

    trigger:
    - master
    
    variables:
     
      azureSubscription: 'xxxxxxxx97cb2a7'
    
      
      functionAppName: 'siliconfunc65'
    
      
      vmImageName: 'ubuntu-latest'
    
      
      workingDirectory: '$(System.DefaultWorkingDirectory)'
    
    stages:
    - stage: Build
      displayName: Build stage
    
      jobs:
      - job: Build
        displayName: Build
        pool:
          vmImage: $(vmImageName)
    
        steps:
        - bash: |
            if [ -f extensions.csproj ]
            then
                dotnet build extensions.csproj --runtime ubuntu.16.04-x64 --output ./bin
            fi
          workingDirectory: $(workingDirectory)
          displayName: 'Build extensions'
    
        - task: UsePythonVersion@0
          displayName: 'Use Python 3.6'
          inputs:
            versionSpec: 3.10 
    
        - bash: |
            pip install --target="./.python_packages/lib/site-packages" -r ./requirements.txt
          workingDirectory: $(workingDirectory)
          displayName: 'Install application dependencies'
    
        - task: ArchiveFiles@2
          displayName: 'Archive files'
          inputs:
            rootFolderOrFile: '$(workingDirectory)'
            includeRootFolder: false
            archiveType: zip
            archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
            replaceExistingArchive: true
    
        - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
          artifact: drop
    
    - stage: Deploy
      displayName: Deploy stage
      dependsOn: Build
      condition: succeeded()
    
      jobs:
      - deployment: Deploy
        displayName: Deploy
        environment: 'development'
        pool:
          vmImage: $(vmImageName)
    
        strategy:
          runOnce:
            deploy:
    
              steps:
              - task: AzureFunctionApp@1
                displayName: 'Azure functions app deploy'
                inputs:
                  azureSubscription: 'xxxxx subscription (xxxxxxxb2a7)'
                  appType: 'functionAppLinux'
                  appName: '$(functionAppName)'
                  package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
    

    enter image description here

    Additional Reference:-

    Azure Function Deployment using CI-CD pipeline Differing from VsCode Deployment – Stack Overflow My SO answer

    Login or Signup to reply.
  2. The ModuleNotFoundError generally occurs when the required Python package is not correctly installed into the directory ".python_packages/lib/site-packages". This directory should be archived together with the files of the Python function app to be a ZIP that will be deploy to Azure Function App.

    For your case, since the Python package is your custom package, it is recommended to publish the custom package into an Artifacts feed in your Azure DevOps project for use:

    1. Create a private Artifacts feed in your Azure DevOps project if you do not have one. And ensure you have added PyPI as the upstream in the feed.

      enter image description here

    2. Build and publish your custom Python package into the feed. You can set up a pipeline to do this for your package.

    3. In the pipeline to deploy your Python function app, before the task which runs the "pip install" command, add the Python pip authenticate task like as below.

      steps:
      . . .
      
      - task: PipAuthenticate@1
        displayName: 'Pip Authenticate'
        inputs:
          artifactFeeds: {Your Artifacts feed name}
      
      . . .
      
    4. Ensure you have listed the custom package into the requirements.txt file of your Python function app. And in the code of your Python function app, ensure you have set to correctly import the custom package.

    5. When running the following "pip install" command in the root directory of your Python function app, it will install your custom package from the Artifacts feed and the public packages from the PyPI upstream into the directory ".python_packages/lib/site-packages".

      pip install --target="./.python_packages/lib/site-packages" -r ./requirements.txt
      
    6. Then you can use the Archive files task to archive the directory ".python_packages/lib/site-packages" together with the files of your Python function app to be a ZIP.


    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search