azure-functions-python-worker: Exception: ModuleNotFoundError: No module named 'requests'

I’m trying to run a simple python script via an Azure Function. When I run the function locally, it works fine. But when I deploy the function to Azure using Azure Pipelines, I encounter the ModuleNotFoundError for requests even though I’ve included the request in requirements.txt. I saw some other people ran into this issue such as 626, I tried the solutions in these posts but haven’t got anything to work.

I suspect that the packages installed in .python_packages/lib/site-packages are not being read in the Azure Portal or becuase I am using Linux & Python in “Consumption Plan”.

Investigative information

Please provide the following:

  • Function App name: TakeRateFunction

Repro steps

Provide the steps required to reproduce the problem:

I use the following YAML in my Azure Pipelines Build:

# Python Function App to Linux on Azure
# Build a Python function app and deploy it to Azure as a Linux function app.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/python

trigger:
- master

variables:
  # Azure Resource Manager connection created during pipeline creation. Replace 'xxx' with actual subscription and functionappname
  azureSubscription: 'xxxx'

  # Function app name
  functionAppName: 'xxxx'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

  # Working Directory
  workingDirectory: '$(System.DefaultWorkingDirectory)/my_repo'


stages:
- stage: Build
  displayName: Build stage

  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)

    steps:
    - task: UsePythonVersion@0
      displayName: 'Use Python 3.6'
      inputs:
        versionSpec: 3.6 # Functions V2 supports Python 3.6 as of today
    - bash: |
        if [ -f extensions.csproj ]
        then
          dotnet build extensions.csproj --output ./bin
        fi
        pip install --target $(System.DefaultWorkingDirectory)/my_repo/.python_packages/lib/site-packages -r requirements.txt

    - 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: 'production'
    pool:
      vmImage: $(vmImageName)

    strategy:
      runOnce:
        deploy:

          steps:
          - task: AzureFunctionApp@1
            displayName: 'Azure functions app deploy'
            inputs:
              azureSubscription: '$(azureSubscription)'
              appType: functionAppLinux
              appName: $(functionAppName)
              package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'

Expected behavior

Provide a description of the expected behavior.

Actual behavior

Azure Function is able to find requests locally but not on Portal.I get the following error in the portal:

Result: Failure
Exception: ModuleNotFoundError: No module named 'requests'
Stack:   File "/azure-functions-host/workers/python/3.6/LINUX/X64/azure_functions_worker/dispatcher.py", line 242, in _handle__function_load_request
    func_request.metadata.entry_point)
  File "/azure-functions-host/workers/python/3.6/LINUX/X64/azure_functions_worker/loader.py", line 66, in load_function
    mod = importlib.import_module(fullmodname)
  File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/home/site/wwwroot/TakeRateFunction/update.py", line 13, in <module>
    from ..modules.take_rate_wrapper.take_rate import TakeRate
  File "/home/site/wwwroot/modules/take_rate_wrapper/take_rate.py", line 6, in <module>
    import requests

Known workarounds

I have tried Azure CLI instead of Azure Pipelines YAML and still getting the same error.

Contents of the requirements.txt file:

Provide the requirements.txt file to help us find out module related issues.

Related information

Tried these links but none of them helped so far

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 29 (3 by maintainers)

Most upvoted comments

Had the same issue, can confirm that changing pip install -r requirements.txt line in my YAML file to pip install --target="$(workingDirectory)/.python_packages/lib/site-packages" -r requirements.txt resolved it.

I have lost few hours with this issue and I have found that this happens when you select Python 3.7/3.8 during the function creation in Azure and later you are trying to integrate the Azure Pipeline which supports Python 3.6 only. So this is not a bug, but it’s really difficult to realize the root cause if you have created your function a time ago. I guess that Python 3.6 Azure Pipeline has different directory structure than Azure Function for Python 3.7/3.8 expects so site packages are not found. Maybe some note in the docs or check for the version of the target function would help further investigators.

Thanks @cmasch. You were spot on. I missed this gem, FUNCTIONS_WORKER_RUNTIME in my terraform app_settings definition, but I had it in my local.settings.json and skimmed right past it in the terraform docs. For anyone else that may stumble upon this, this worked for me:

resource "azurerm_app_service_plan" "myPlan" {
  name                = "plan"
  location            = data.azurerm_resource_group.myGroup.location
  resource_group_name = data.azurerm_resource_group.myGroup.name
  kind                = "Linux"
  reserved            = true

  sku {
    tier = "Dynamic"
    size = "Y1"
  }
}

resource "azurerm_function_app" "myApp" {
  name                       = "app"
  location                   = data.azurerm_resource_group.myGroup.location
  resource_group_name        = data.azurerm_resource_group.myGroup.name
  app_service_plan_id        = azurerm_app_service_plan.myPlan.id
  storage_account_name       = azurerm_storage_account.myStorageAccount.name
  storage_account_access_key = azurerm_storage_account.myStorageAccount.primary_access_key
  os_type                    = "linux"
  version                    = "~4"

  app_settings = {
    EVENTHUB_CONNECTION_STRING = azurerm_eventhub_namespace_authorization_rule.myListener.primary_connection_string
    FUNCTIONS_WORKER_RUNTIME   = "python"
  }

  site_config {
    linux_fx_version = "python|3.8"
  }
}
func azure functionapp publish <app> --subscription <sub> --build remote

And there was a very clear difference in the build output:

Command: oryx build /tmp/zipdeploy/extracted -o /home/site/wwwroot --platform python --platform-version 3.8 -p packagedir=.python_packages/lib/site-packages
Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx
You can report issues at https://github.com/Microsoft/Oryx/issues

Oryx Version: 0.2.20201015.1, Commit: 1a35fbce482b20b71290f3a837a3469803ce4b44, ReleaseTagName: 20201015.1

Build Operation ID: |TXpug4loFB4=.998f55b_
Repository Commit : d1906ea77cca4f2d87244a0cf1398b03

Detecting platforms...
Detected following platforms:
  python: 3.8.12
Version '3.8.12' of platform 'python' is not installed. Generating script to install it...

Hi Joey, do you use Terraform for deploying the function app? I guess so 😃 Could you pls try out to create a function app via the portal with Python as runtime? If you publish the app again, do you get some outputs about pip and installing dependencies?

If you use Terraform, could you provide the Terraform code and the provider version? Maybe the Python runtime is not specified in the app settings (see azurerm_function_app). That should fix the issue: https://docs.microsoft.com/en-us/azure/azure-functions/functions-app-settings#functions_worker_runtime

Best Christopher

Although i think the docs might be worded a bit differently: From what it says now it seems like including deps. in the .python_packages dir is only relevant when you want to include dependencies that are not publicly available (e.g not on pip), but all of my dependencies are on pip.

This is not a hack. If for some reason you are not able to use Remote Build then this is the right way to include your dependencies. https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-python#custom-dependencies

Sure, i made pip install to $(wd)/.python_packages. This makes the packages available to anything running from wd.

Nevermind, fixed this by making pip install to WD/.python_packages…

@stefanlenoach I published my functions with a remote build option with this command:

func azure functionapp publish my_package --build remote

In my requirements.txt I had a package called sqlalchemy-snowflake. Now, the pip version used by Azure’s Dockerfile is probably using an older version of pip. In my local, I am using pip 20.0.2 while the Azure’s remote build is using 19.2.3. During my build it even gives me the following error:

You are using pip version 19.2.3, however version 20.0.2 is available.

So I removed sqlalchemy-snowflake and it removed the error for me. So change your local pip version to 19.2.3 and see if you still get the same error.If yes, then you know it is pip version issue.

Sorry for some reason, it didn’t publish. Here is the requirements.txt

appdirs==1.4.3
asn1crypto==1.3.0
attrs==19.3.0
autoflake==1.3.1
azure-common==1.1.24
azure-storage-blob==2.1.0
azure-storage-common==2.1.0
black==19.10b0
boto3==1.11.17
botocore==1.14.17
certifi==2019.11.28
cffi==1.13.2
chardet==3.0.4
Click==7.0
coverage==5.0.3
cryptography==2.8
docutils==0.15.2
idna==2.8
ijson==2.6.1
importlib-metadata==1.5.0
isort==4.3.21
jmespath==0.9.5
more-itertools==8.2.0
numpy==1.18.1
oscrypto==1.2.0
packaging==20.1
pandas==1.0.1
pathspec==0.7.0
pluggy==0.13.1
py==1.8.1
pycparser==2.19
pycryptodomex==3.9.7
pyflakes==2.1.1
PyJWT==1.7.1
pyOpenSSL==19.1.0
pyparsing==2.4.6
pytest==5.3.5
python-dateutil==2.8.1
pytz==2019.3
regex==2020.1.8
requests==2.22.0
s3transfer==0.3.3
six==1.14.0
snowflake-connector-python==2.2.1
snowflake-sqlalchemy==1.2.1
SQLAlchemy==1.3.13
toml==0.10.0
typed-ast==1.4.1
urllib3==1.25.8
wcwidth==0.1.8
zipp==2.1.0