0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Enterprise電卓を作るAdvent Calendar 2019

Day 14

Fn Projectを使ってPythonで書いたfunctionを動かしてみる

Last updated at Posted at 2020-02-04

概要

このエントリでは、OSSのFaaSサーバである「Fn Project」を使い、Pythonの関数を動かすパターンを扱います。

下図のようなPythonによる掛け算の関数をFnのサーバにデプロイして動かします。

calcfn_multiply.png

想定読者

準備

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でリモートでつないで作業しました。

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?