関数の実装
いよいよコードを実装します。ここでは作業環境にMacを利用する前提で説明します。
まず、FaceDetectProjectとして作っておきましょう。
$ mkdir FaceDetectProjectFace APIを利用するモジュールの導入
Functionsには、Net::Azure::CognitiveService::Face
CPANモジュールの導入には、cpanmを使います。プロジェクトフォルダ直下でcpanmを使い、
$ cpanm -n -L local Net::Azure::CognitiveServices::Face関数名フォルダの作成
関数名フォルダの名称はそのまま関数名となりますので、InspectFaceという名称で関数名フォルダを作ります。
$ mkdir InspectFaceここから先は、
function.jsonの作成 
トリガとバインディングの設定をするために、function.を作成します。InspectFaceはHTTPリクエストを受けてHTTPレスポンスを返す関数ですので、function.と同じです。
run.shの作成 
関数本体となるrun.は次の内容です。
perl task.pl > $resFunctionsから起動されたときにtask.を起動し、resで指定されたファイルにレスポンスデータを出力させる役割を担います。
Perlプログラムの作成
関数本体から呼び出されるtask.を作ります。
use strict;
use warnings;
use lib "../local/lib/perl5";
use Net::Azure::CognitiveServices::Face;
use JSON 'encode_json';
# (1)長い名前なので変数に入れて短くする
my $cog = 'Net::Azure::CognitiveServices::Face';
# (2)環境変数から、Face APIの設定値を取得する
$cog->endpoint($ENV{FACEAPI_URL});
$cog->access_key($ENV{FACEAPI_KEY});
# (3)HTTPクエリパラメータimageを取得する
my $image_url = $ENV{REQ_QUERY_IMAGE};
# (4)デフォルトのレスポンスを定義する
my $res = {
    status => 400,
    headers => {'Content-Type' => 'application/json'},
    body => {
    message => 'parameter "image" is required',
        }
};
# (5)画像URLが指定されている場合のみ顔認識を試みる
if ($image_url) {
    # (6)Face APIクライアントを使って顔認識を行う
    my $faceapi = $cog->Face;
    my $result = $faceapi->detect(
        $image_url,
        returnFaceAttributes => ['age', 'gender']
    );
    # (7)認識した顔情報から年齢と性別を抽出する
    my @faces = ();
    if ($result->[0]) {
        @faces = map { $_->{faceAttributes} } @$result;
    }
    # (8)レスポンスデータを上書きする
    $res = {
        status => 200,
        headers => {
            'Content-Type' => 'application/json'
        },
        body => {
            faces => [@faces]
        }
    };
}
# (9)レスポンスを返す
print encode_json($res);冒頭のuse文では、Net::Azure::CognitiveService::Faceモジュールを利用するので、$cogにモジュール名を代入し、JSONモジュールをuseしていますが、
(2)では、Net::Azure::CognitiveService::Faceに対し、
(3)では、imageを取得しています。
(4)ではデフォルトのレスポンスを定義しています。もしクエリパラメータimageが指定されていない場合、
(6)でFace APIに顔認識のリクエストを行い、@facesに格納します。顔が認識されなかった場合は何もしません。
(8)でレスポンスデータを正常系のものに上書きしています。このとき、@facesを配列リファレンスに展開します。
そして(9)でレスポンスデータをJSONに変換して、printで出力しています。run.ではtask.の出力内容をそのまま環境変数resで指定されているファイルにリダイレクトしており、
Functionsリソースへの環境変数の設定
task.の(2)で、FACEAPI_と、FACEAPI_を参照している箇所がありました。これらの環境変数をFunctionsリソースに設定します。
まず、
$ az cognitiveservices account show \
  --resource-group face-detect \
  --name face-detect-test |
  grep endpoint
  "endpoint": "https://japaneast.api.cognitive.microsoft.com/face/v1.0",
  ↑実行結果。エンドポイントURLなのでメモしておく--resource-groupにはリソースグループ名を、--nameにはCognitive Serviceアカウント名を指定します。
続いて、--resource-group、--nameの指定は先ほどと同じです。
$ az cognitiveservices account keys list \
  --resource-group face-detect \
  --name face-detect-test |
  grep key1
  "key1": "ba74XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  ↑実行結果。アクセスキーなのでメモしておくFace APIのエンドポイントURLとアクセスキーの両方がメモできたら、
$ az functionapp config appsettings set \
  --resource-group face-detect \
  --name face-detect-app1001 \
  --settings \
    FACEAPI_URL=https://japaneast.api.cognitive.microsoft.com/face/v1.0 \
    FACEAPI_KEY=ba74XXXXXXXXXXXXXXXXXXXXXXXXXXXXAzureへのデプロイ
できあがったコードをAzureにデプロイします。
Functionsでは、
まず、
$ zip -r FaceDetectProject.zip ./できあがったZIPファイルのFaceDetectProject.をデプロイします。
$ az functionapp deployment source config-zip \
  --resource-group face-detect \
  --name face-detect-app1001 \
  --src FaceDetectProject.zip--resource-groupにはリソースグループ名を、--nameにはリソース名を、--srcには先ほど作成したZIPファイルのパスを指定します。
これで、
ブラウザで動作確認
ブラウザでアクセスして動作を確認します。アクセス先URLは関数のエンドポイントURLで、
# Functionsリソース名。この例では"face-detect"
my $functionapp_name = "face-detect";
# 関数名。この例では"FaceDetect"
my $funcname = "FaceDetect";
# エンドポイントURL
my $endpoint_url = sprintf(
    'https://%s.azurewebsites.net/api/%s',
    $functionapp_name,
    $funcname
);
print $endpoint_url;上記の実行結果、https://です。
また、imageパラメータとして付加すると、https://となります。
ブラウザでこのURLにアクセスすると、
{
  "faces":[
    {"gender":"male","age":56},
    {"age":58,"gender":"male"}
  ]
}これは、
まとめ
本稿を通じて、
Perlの強みは、
さて、
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
 イミュータブルデータモデルで始める
 実践データモデリング
 業務の複雑さをシンプルに表現!
- 特集2
 いまはじめるFlutter
 iOS/Android両対応アプリを開発してみよう 
- 特集3
 作って学ぶWeb3
 ブロックチェーン、スマートコントラクト、 NFT 


