(1)はこちら、(2)はこちらから。
関数の実装
いよいよコードを実装します。ここでは作業環境にMacを利用する前提で説明します。
まず、関数のプロジェクトとなるフォルダを用意します。顔認識をさせるプロジェクトですので、名前をFaceDetectProject
として作っておきましょう。
Face APIを利用するモジュールの導入
Functionsには、Face APIへ顔認識のリクエストを行うためのバインディングが用意されていません。そのため、CPANモジュールを使用します。Face API向けのモジュールとして、MetaCPANで拙作のNet::Azure::CognitiveService::Face
(執筆時点ではv0.04)を公開していますので、これを利用します。
CPANモジュールの導入には、本連載でお馴染みのcpanm
を使います。プロジェクトフォルダ直下でcpanm
を使い、プロジェクトにモジュールを導入します。
関数名フォルダの作成
関数名フォルダの名称はそのまま関数名となりますので、わかりやすい名称がよいでしょう。今から作るのは顔認識の結果(年齢と性別)を返す関数ですので、InspectFace
という名称で関数名フォルダを作ります。
ここから先は、InspectFaceフォルダ内での作業となります。
function.jsonの作成
トリガとバインディングの設定をするために、function.json
を作成します。InspectFace
はHTTPリクエストを受けてHTTPレスポンスを返す関数ですので、HTTPトリガを設定します。内容は、先述したHTTPトリガのfunction.json
と同じです。
run.shの作成
関数本体となるrun.sh
は次の内容です。
Functionsから起動されたときにtask.pl
を起動し、環境変数res
で指定されたファイルにレスポンスデータを出力させる役割を担います。
Perlプログラムの作成
関数本体から呼び出されるtask.pl
を作ります。
冒頭のuse
文では、4行目でNet::Azure::CognitiveService::Face
モジュールを利用するので、3行目でライブラリパスの指定を行っています。名前が長いモジュールですので、(1)で変数$cog
にモジュール名を代入し、表記を短縮しています。5行目ではJSON
モジュールをuse
していますが、これはレスポンスをJSON形式にするためです。
(2)では、Net::Azure::CognitiveService::Face
に対し、Face APIのエンドポイントURLとFace APIのアクセスキーを渡しています。これらの値は、のちほど環境変数の設定を行うときに登場します。
(3)では、HTTPリクエストのクエリパラメータimage
を取得しています。
(4)ではデフォルトのレスポンスを定義しています。もしクエリパラメータimage
が指定されていない場合、(5)の条件分岐で顔認識を行うロジックに入らず、そのまま400エラーを返すためです。
(6)でFace APIに顔認識のリクエストを行い、レスポンスを受け取ります。顔が認識された場合は、(7)で認識した顔情報から年齢と性別を取り出し、@faces
に格納します。顔が認識されなかった場合は何もしません。
(8)でレスポンスデータを正常系のものに上書きしています。このとき、bodyに@faces
を配列リファレンスに展開します。
そして(9)でレスポンスデータをJSONに変換して、print
で出力しています。run.sh
ではtask.pl
の出力内容をそのまま環境変数resで指定されているファイルにリダイレクトしており、これでFunctionsにレスポンスを引き渡すことができています。
Functionsリソースへの環境変数の設定
task.pl
の(2)で、環境変数からFace APIのエンドポイントURLのFACEAPI_URL
と、アクセスキーのFACEAPI_KEY
を参照している箇所がありました。これらの環境変数をFunctionsリソースに設定します。
まず、次のコマンドでFace APIのエンドポイントURLを調べます。
--resource-group
にはリソースグループ名を、--name
にはCognitive Serviceアカウント名を指定します。
続いて、次のコマンドでFace APIのアクセスキーを調べます。--resource-group
、--name
の指定は先ほどと同じです。
Face APIのエンドポイントURLとアクセスキーの両方がメモできたら、次のコマンドでFunctionsリソースに環境変数を設定します。
Azureへのデプロイ
できあがったコードをAzureにデプロイします。
Functionsでは、GitHubやOneDriveなど、いくつかのデプロイ方法に対応しています。本稿では比較的容易なZIPファイルによるデプロイを紹介します。
まず、プロジェクトフォルダをZIP形式で圧縮します。プロジェクトフォルダ内で次のコマンドを実行してください。
できあがったZIPファイルのFaceDetectProject.zip
をデプロイします。
--resource-group
にはリソースグループ名を、--name
にはリソース名を、--src
には先ほど作成したZIPファイルのパスを指定します。
これで、Perlで作られた関数をFunctionsリソースにデプロイできました。
ブラウザで動作確認
ブラウザでアクセスして動作を確認します。アクセス先URLは関数のエンドポイントURLで、Perlで表現すると次のルールで割り当てられます。
上記の実行結果、つまりこの関数のエンドポイントURLはhttps://face-detect.azurewebsites.net/api/FaceDetect
です。
また、動作確認に利用できる顔画像のURLが必要となります。各自画像URLを用意してください。先ほどの関数のエンドポイントURLに顔画像URLをimage
パラメータとして付加すると、https://face-detect.azurewebsites.net/api/FaceDetect?image=顔画像URL
となります。
ブラウザでこのURLにアクセスすると、次のような結果が返ってくることでしょう。
これは、指定した画像から2名の顔を認識した結果です。性別と推測年齢を人物ごとに抽出できていることが確認できますね。
まとめ
本稿を通じて、Functionsを使い、サーバレス環境上でPerlを利用できることをご理解いただけたと思います。Functionsについてより詳しく知りたい人は、「Microsoft Learn」をご覧ください。
Perlの強みは、後方互換性の高さにあります。筆者が管理するシステムでは、Perlで書かれたビジネスロジックがFunctions上で稼働しています。古いロジックであるにもかかわらず、Functionsでそのまま動作したことは、筆者にとっても驚きでした。
さて、次回の執筆者は東邦之さんで、テーマは「Perlコードを速くする書き方」です。
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現!
- 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう
- 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、NFT