概要
このエントリでは、OSSのFaaSサーバである「Fn Project」を使い、Pythonの関数を動かすパターンを扱います。
下図のようなPythonによる掛け算の関数をFnのサーバにデプロイして動かします。
想定読者
- Fn ProjectでのPythonプログラムまだ自分で動かしていない方
- 「Fn Projectを使ってJavaScriptで書いたfunctionをNodeで動かしてみる」のPython版に興味がある方
準備
Fn Projectを動かすまでのところは、別エントリ「OCIのMicro InstanceでCentOSにFn Projectのサーバをインストールしてみる」を参照ください。
このエントリでは、筆者はOCIのMicro Instanceの上で作業しています。
Pythonでfunctionを動かす
作業の基本的な流れは、Introduction to Fn with Pythonに書いてあるものに従っています。
Fn上のアプリ
別のエントリ「Fn Projectを使ってJavaScriptで書いたfunctionをNodeで動かしてみる」で、「fn create app」で、fn上に「calc-fn-app」アプリを作ってあるものにFunctionを追加する形をとります。
登録
/multiplyという位置にPythonで関数を一つ作るため、「fn init」を実行します。
$ fn init --runtime python --trigger http multiply
Creating function at: ./multiply
Function boilerplate generated.
func.yaml created.
下記のような3つのファイルができています。
$ ls
func.py func.yaml requirements.txt
コードを変更
下記のような、入力値のleftとrightを掛けて返すような関数に書き換えます。
import io
import json
from decimal import *
from fdk import response
def handler(ctx, data: io.BytesIO=None):
value = Decimal('NaN')
try:
body = json.loads(data.getvalue())
left = Decimal(body.get('left'))
right = Decimal(body.get('right'))
value = left * right
except (Exception, ValueError) as ex:
print(str(ex))
return response.Response(
ctx, response_data=json.dumps(
{"result": str(value)}),
headers={"Content-Type": "application/json"}
)
アプリデプロイします。「-w」で作業ディレクトリを指定して、登録しています。
fn --verbose deploy --app calc-fn-app --local -w /home/opc/calc-fn-app/multiply
初回実行時には、以下のような流れとなるようです。
$ fn --verbose deploy --app calc-fn-app --local -w /home/opc/calc-fn-app/multiply
Deploying multiply to app: calc-fn-app
Bumped to version 0.0.2
Building image fndemouser/multiply:0.0.2
FN_REGISTRY: fndemouser
Current Context: default
Sending build context to Docker daemon 6.144kB
Step 1/12 : FROM fnproject/python:3.6-dev as build-stage
3.6-dev: Pulling from fnproject/python
80369df48736: Pull complete
aaba0609d543: Pull complete
a97b990f94a5: Pull complete
af4a941e5376: Pull complete
709c35256bb6: Pull complete
3c3deb8445b4: Pull complete
Digest: sha256:8ac8c28a68fd0442b9ddcdf6a41f30230482d72d1024cafca06c9f1ac0bd821c
Status: Downloaded newer image for fnproject/python:3.6-dev
---> c5dbe9a0175b
Step 2/12 : WORKDIR /function
---> Running in f7aaa0e58f7a
Removing intermediate container f7aaa0e58f7a
---> 697f68e69e7c
Step 3/12 : ADD requirements.txt /function/
---> c4472f73a275
Step 4/12 : RUN pip3 install --target /python/ --no-cache --no-cache-dir -r requirements.txt && rm -fr ~/.cache/pip /tmp* requirements.txt func.yaml Dockerfile .venv
---> Running in 4f758b74080b
Collecting fdk
Downloading https://files.pythonhosted.org/packages/1d/b8/41b81bf76766f7e810627728647a8076626070a6e1d01a18a8ed16bd3d3f/fdk-0.1.12-py3-none-any.whl (46kB)
Collecting iso8601==0.1.12
Downloading https://files.pythonhosted.org/packages/ef/57/7162609dab394d38bbc7077b7ba0a6f10fb09d8b7701ea56fa1edc0c4345/iso8601-0.1.12-py2.py3-none-any.whl
Collecting httptools>=0.0.10
Downloading https://files.pythonhosted.org/packages/1b/03/215969db11abe8741e9c266a4cbe803a372bd86dd35fa0084c4df6d4bd00/httptools-0.0.13.tar.gz (104kB)
Collecting pbr!=2.1.0,>=2.0.0
Downloading https://files.pythonhosted.org/packages/7a/db/a968fd7beb9fe06901c1841cb25c9ccb666ca1b9a19b114d1bbedf1126fc/pbr-5.4.4-py2.py3-none-any.whl (110kB)
Collecting pytest==4.0.1
Downloading https://files.pythonhosted.org/packages/81/27/d4302e4e00497448081120f65029696070806bc8e649b83f644de006d710/pytest-4.0.1-py2.py3-none-any.whl (217kB)
Collecting pytest-asyncio==0.9.0
Downloading https://files.pythonhosted.org/packages/33/7f/2ed9f460872ebcc62d30afad167673ca10df36ff56a6f6df2f1d3671adc8/pytest_asyncio-0.9.0-py3-none-any.whl
Collecting py>=1.5.0
Downloading https://files.pythonhosted.org/packages/99/8d/21e1767c009211a62a8e3067280bfce76e89c9f876180308515942304d2d/py-1.8.1-py2.py3-none-any.whl (83kB)
Collecting pluggy>=0.7
Downloading https://files.pythonhosted.org/packages/a0/28/85c7aa31b80d150b772fbe4a229487bc6644da9ccb7e427dd8cc60cb8a62/pluggy-0.13.1-py2.py3-none-any.whl
Collecting attrs>=17.4.0
Downloading https://files.pythonhosted.org/packages/a2/db/4313ab3be961f7a763066401fb77f7748373b6094076ae2bda2806988af6/attrs-19.3.0-py2.py3-none-any.whl
Collecting setuptools
Downloading https://files.pythonhosted.org/packages/a7/c5/6c1acea1b4ea88b86b03280f3fde1efa04fefecd4e7d2af13e602661cde4/setuptools-45.1.0-py3-none-any.whl (583kB)
Collecting more-itertools>=4.0.0
Downloading https://files.pythonhosted.org/packages/72/96/4297306cc270eef1e3461da034a3bebe7c84eff052326b130824e98fc3fb/more_itertools-8.2.0-py3-none-any.whl (43kB)
Collecting six>=1.10.0
Downloading https://files.pythonhosted.org/packages/65/eb/1f97cb97bfc2390a276969c6fae16075da282f5058082d4cb10c6c5c1dba/six-1.14.0-py2.py3-none-any.whl
Collecting atomicwrites>=1.0
Downloading https://files.pythonhosted.org/packages/52/90/6155aa926f43f2b2a22b01be7241be3bfd1ceaf7d0b3267213e8127d41f4/atomicwrites-1.3.0-py2.py3-none-any.whl
Collecting importlib-metadata>=0.12; python_version < "3.8"
Downloading https://files.pythonhosted.org/packages/8b/03/a00d504808808912751e64ccf414be53c29cad620e3de2421135fcae3025/importlib_metadata-1.5.0-py2.py3-none-any.whl
Collecting zipp>=0.5
Downloading https://files.pythonhosted.org/packages/be/69/4ac28bf238f287f1677f41392e24d2c4ffafcf11648c23824f5f62ef6ccb/zipp-2.1.0-py3-none-any.whl
Building wheels for collected packages: httptools
Building wheel for httptools (setup.py): started
Building wheel for httptools (setup.py): finished with status 'done'
Created wheel for httptools: filename=httptools-0.0.13-cp36-cp36m-linux_x86_64.whl size=217310 sha256=51eb19168c0639662416a8ad83b9df7d7ceb8eb14a58ce3bec5ffe3ab3b07a7f
Stored in directory: /tmp/pip-ephem-wheel-cache-pwxrmfa5/wheels/e8/3e/2e/013f99b42efc25cf3589730cf380738e46b1e5edaf2f78d525
Successfully built httptools
Installing collected packages: iso8601, httptools, pbr, py, zipp, importlib-metadata, pluggy, attrs, setuptools, more-itertools, six, atomicwrites, pytest, pytest-asyncio, fdk
Successfully installed atomicwrites-1.3.0 attrs-19.3.0 fdk-0.1.12 httptools-0.0.13 importlib-metadata-1.5.0 iso8601-0.1.12 more-itertools-8.2.0 pbr-5.4.4 pluggy-0.13.1 py-1.8.1 pytest-4.0.1 pytest-asyncio-0.9.0 setuptools-45.1.0 six-1.14.0 zipp-2.1.0
WARNING: You are using pip version 19.3.1; however, version 20.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Removing intermediate container 4f758b74080b
---> 5246c18d4e6f
Step 5/12 : ADD . /function/
---> c6181bb33bd1
Step 6/12 : RUN rm -fr /function/.pip_cache
---> Running in 695fe059e692
Removing intermediate container 695fe059e692
---> 5ea69eaafc3a
Step 7/12 : FROM fnproject/python:3.6
3.6: Pulling from fnproject/python
80369df48736: Already exists
aaba0609d543: Already exists
a97b990f94a5: Already exists
af4a941e5376: Already exists
709c35256bb6: Already exists
671870542c6c: Pull complete
936a6f40830a: Pull complete
Digest: sha256:3b438ba11405bba0f6e1e8d8819c9b8be38249da7253491f3cf9f7e5ed6c0ec6
Status: Downloaded newer image for fnproject/python:3.6
---> e8e10863d7cd
Step 8/12 : WORKDIR /function
---> Running in ddbc794f4bd9
Removing intermediate container ddbc794f4bd9
---> 4e3bed62a7f5
Step 9/12 : COPY --from=build-stage /python /python
---> b1c7d4fd7598
Step 10/12 : COPY --from=build-stage /function /function
---> 87446e069bd2
Step 11/12 : ENV PYTHONPATH=/function:/python
---> Running in af075fbcae2c
Removing intermediate container af075fbcae2c
---> 98a9f515e7e0
Step 12/12 : ENTRYPOINT ["/python/bin/fdk", "/function/func.py", "handler"]
---> Running in 555033ab1e55
Removing intermediate container 555033ab1e55
---> 9942a3d98858
Successfully built 9942a3d98858
Successfully tagged fndemouser/multiply:0.0.2
Updating function multiply using image fndemouser/multiply:0.0.2...
Successfully created function: multiply with fndemouser/multiply:0.0.2
Successfully created trigger: multiply
Trigger Endpoint: http://127.0.0.1:18080/t/calc-fn-app/multiply
fnのコマンドで確認します。(別エントリでplus,minusを作ってあります)
$ fn list fn calc-fn-app
NAME IMAGE ID
multiply fndemouser/multiply:0.0.2 01E086F2D6NG8G00GZJ000001E
plus fndemouser/plus:0.0.2 01E0393FDCNG8G00GZJ000000E
subtract fndemouser/subtract:0.0.3 01E05KAKGENG8G00GZJ0000013
Dockerのコマンドで確認すると、対応するコンテナのイメージができていることがわかります。
$ docker images | grep multiply
fndemouser/multiply 0.0.2 9942a3d98858 About a minute ago 175MB
実行
登録時の末尾にあったURLにcurlでアクセスしてみます。
$ curl -d '{"left":"2", "right":"4"}' http://127.0.0.1:18080/t/calc-fn-app/multiply
{"result": "8"}
2*4の結果である8が返ってきています。
おわりに
このエントリでは、Fn projectを使ってPythonで書いたfunctionを動かしてみることを扱いました。
このエントリで使用したコードは、https://github.com/hrkt/calc-fn-app/releases/tag/0.0.3のタグに格納してあります。
補足:外部ライブラリ
このエントリでは、外部ライブラリを使いませんでしたが、requirements.txt中に記載することで、pipを利用できます。
補足:このエントリを書くにあたり
このエントリを書くにあたり、OCIのマイクロインスタンス上に下記の状況を作り、ノートPCからクラウド側にsshでリモートでつないで作業しました。
- sshの先にscreenで複数枚のウインドウ上げておいて作業して
- VS CodeをWEBで動かして「cdr/code-serverとOCIのAlways FreeのMicroインスタンスでVS Codeを動かしてみる」
- Fn projectのサーバもそこで動かして
- コードはGitHubに