Search code examples
pythonazureazure-functionsdb2

i can't install the ibm_db python package in my azure function


I'm trying to access a IBM DB2 instance from an azure function, but as soon as i add the ibm_db package to my requirement.txt and publish the function, when trying to install this package it gives me the error described below

  ERROR: Command errored out with exit status 1:
   command: /tmp/oryx/platforms/python/3.8.6/bin/python3.8 /tmp/oryx/platforms/python/3.8.6/lib/python3.8/site-packages/pip/_vendor/pep517/in_process/_in_process.py get_requires_for_build_wheel /tmp/tmpohdx5kca
       cwd: /tmp/pip-install-ygqaie_9/ibm-db_ae91bb58811d4da4a16cf48bfdca7e17
  Complete output (8 lines):
  Detected 64-bit Python
  Detected platform = linux, uname = x86_64
  Downloading https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/linuxx64_odbc_cli.tar.gz
   Downloading DSDriver from url =  https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/linuxx64_odbc_cli.tar.gz
  Pre-requisite check [gcc] : Passed

  No Python.h header file detected.
  Please install python-devel or python3-devel as instructed in "https://github.com/ibmdb/python-ibmdb/blob/master/README.md#KnownIssues" and continue with the installation

The goal is to be capable to access DB2 regardless the language. I tried with node and .NET but they also have their own issues with this package (or i may have done something wrong)

Any idea how to to avoid this error?

Thanks!

The goal is to reach DB2 and run SQL statements but i didn't even have the chance to install a package that allowed me to do this. I tried by change the language of my function to node and .NET but they have issues as well


Solution

  • The problem is that several online sources which describe the installation procedure for the ibm_db module do not specify clearly enough that the python3-dev dependency is an OS package. Adding python3-dev to requirements.txt simply will not work.

    python3-dev must be installed as an OS package. In Linux you can accomplish that with:

    apt-get install --yes python3-dev
    

    The particular issue with Azure Functions is that the default Azure Function image does not include the python3-dev package. The only way to get ibm_db working is to create an Azure Function using a custom Docker image so you can install the python3-dev and another dependency you will come across, namely gcc. A useful tutorial on this topic can be found here.

    Also note the Python version you are using since the Azure Function runtime (current version as of this writing is 4.x) only supports GA (Python 3.10, 3.9, 3.8, 3.7), see this page for supported versions.

    Given the above, an example Dockerfile for the Azure Function runtime version 4.x and Python 3.10 would be:

    # To enable ssh & remote debugging on app service change the base image to the one below
    # FROM mcr.microsoft.com/azure-functions/python:4-python3.10-appservice
    FROM mcr.microsoft.com/azure-functions/python:4-python3.10
    
    ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
        AzureFunctionsJobHost__Logging__Console__IsEnabled=true
    
    RUN apt-get update \
        && apt-get install --yes gcc \
        && apt-get install --yes python3-dev
    
    COPY requirements.txt /
    RUN pip install -r /requirements.txt
    
    # This last line and any additional Dockerfile content will depend on your function
    COPY . /home/site/wwwroot
    

    It is also recommended that you include the specific versions of Python packages that your application is using, so, at the time of this writing, an Azure Function requirements.txt file using the ibm_db driver would need to contain:

    azure-functions==1.15.0
    ibm-db==3.1.4
    

    One final note for Mac users with an Apple silicon (M1, M2, etc.) processor - ensure that you run your terminal with Rosetta so that you can compile the Docker image for the amd64 architecture to ensure it will run in Azure. To confirm that your terminal is running Rosetta, run the arch command. You should get i386 as a response. Building an amd64 Docker image would then be done with:

    docker build --platform linux/amd64 --tag <YOUR_DOCKER_ID>/<YOUR_IMAGE_NAME> .