チャットボットなどの開発において、ユーザー入力に応じて動的に外部API(天気情報や翻訳など)を呼び出す要件がある。このような場合、各API呼び出し処理を個別のPythonスクリプトとしてプラグイン化し、.NETアプリケーションから動的に実行するアーキテクチャが考えられる。この手段としてIronPythonを利用することがある。
例えば、以下のような外部リソース取得スクリプトをC#から実行する状況を想定する。
def retrieve_api_data(target_location):
import requests
endpoint = f"https://api.example.com/weather?loc={target_location}"
response = requests.get(endpoint)
return response.text
ところが、上記のようにrequestsモジュールをインポートしたスクリプトをIronPython経由で実行すると、次のような例外がスローされる。
System.MissingMemberException: 'module' object has no attribute '_getframe'
このエラーは、requestsなどのサードパーティ製ライブラリがCPython実装依存のsys._getframe()を使用していることに起因する。この関数はデバッグ目的でコールスタックのフレームオブジェクトを取得するためにCPythonに実装されているが、IronPythonなどの.NET実装では標準でサポートされていない。
この問題に対する回避策として、IronPythonのスクリプトエンジン初期化時にフレーム取得を有効化するオプションを渡す方法が知られている。
var runtimeSetup = new Dictionary<string, object>
{
{ "Frames", true },
{ "FullFrames", true }
};
ScriptEngine pyEngine = Python.CreateEngine(runtimeSetup);
上記の設定を適用することで_getframeのエラー自体は解消されるが、新たな問題が顕在化する。次は依存パッケージの解決エラーが多発するようになる。
IronPython.Runtime.Exceptions.ImportException: No module named urllib3
urllib3をインストールして対応しても、続いてhttp_clientが見つからないといったエラーが連鎖的に発生し、依存関係の解決が終わりのない状態に陥る。
requestsライブラリは純粋なPythonコードだけでなく、CPythonのネイティブ拡張や複雑な標準モジュール階層に強く依存しており、IronPythonの実行環境での互換性担保は極めて困難であることがわかる。