LoginSignup
8
3

More than 3 years have passed since last update.

IBM Cloud Functions の Python で外部パッケージを利用する

Last updated at Posted at 2019-09-28

はじめに

IBM Cloud Functions の Python ラインタイムに標準でインストールされているパッケージはこちらにドキュメントがあります。
https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-runtimes&locale=ja#python-

IBM Cloud Functions の Python コード内で、ここに含まれていない "SoftLayer" パッケージを import しようと試みても、「ModuleNotFoundError: No module named 'SoftLayer'」というエラーが出ます。

Kobito.bklrgg.png

IBM Cloud Functions の Python で外部パッケージを利用するには?

こちらのドキュメントにあるように、ibmfunctions の docker image を使って、自分で zip にパッケージ化する必要があります。

Python コードを仮想環境と一緒に .zip ファイル形式でパッケージ化する

手順

Docker イメージダウンロード

exec_command1
docker pull ibmfunctions/action-python-v3.7

requirements.txt の準備

zip にパッケージ化するための作業ディレクトリを準備し、import したい外部パッケージを requirements.txt にリストで書いておきます。

current_directory1
slapi-test
└── requirements.txt
requirements.txt
SoftLayer

virtualenv の作成

以下のコマンドで、 virtualenv ディレクトリが作成されます。

exec_command2
docker run --rm -v "$PWD:/tmp" ibmfunctions/action-python-v3.7 bash -c "cd /tmp && virtualenv virtualenv && source virtualenv/bin/activate && pip install -r requirements.txt"
result2
Using base prefix '/usr/local'
New python executable in /tmp/virtualenv/bin/python
Installing setuptools, pip, wheel...
done.
Collecting SoftLayer (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/54/d4/f8c70fd500f68e2cdcc6d9afb271528633398b10cdf36d94d57d4fc3ebcc/SoftLayer-5.8.0-py2.py3-none-any.whl (514kB)
Collecting prompt-toolkit>=2 (from SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/f7/a7/9b1dd14ef45345f186ef69d175bdd2491c40ab1dfa4b2b3e4352df719ed7/prompt_toolkit-2.0.9-py3-none-any.whl (337kB)
Collecting pygments>=2.0.0 (from SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/5c/73/1dfa428150e3ccb0fa3e68db406e5be48698f2a979ccbcec795f28f44048/Pygments-2.4.2-py2.py3-none-any.whl (883kB)
Collecting six>=1.7.0 (from SoftLayer->-r requirements.txt (line 1))
  Using cached https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
Collecting urllib3>=1.24 (from SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/e0/da/55f51ea951e1b7c63a579c09dd7db825bb730ec1fe9c0180fc77bfb31448/urllib3-1.25.6-py2.py3-none-any.whl (125kB)
Collecting ptable>=0.9.2 (from SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/ab/b3/b54301811173ca94119eb474634f120a49cd370f257d1aae5a4abaf12729/PTable-0.9.2.tar.gz
Collecting click>=7 (from SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
Collecting requests>=2.20.0 (from SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl (57kB)
Collecting wcwidth (from prompt-toolkit>=2->SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7e/9f/526a6947247599b084ee5232e4f9190a38f398d7300d866af3ab571a5bfe/wcwidth-0.1.7-py2.py3-none-any.whl
Collecting idna<2.9,>=2.5 (from requests>=2.20.0->SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl (58kB)
Collecting certifi>=2017.4.17 (from requests>=2.20.0->SoftLayer->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/18/b0/8146a4f8dd402f60744fa380bc73ca47303cccf8b9190fd16a827281eac2/certifi-2019.9.11-py2.py3-none-any.whl (154kB)
Collecting chardet<3.1.0,>=3.0.2 (from requests>=2.20.0->SoftLayer->-r requirements.txt (line 1))
  Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Building wheels for collected packages: ptable
  Building wheel for ptable (setup.py): started
  Building wheel for ptable (setup.py): finished with status 'done'
  Created wheel for ptable: filename=PTable-0.9.2-cp37-none-any.whl size=22906 sha256=e852c92019f189224d5fc78ea1b5105290e9ddba0252d80a0e1ab92aec9ad76c
  Stored in directory: /root/.cache/pip/wheels/22/cc/2e/55980bfe86393df3e9896146a01f6802978d09d7ebcba5ea56
Successfully built ptable
Installing collected packages: six, wcwidth, prompt-toolkit, pygments, urllib3, ptable, click, idna, certifi, chardet, requests, SoftLayer
Successfully installed SoftLayer-5.8.0 certifi-2019.9.11 chardet-3.0.4 click-7.0 idna-2.8 prompt-toolkit-2.0.9 ptable-0.9.2 pygments-2.4.2 requests-2.22.0 six-1.12.0 urllib3-1.25.6 wcwidth-0.1.7
current_directory2
slapi-test
├── requirements.txt
└── virtualenv

IBM Cloud Functions で実行する Python コードの準備

__main__.py
#
#
# main() このアクションの実行時に呼び出されます
#
# @param Cloud Functions アクションは 1 つのパラメーターを受け入れます。このパラメーターは JSON オブジェクトでなければなりません。
#
# @return このアクションの出力。この出力は、JSON オブジェクトでなければなりません。
#

import sys
import SoftLayer

def main(dict):
    SLUSERNAME = dict['SLUSERNAME']
    SLAPIKEY = dict['SLAPIKEY']
    client = SoftLayer.create_client_from_env(username=SLUSERNAME,
                                              api_key=SLAPIKEY,
                                              endpoint_url="https://api.softlayer.com/xmlrpc/v3.1")
    pkgType = client['Product_Package_Type'].getAllObjects(mask='id,name')                                          
    return { 'message': pkgType }
current_directory3
slapi-test
├── requirements.txt
├── virtualenv
└── __main__.py

Python コードを仮想環境と一緒に .zip ファイル形式でパッケージ化する

IBM Cloud Functions にデプロイするための zip ファイルを作成します。

exec_command3
zip -r slapi-test.zip virtualenv __main__.py
current_directory4
slapi-test
├── requirements.txt
├── virtualenv
├── __main__.py
└── slapi-test.zip

IBM Cloud Functions にデプロイするための準備

ibmcloud コマンドを使って、ターゲットとなるリソースグループ、リージョン、ネームスペースを設定します。

exec_command4
ibmcloud login
ibmcloud target -g khayama -r jp-tok
ibmcloud fn namespace create khayama-fn
ibmcloud fn namespace target khayama-fn

IBM Cloud Functions にデプロイ

zip ファイルをデプロイして、アクションを作成します。

exec_command5
ibmcloud fn action create slapi-test slapi-test.zip --kind python:3.7
ibmcloud fn action list

GUI 画面でもデプロイされたことが確認できます。

Kobito.sYP6ZE.png

パラメータの設定

コード内には記述したくない認証情報について、以下のパラメータを設定します。
コード内でのパラメータの取り出し方は __main__.py を確認してください。

exec_command6
ibmcloud fn action update slapi-test --param SLUSERNAME "xxx" --param SLAPIKEY "yyy"
ibmcloud fn action get slapi-test parameters

テスト

以下のコマンドで応答の確認ができます。

exec_command7
ibmcloud fn action invoke --result slapi-test
result7
{
    "message": [
        {
            "id": 8,
            "name": "Additional Services"
        },
        {
            "id": 446,
            "name": "Additional Services Enterprise Storage"
        },
        {
            "id": 208,
            "name": "Additional Services Iscsi Storage"
        },
        {
            "id": 207,
            "name": "Additional Services Network Attached Storage"
        },
        {
            "id": 243,
            "name": "Additional Services Performance Storage"
        },
        {
            "id": 650,
            "name": "Additional Services Portable IP Addresses"
        },
        {
            "id": 162,
            "name": "Additional Services Portable Storage"
        },
        {
            "id": 248,
            "name": "Additional Services Static IP Addresses"
        },
        {
            "id": 82,
            "name": "Additional services application delivery appliance"
        },
        {
            "id": 807,
            "name": "Additional services authentication services"
        },
        {
            "id": 204,
            "name": "Additional services cdn"
        },
        {
            "id": 232,
            "name": "Additional services domain name services"
        },
        {
            "id": 84,
            "name": "Additional services load balancer"
        },
        {
            "id": 206,
            "name": "Additional services message queue"
        },
        {
            "id": 203,
            "name": "Additional services object storage"
        },
        {
            "id": 205,
            "name": "Additional services ssl certificate"
        },
        {
            "id": 42,
            "name": "Bare Metal Gateway"
        },
        {
            "id": 209,
            "name": "Bare Metal Power Server"
        },
        {
            "id": 6,
            "name": "Bare Metal Server"
        },
        {
            "id": 691,
            "name": "Bare Metal Server for Service"
        },
        {
            "id": 695,
            "name": "Bare Metal Server for VPC"
        },
        {
            "id": 202,
            "name": "Bare metal cpu fast provision"
        },
        {
            "id": 491,
            "name": "Bluemix Service"
        },
        {
            "id": 497,
            "name": "CDN Addon"
        },
        {
            "id": 18,
            "name": "Colocation"
        },
        {
            "id": 674,
            "name": "Content Delivery Network Service"
        },
        {
            "id": 20,
            "name": "Control Panels for VPS"
        },
        {
            "id": 499,
            "name": "Dedicated Host"
        },
        {
            "id": 677,
            "name": "External Service Addons"
        },
        {
            "id": 493,
            "name": "Firewall"
        },
        {
            "id": 672,
            "name": "Firewall Appliance"
        },
        {
            "id": 122,
            "name": "Gateway Resource Group"
        },
        {
            "id": 494,
            "name": "Global IP Addresses"
        },
        {
            "id": 654,
            "name": "Hardware Security Module"
        },
        {
            "id": 662,
            "name": "Load Balancer As A Service"
        },
        {
            "id": 668,
            "name": "Mass Data Migration Service"
        },
        {
            "id": 238,
            "name": "Monitoring"
        },
        {
            "id": 667,
            "name": "Network Interconnect"
        },
        {
            "id": 240,
            "name": "Network Message Delivery"
        },
        {
            "id": 495,
            "name": "Network VLAN"
        },
        {
            "id": 673,
            "name": "Network VLAN for Service"
        },
        {
            "id": 658,
            "name": "New Customer Setup"
        },
        {
            "id": 663,
            "name": "Private Cloud"
        },
        {
            "id": 694,
            "name": "Reserved Capacity"
        },
        {
            "id": 2,
            "name": "Server"
        },
        {
            "id": 675,
            "name": "Service Addons"
        },
        {
            "id": 438,
            "name": "Software License"
        },
        {
            "id": 10,
            "name": "Solution"
        },
        {
            "id": 12,
            "name": "Solution Server"
        },
        {
            "id": 16,
            "name": "Specialty Server"
        },
        {
            "id": 659,
            "name": "Storage as a Service"
        },
        {
            "id": 484,
            "name": "Support"
        },
        {
            "id": 22,
            "name": "VHD Import"
        },
        {
            "id": 492,
            "name": "Virtual Datacenter"
        },
        {
            "id": 4,
            "name": "Virtual Server Instance"
        },
        {
            "id": 666,
            "name": "Virtual Server Instance for Service"
        },
        {
            "id": 693,
            "name": "Virtual Server Instance for VPC"
        }
    ]
}

さいごに

このような手順を踏むことで IBM Cloud Functions の Python ラインタイムに標準で含まれていない任意のパッケージを利用することができます。
今回作成したアクションは、トリガーと組み合わせることで任意のタイミングでの実行が可能です。
サーバーレスな関数をぜひご活用ください。

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3