関数ディレクトリ

function-storage upload コマンドでアップロードする関数ディレクトリについて説明します。

基本情報

ローカルで書いた Python コードを function-storage upload コマンドでアップロードすることで、Cleanroom 内で実行することができます。
アップロードは、ディレクトリ単位で行われます。

基本的なディレクトリ構造は以下の通りです。

functions/
├── handler.py # 実行する関数を記載したモジュール
└── packages/  # 依存ライブラリを同梱する場合

エントリポイントについて

function-storage upload で関数ディレクトリをアップロードした後、 cleanroom deploy コマンドの handler オプションで実行する関数(エントリポイント)を指定します。 エントリポイントは、<モジュール名>.<関数名> の形式で指定します。

例えば関数ディレクトリ直下にある handler.pyrun 関数を実行する場合は以下のように指定します。

apc cleanroom deploy --handler handler.run [他のオプション]

エントリポイントは引数を持たない関数である必要があります。

ライブラリについて

アップロードされた関数ディレクトリはCleanroom内にそのまま展開されます。 セキュリティ上の理由から、Cleanroom から pip サーバのような外部へのアクセスは出来ません。 そのため、必要なライブラリは全てディレクトリ内に同梱する必要があります。 import 文は必ず相対パスを使用してください。

例として、以下のようなディレクトリ構造を考えます。 ここで packages には pip などを用いて pandas と numpy がインストールされているとします。

functions/
├── handler.py
├── utils.py
└── packages/
    ├── pandas
    └── numpy

この場合、handler.py からは以下のようにライブラリをimportすることができます。

# handler.py

import sys
sys.path.append("packages")

import pandas as pd
import numpy as np

from utils import load_data

Warning

必要なライブラリが関数ディレクトリ内にインストールされていない場合、handler の実行時に以下のようなエラーが発生します。

$ apc cleanroom run app --profile acompany
2025-08-07 12:50:16 [INFO]: Work status: error.
        Message: Failed to import module 'handler': Either the module is missing from the function directory, or it has missing dependencies.

ライブラリインストール時の注意

以下の環境に合わせたライブラリをインストールする必要があります。

  • Ubuntu 22.04

  • Python 3.10

  • GPU非搭載

Warning

環境非対応のライブラリをアップロードした場合の挙動は保証外です。 Cleanroom内で環境非対応のライブラリを呼び出した場合、以下のようなエラーが発生することが確認されています。

  • ImportError

  • NameError

  • OSError

  • ValueError

以下は Python3.10 の Linux x86_64 用ライブラリをインストールする場合の pip コマンドの例です。

pip install \
    --platform manylinux2014_x86_64 \
    --only-binary=:all: \
    --python-version 3.10 \
    -r <requirements_file> \
    --target=<packages_dir>

requirements.txt に記載されたライブラリを ./function/packages にインストールする場合

pip install \
    --platform manylinux2014_x86_64 \
    --only-binary=:all: \
    --python-version 3.10 \
    -r requirements.txt \
    --target=./function/packages

入力ファイルのパスについて

cleanroom data cp コマンドでアップロードされる入力データディレクトリは、Cleanroom 内部の /WORK/inputs/<input-id> に展開されます。

例えば、./input/input.txt というファイルを以下のコマンドでアップロードした場合、Cleanroom 内部の /WORK/inputs/input_1/input.txt に展開されます。

apc cleanroom data cp ./input app:input_1/

したがって、handler.py では以下のようにファイルを読み込むことができます。

with open("/WORK/inputs/input_1/input.txt", "r") as f:
    data = f.read()

出力ファイルのパスについて

cleanroom data cp コマンドでダウンロードするデータは必ず /WORK/outputs/<output-id> に書き込む必要があります。

例えば、handler.py で以下のようにファイルを書き込んだ場合、cleanroom 内部の /WORK/outputs/output_1/output.txt に書き込まれます。

with open("/WORK/outputs/output_1/output.txt", "w") as f:
    f.write("Hello, World!")

この場合、以下のコマンドを実行することで ./output/output.txt にデータをダウンロードすることができます。

apc cleanroom data cp app:output_1 ./output

ログ出力について

cleanroom data cp コマンドでダウンロードする以外の方法で、実行環境内のデータを取得することはできません。 そのため、Cleanroom実行時にログを出力する場合も、/WORK/outputs/<output-id> に書き込む必要があります。 現在は、ログ出力の取得は関数の実行後にのみ行えますが、今後は関数の実行中にもログ出力を取得できるようになる予定です。

特に、Cleanroom実行時に標準出力(stdout)や標準エラー出力(stderr)に出力した内容は、全て削除されることに注意してください。

エラー時の log がないとデバッグが難しいため、実行関数に try-except を使用するなどして、適切にエラーをキャッチして /WORK/outputs/<output-id> に出力することを推奨します。

Warning

ログ出力に入力データの内容を含めてしまうと、入力データの漏洩に繋がる可能性があります。 特に traceback には意図せずデータの内容が入っていることがある ため、traceback の内容をログに出力する場合は十分注意してください。 ログに出力する内容を入力データに依存しない形式にすることを強く推奨します。

以下はキャッチしたエラーから、その型と発生した場所のみを保存するようなスクリプトの例です。 エラーの型と発生した場所のみをログに出力することで、入力データの内容を漏洩させることなく、エラーの原因を特定することができます。

import traceback

def run():
    try:
        # 実行したい処理
    except BaseException as e:
        # エラーの型をログに出力
        error_log = f"error type: {type(e).__name__}\n"

        # エラーの発生した場所をログに出力
        tb = traceback.extract_tb(e.__traceback__)
        if tb:
            for i, frame in enumerate(tb):
                error_log += f"error location {i + 1}: {frame.filename}:{frame.lineno}\n"

        with open("/WORK/outputs/output_1/error.txt", "w") as f:
            f.write(error_log)

使用メモリについて

関数の実行に使用できるメモリ量は、 cleanroom deploy コマンドの --memory オプションで指定します。 指定したメモリ以上のメモリを使用すると、 MemoryError が発生します。 MemoryError は気づきにくく、エラーメッセージが存在しないケースもあります。 ログ出力について の例のようにエラーの型を出力したり、MemoryError を個別にキャッチするなどの工夫をすることを推奨します。

マルチプロセスについて

APC-DCR では、関数の実行にマルチプロセスを使用することはできません。 マルチプロセスを用いるコードを実行した場合、 BlockingIOError が発生します。