はじめに
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'」というエラーが出ます。
IBM Cloud Functions の Python で外部パッケージを利用するには?
こちらのドキュメントにあるように、ibmfunctions の docker image を使って、自分で zip にパッケージ化する必要があります。
手順
Docker イメージダウンロード
docker pull ibmfunctions/action-python-v3.7
requirements.txt の準備
zip にパッケージ化するための作業ディレクトリを準備し、import
したい外部パッケージを requirements.txt
にリストで書いておきます。
slapi-test
└── requirements.txt
SoftLayer
virtualenv の作成
以下のコマンドで、 virtualenv
ディレクトリが作成されます。
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"
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
slapi-test
├── requirements.txt
└── virtualenv
IBM Cloud Functions で実行する Python コードの準備
#
#
# 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 }
slapi-test
├── requirements.txt
├── virtualenv
└── __main__.py
Python コードを仮想環境と一緒に .zip ファイル形式でパッケージ化する
IBM Cloud Functions にデプロイするための zip ファイルを作成します。
zip -r slapi-test.zip virtualenv __main__.py
slapi-test
├── requirements.txt
├── virtualenv
├── __main__.py
└── slapi-test.zip
IBM Cloud Functions にデプロイするための準備
ibmcloud
コマンドを使って、ターゲットとなるリソースグループ、リージョン、ネームスペースを設定します。
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 ファイルをデプロイして、アクションを作成します。
ibmcloud fn action create slapi-test slapi-test.zip --kind python:3.7
ibmcloud fn action list
GUI 画面でもデプロイされたことが確認できます。
パラメータの設定
コード内には記述したくない認証情報について、以下のパラメータを設定します。
コード内でのパラメータの取り出し方は __main__.py
を確認してください。
ibmcloud fn action update slapi-test --param SLUSERNAME "xxx" --param SLAPIKEY "yyy"
ibmcloud fn action get slapi-test parameters
テスト
以下のコマンドで応答の確認ができます。
ibmcloud fn action invoke --result slapi-test
{
"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 ラインタイムに標準で含まれていない任意のパッケージを利用することができます。
今回作成したアクションは、トリガーと組み合わせることで任意のタイミングでの実行が可能です。
サーバーレスな関数をぜひご活用ください。