概要
PowerApps のカメラで撮影した画像を API Management 経由で FaceAPI に転送し、その画像の分析結果「感情、性別、年齢」を PoweApps に表示するアプリの実装手順を数回に分け記載しています。また、並行して、その分析結果を CosmosDB に保存しておき、PowerApps からの累積情報取得リクエストにより累積クエリ結果「感情分布、性別分布」を PowerApps に返し、円グラフ表示する機能の実装手順も複数回に分け記載します。なお、PowerApp の画面作成については省略し、APIコール部分とその戻り値の部分に焦点をあてて記載しています。
本アプリの全体構成は下図となります。
第7回目は、第6回 で作成した PowerAppsアプリケーションでカメラ撮影された画像データのFaceAPI分析結果「感情、感情確率、性別、年齢」を CosmosDB へ登録し、その蓄積された情報を取得するための 前段階のローカルサンプルプログラムを作成します。
実行環境
macOS Big Sur 11.3
Python 3.8.3
Azure Cosmos DB 関連
最初にデータを保存する CosmosDB の Conteiner を作成します。
Cosmos DB アカウントの作成
画像分析結果情報「感情、感情確率、性別、年齢」の保存先として Azure Cosmos DB を使用します。アカウント名を「iturucosmosdx」として CosmosDB のアカウントを以下の画面内容で作成します。
上記アカウントの画面左側項目から「キー」を選択し、表示されている「エンドポイント(URI)」と「キー(プライマリキー)」を取得します。
Cosmos DB の Container の作成
上記アカウントの画面左側項目から「データエクスプローラ」を選択し、画面上部の「New Container」タブから「New Container」を選択します。
「Add Container」画面において、以下を定義し、画面下部の「OK」ボタンを押します。
Cosmos DB の Container への Item の登録
上記アカウントの「データエクスプローラ」画面から、先程作成した Conteiner を選択し、画面上部の「New Item」ボタンを押します。
表示されるエディターに、今回登録されるべき情報を追加してみます。
{
"id": "1",
"age": 27,
"gender": "female",
"emotion": "幸",
"data": 100
}
以下のように問題なくデータが登録されていることから、CosmosDB の Conteiner が正常に作成されたことを確認できました。
CosmosDB へのデータ操作 関連
CosmosDB へのデータ登録
画像データの分析結果情報を CosmosDB に登録するローカルプログラムは以下となります。
import pprint
from datetime import datetime
from azure.cosmos import exceptions, CosmosClient, PartitionKey
endpoint = 'https://iturucosmosdx.documents.azure.com:443/'
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
databaseName = 'GetFaceAPIData'
containerName = 'FaceContainer'
def main():
# CosmosDBへの接続
client = CosmosClient(endpoint, key)
db = client.get_database_client(databaseName)
container = db.get_container_client(containerName)
# idの作成
now_ts_str = str(datetime.now().timestamp())
# 登録データ
newItem = {
"id": now_ts_str,
"age": 36,
"gender": "female",
"emotion": "幸",
"data": 84.7
}
# アイテムの追加
item = container.create_item(newItem)
print(' --- create_item --- ')
pprint.pprint(item)
print()
# アイテムの取得
items = container.read_all_items()
print(' --- read_all_items --- ')
pprint.pprint(list(items))
print()
main()
実行結果は以下となります。
$ python CosmosSampleCreate.py
--- create_item ---
{'_attachments': 'attachments/',
'_etag': '"b1017372-0000-2400-0000-60a451e00000"',
'_rid': '-MxGAMsRyx4uAAAAAAAAAA==',
'_self': 'dbs/-MxGAA==/colls/-MxGAMsRyx4=/docs/-MxGAMsRyx4uAAAAAAAAAA==/',
'_ts': 1621381600,
'age': 32,
'data': 81.7,
'emotion': '幸',
'gender': 'female',
'id': '1621381600.242014'}
--- read_all_items ---
[{'_attachments': 'attachments/',
'_etag': '"b1017372-0000-2400-0000-60a451e00000"',
'_rid': '-MxGAMsRyx4uAAAAAAAAAA==',
'_self': 'dbs/-MxGAA==/colls/-MxGAMsRyx4=/docs/-MxGAMsRyx4uAAAAAAAAAA==/',
'_ts': 1621381600,
'age': 32,
'data': 81.7,
'emotion': '幸',
'gender': 'female',
'id': '1621381600.242014'}]
問題なく CosmosDB にデータが登録でき、その登録データを確認することができました。
CosmosDB からのデータ取得
CosmosDB の分析結果情報から、感情毎の件数と性別毎の件数を取得するローカルプログラムは以下となります。戻り値としては、PowerAppsアプリケーション上でグラフ表示させるためにArray型のJSON形式にしておきます。
import pprint
from datetime import datetime
from azure.cosmos import exceptions, CosmosClient, PartitionKey
from collections import OrderedDict
endpoint = 'https://iturucosmosdx.documents.azure.com:443/'
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
databaseName = 'GetFaceAPIData'
containerName = 'FaceContainer'
# emotion定義
emobase = ['anger', 'contempt', 'disgust', 'fear', 'happiness', 'neutral', 'sadness', 'surprise']
emolist = ['怒', '侮', '嫌', '恐', '幸', '無', '悲', '驚']
# gender定義
genlist = ['male', 'female']
def main():
# CosmosDBへの接続
client = CosmosClient(endpoint, key)
db = client.get_database_client(databaseName)
container = db.get_container_client(containerName)
# 感情毎にデータ件数を取得する
print("------ emotion -----")
emo_list = []
for el in emolist:
query = ("SELECT VALUE COUNT(1) FROM items i WHERE i.emotion = '{}'").format(el)
items = container.query_items(query, enable_cross_partition_query=True)
emo_list.append(OrderedDict(感=el, 値=list(items)[0]))
pprint.pprint(emo_list)
# 性別毎にデータ件数を取得する
print("------ genger -----")
gen_list = []
for gl in genlist:
query = ("SELECT VALUE COUNT(1) FROM items i WHERE i.gender = '{}'").format(gl)
items = container.query_items(query, enable_cross_partition_query=True)
gen_list.append(OrderedDict(性=gl, 値=list(items)[0]))
pprint.pprint(gen_list)
# 戻り値の生成
print("------ return -----")
return_dict = {'emo_graph': emo_list, 'gen_graph': gen_list} # 辞書データの作成
pprint.pprint(return_dict)
print(type(return_dict))
main()
実行結果は以下となります。
$ python CosmosSampleSummary.py
------ emotion -----
[OrderedDict([('感', '怒'), ('値', 1)]),
OrderedDict([('感', '侮'), ('値', 1)]),
OrderedDict([('感', '嫌'), ('値', 0)]),
OrderedDict([('感', '恐'), ('値', 0)]),
OrderedDict([('感', '幸'), ('値', 20)]),
OrderedDict([('感', '無'), ('値', 13)]),
OrderedDict([('感', '悲'), ('値', 5)]),
OrderedDict([('感', '驚'), ('値', 3)])]
------ genger -----
[OrderedDict([('性', 'male'), ('値', 25)]),
OrderedDict([('性', 'female'), ('値', 18)])]
------ return -----
{'emo_graph': [OrderedDict([('感', '怒'), ('値', 1)]),
OrderedDict([('感', '侮'), ('値', 1)]),
OrderedDict([('感', '嫌'), ('値', 0)]),
OrderedDict([('感', '恐'), ('値', 0)]),
OrderedDict([('感', '幸'), ('値', 20)]),
OrderedDict([('感', '無'), ('値', 13)]),
OrderedDict([('感', '悲'), ('値', 5)]),
OrderedDict([('感', '驚'), ('値', 3)])],
'gen_graph': [OrderedDict([('性', 'male'), ('値', 25)]),
OrderedDict([('性', 'female'), ('値', 18)])]}
<class 'dict'>
問題なく CosmosDB にあるデータから感情毎の件数と性別毎の件数をArray型の辞書型で取得できることを確認できました。
次回について
次回(第8回)はCosmosDBへのデータ登録ローカルプログラムを 第2回 で作成した Azure Functions に追加します。
参考情報
以下の情報を参考にさせていただきました。感謝申し上げます。
Azure Cosmos DB - 基本操作(Python)
PythonからAzure Comos DBのデータ操作
Azure Functions App × Python で Azure CosmosDB にアクセスしてみる
Azure cosmosDB のアラート設定について