注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
関数実行モードで実行している場合、Foundry の他の場所から呼び出せるように計算モジュール内の関数を登録する必要があります。このページでは、計算モジュールの関数を手動で登録する 2 つの異なる方法を説明します。
計算モジュール SDK を使用すると、関数のスキーマを自動的に推論することで関数の登録が容易になります。計算モジュール SDK を使用している場合は、以下の関数スキーマの自動推論セクションを確認してください。
Functions ページから計算モジュールの関数を手動で登録できます。Add function を選択して Create function パネルを開きます。
計算モジュール関数の入力は JSON オブジェクトにパッケージ化されます。追加する各入力は、関数に渡される入力オブジェクトのプロパティに対応します。以下の例では、関数入力は左側にあり、対応する関数に渡される JSON オブジェクトは右側にあります。
example_function_payload.json
Copied!1 2 3 4 5
{ "arg1": "hello", // 文字列 "hello" "arg2": 2, // 数値 2 "arg3": "1969-07-20" // 文字列 "1969-07-20", 日付形式 }
com.<名前空間>.computemodules.<MyApiName>
の構造に従い、以下の命名ルールに従わなければなりません。API 名を変更すると、使用しているコードが壊れます。クエリの最新の公開バージョンのみがサポートされます。
関数を定義したら、Test タブに切り替えて関数の呼び出しを試すことができ、または Save を選択して関数を保存し、Foundry から呼び出せるようにします。
コンピュート モジュール関数は常にバージョン 0.0.0
で登録されます。関数を更新すると、その関数のバージョンはユーザーの変更によって上書きされます。
コンピュート モジュール内から HTTP POST リクエストを送信することで、手動で関数スキーマを定義することもできます。通常、独自のクライアントを作成する場合にのみこれを行う必要があります。HTTP リクエストに関する情報については、POST function schema ドキュメントを参照してください。
このエンドポイントは、ペイロードとして JSON 配列を受け入れます。配列内の各要素は、コンピュート モジュール内の関数の仕様に対応します。私たちの Python SDK ↗ は、この JSON ペイロードの組み立てに関する良いリファレンスを提供しています。
以下の表は、関数の入力/出力タイプと、それらのタイプがコンピュート モジュールに対して HTTP 経由でどのようにシリアライズされるかのマッピングを示しています。
Foundry タイプ | HTTP 経由でシリアライズされる形式 | 備考 |
---|---|---|
Integer | int | |
Byte | string | |
Boolean | boolean | |
Binary | string | |
Date | string | |
Timestamp | int | エポックからのミリ秒 |
Decimal | string | |
Float | float | |
Array | array (non-streaming), stream of JSON (streaming) | |
Map | JSON | キーバリュー ストア (たとえば、Python dict , Java Map) |
Struct | JSON | カスタム オブジェクト タイプ |
コンピュート モジュールは、関数の定義と登録を簡素化し、自動スキーマ推論と Foundry のコンピュート モジュール アプリケーションとの統合を可能にします。このセクションでは、関数の自動登録と高度な使用シナリオについて詳しく説明し、スムーズな開発体験を提供します。
インポートされた関数スキーマは、コンピュート モジュールが実行中で応答している場合にのみ、コンピュート モジュールのインターフェースに表示されます。つまり、関数を Foundry で表示およびアクセス可能にするには、コンピュート モジュールをデプロイして実行する必要があります。詳細については、replica status を使用したデバッグ に関するドキュメントを参照してください。
ユーザーのコンピュート モジュール内で、コード内に直接 JSON 構造を使用して関数のスキーマを定義できます。このアプローチには次のような利点があります。
コンピュート モジュールの起動時に単純な POST
コールを行うことで、エンドポイント コールからスキーマを自動的に推論し、コンピュート モジュール アプリケーション内で関数として利用可能にします。これにより、開発者はエンドポイント スキーマを一度定義し、それを簡単に Foundry にインポートすることができます。
簡単な add
関数を考えてみましょう。入力は x
と y
(2 個の整数) で、出力は文字列です。以下の例は、この関数の JSON スキーマを定義する方法を示しています。
schemas.json
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
{ "functionName": "add", // 関数名「add」 "inputs": [ // 入力パラメータ { "name": "x", // パラメータ名「x」 "dataType": { "integer": {}, // データ型「integer(整数)」 "type": "integer" // データ型「integer(整数)」 }, "required": true, // 必須パラメータ "constraints": [] // 制約なし }, { "name": "y", // パラメータ名「y」 "dataType": { "integer": {}, // データ型「integer(整数)」 "type": "integer" // データ型「integer(整数)」 }, "required": true, // 必須パラメータ "constraints": [] // 制約なし } ], "output": { "single": { "dataType": { "string": {}, // データ型「string(文字列)」 "type": "string" // データ型「string(文字列)」 } }, "type": "single" // 出力タイプ「single(単一)」 } }
JSON スキーマを定義したら、app.py
ファイルで HTTP POST リクエストを送信して Foundry に登録してください。
if __name__ == "__main__":
certPath = os.environ['CONNECTIONS_TO_OTHER_PODS_CA_PATH'] # 環境変数から証明書のパスを取得
postSchemaUri = os.environ["POST_SCHEMA_URI"] # 環境変数からスキーマの投稿先URIを取得
with open('schemas.json', 'r') as file:
SCHEMAS = json.load(file) # スキーマが記述されたJSONファイルを読み込む
requests.post(
postSchemaUri,
json=SCHEMAS,
headers={"Module-Auth-Token": moduleAuthToken, "Content-Type": "application/json"},
verify=certPath # 証明書のパスを使ってリクエストを検証
)
本番環境では例外処理と適切なエラーロギングを必ず実装してください。
関数は以下の制約に従う必要があります:
functionName
を宣言する必要があります。Python type | Foundry type | Serialsed over HTTP as | Notes |
---|---|---|---|
int | Integer | int | |
str | Byte | string | |
bool | Boolean | boolean | |
bytes | Binary | string | |
datetime.datetime | Date | string | |
datetime.datetime | Timestamp | int | Milliseconds since epoch |
decimal.Decimal | Decimal | string | |
float | Float | float | |
list | Array | array (non-streaming), stream of JSON (streaming) | |
set | Array | array (non-streaming), stream of JSON (streaming) | |
dict | Map | JSON | Key-value store (たとえば、Python dict , Java Map) |
class/TypedDict | Struct | JSON | カスタムオブジェクト型 |
Iterable | Array | array (non-streaming), stream of JSON (streaming) |
computeモジュールSDKには、自動関数発見の機能が含まれています。定義された関数とその入力/出力型を検査し、それらを変更なしでFoundry FunctionsとしてインポートできるFunctionSpecs
に変換します。
この機能がスムーズに動作するようにするためには、SDK内での型推論の仕組みと入力および出力型の正しい定義方法を理解することが重要です。以下の考慮事項を確認してください:
✅ 入力型としてTypedDict
Copied!1 2 3 4 5 6 7 8 9 10 11 12
# app.py from typing import TypedDict from compute_modules.annotations import function # HelloInputはTypedDictを継承し、'planet'というキーを持つ辞書型を定義 class HelloInput(TypedDict): planet: str @function def hello(context, event: HelloInput) -> str: # eventから'planet'キーの値を取得し、"Hello "と連結して返す return "Hello " + event["planet"] + "!"
✅ dataclass を入力タイプとして使用
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# app.py from compute_modules.annotations import function from dataclasses import dataclass import datetime import decimal # データクラスの定義 @dataclass class TypedInput: bytes_value: bytes # バイト値 bool_value: bool # ブール値 date_value: datetime.date # 日付値 decimal_value: decimal.Decimal # 小数値 float_value: float # 浮動小数点値 int_value: int # 整数値 str_value: str # 文字列値 datetime_value: datetime.datetime # 日時値 other_date_value: datetime.datetime # 他の日時値 # 関数の定義。`function`デコレータを使用 @function def typed_function(context, event: TypedInput) -> str: # 2つの日付の差を計算 diff = event.other_date_value - event.datetime_value # 差を文字列として返す return f"The difference between the provided dates is {diff}"
✅ 通常のクラスで、クラスとコンストラクターの両方に型ヒントがあります
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# app.py from compute_modules.annotations import function class GoodExample: some_flag: bool # フラグを保持するブール型の属性 some_value: int # 値を保持する整数型の属性 def __init__(self, some_flag: bool, some_value: int) -> None: # コンストラクタでフラグと値を初期化 self.some_flag = some_flag self.some_value = some_value @function def typed_function(context, event: GoodExample) -> int: # 関数はGoodExample型のイベントを受け取り、そのsome_valueを返す return event.some_value
❌ 避ける クラス型ヒントがない Python クラス
Copied!1 2 3 4 5
# app.py # これは例外を発生させます class BadClassNoTypeHints: def __init__(self, arg1: str, arg2: int): ...
❌ 避ける コンストラクタにArgs
を持つPythonクラス
Copied!1 2 3 4 5 6 7 8 9 10
# app.py # これは例外を発生させます class BadClassArgsInit: arg1: str arg2: int def __init__(self, arg1: str, arg2: int, *args): ... # *argsを使用しているため、初期化時に余分な引数が渡されると予期しない動作を引き起こす可能性があります。 # そのため、正しい引数の数を確認するなどのエラーチェックが必要です。
❌ 使用しない コンストラクタ内の Kwargs
を持つ Python クラス
Copied!1 2 3 4 5 6 7 8 9
# app.py # このクラスは例外を発生させます class BadClassKwargsInit: arg1: str arg2: int # __init__メソッドに**kwargsを含めていますが、これが原因で予期しない引数が渡される可能性があり、例外が発生します。 def __init__(self, arg1: str, arg2: int, **kwargs): ...
Iterable
タイプ (ただし dict
は除く) の場合、ストリーミング出力をサポートしています。結果のストリーミングを有効にするには、@function
を @function(streaming=True)
に変更します。詳細は SDK ドキュメント ↗ で確認できます。ストリーミング関数が正しく登録されていることを確認するには、戻り値の型として任意の Iterable
タイプを使用します。すると、出力は Foundry の Array
として登録されます。streaming=True
を設定しないと、結果はイテラブル全体の単一のJSONブロブとして投稿されます。イテラブルがJSONでシリアライズできない場合、エラーが発生する可能性があります。streaming=True
を設定すると、結果は各要素からシリアライズされたJSONブロブのストリームとして投稿されます。詳細は SDK ドキュメント ↗ で確認してください。
✅ 一般的な Iterable
を出力タイプとして使用
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13
# app.py # 出力は Foundry Array として登録されます from compute_modules.annotations import function @function(streaming=True) def get_string_list(context, event) -> list[str]: # 0から9までの数値を含む文字列のリストを生成して返す return [f'string {i}' for i in range(10)] @function(streaming=True) def get_string_set(context, event) -> set[str]: # 固定された3つの文字列を含むセットを生成して返す return {'string 1', 'string 2', 'string 3'}
✅ 出力タイプとしての Generator
Copied!1 2 3 4 5 6 7 8 9
# app.py # GeneratorはIterable(反復可能オブジェクト)です。出力はFoundry Arrayとして登録されます。 from compute_modules.annotations import function import typing @function(streaming=True) def string_generator(context, event) -> typing.Iterable[str]: for i in range(10): yield f'string {i}'
⚠️ 出力タイプとして通常の Iterable が指定されていますが、ストリーミングが有効になっていません
```python
# app.py
# これは有効です。この出力はFoundry Arrayとして登録されますが、結果はストリーミングされません。
from compute_modules.annotations import function
@function
def get_string_list(context, event) -> list[str]:
return [f'string {i}' for i in range(10)]
❌ 出力タイプとしてGeneratorが設定されていますが、ストリーミングが有効になっていません
Copied!1 2 3 4 5 6 7 8 9 10
# app.py # ジェネレータ全体はJSONシリアライズ可能ではありません。非ストリーミング関数で使用することはできません。 # 出力タイプはFoundry Arrayとして登録されますが、実行時にエラーが発生します。 from compute_modules.annotations import function import typing @function def string_generator(context, event) -> typing.Iterable[str]: for i in range(10): yield f'string {i}'
関数を登録するには、以下の手順に従ってください。
前提条件:
始める前に、TypeScript コードリポジトリでリソース生成が有効になっていることを確認してください。
functions.json
ファイルを開きます。enableResourceGeneration
プロパティを true
に設定します。TypeScript でコンピュートモジュール関数をインポートするには、以下の手順に従ってください。
以下の例は、コンピュートモジュール関数をインポートして使用する方法を示しています。
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13
// index.ts import { Function } from "@foundry/functions-api"; // API名: com.mycustomnamespace.computemodules.Add import { add } from "@mycustomnamespace/computemodules"; export class MyFunctions { @Function() public async myFunction(): Promise<string> { // 50と50を加算する非同期関数 return await add({ x: 50, y: 50 }); } }
string
の戻り値型を宣言した場合、登録されたコンピュートモジュール関数はstruct
型ではなく、string
を返す必要があります。async/await
構文を使用してください。TypeScript関数はfunction-executor
を経由するため、5分未満のコンピュートモジュール関数のみが成功します。関数が5分以上かかる場合、タイムアウトします。