Azure Functions × Cosmos DB を型安全でさらに高速に開発する🐍


求ム!Pythonを使ってAzureで開発する時のTips!【PR】日本マイクロソフト Advent Calendar 2020 20日目の記事です。

はじめに

Azure Functions は他の FaaS と比べて、簡単に開発環境を作れるのが利点だと考えていて、個人的にはブログのデータ収集や JPHacks2020 に参加したときに使用しています。特に、Cosmos DB との相性が非常に良く、簡単にデータの取得や更新をすることができます。

しかし、「Azure Functions 2.x 以降に対する Azure Cosmos DB の入力バインド | Microsoft Docs」でも紹介されているように、関数内で Cosmos DB から持ってくるデータの型は DocumentList となります。これはソースをみると、Document クラスのリストと記載されており、どのようにデータにアクセスすればよいか一見わかりません
また、具体的な問題として例をあげて説明します:

import azure.functions as func

def main(req: func.HttpRequest, users: func.DocumentList):
    username = users["name"]
    id = users["id"]

このとき、Cosmos DB から持ってきたユーザーのデータである users に果たして nameid というプロパティはあるのでしょうか?また、idstr 型を返すのでしょうか、int 型なのでしょうか? Cosmos DB にいちいちアクセスして確認するのは面倒です。

この記事ではこの問題を解決し、開発速度と開発体験を向上させます🐍

解決策

上記の問題を解決するために個人ライブラリを作成しました。個人ライブラリについては、「個人ライブラリのススメ(for Python🐍)」を見てください。

リポジトリ ↓

pip でインストールできます(使用する際は GitHub にスターをいただけると嬉しいです):

$ pip install git+https://github.com/syakoo/azfunc-extensions

Document と Dataclass のコンバーター

関数内で持ってきた Document クラスと Python の dataclass を変換する関数を作成しました。要は、スキーマとして作成したデータクラスに Document を変換します。データクラスについては「Python3.7以上のデータ格納はdataclassを活用しよう | Qiita」が参考になります。

それでは使い方を簡単に説明していきます。

doc2dc(doc: Document, dc: DataClass) -> DataClass

Documentdataclass に変換する関数。

from dataclasses import dataclass
from azfunc_extensions import doc2dc

@dataclass
class User:
    name: str
    age: int
    id: str

# Document → User
user = doc2dc(doc, User)

dc2doc(dc: DataClass) -> Document

dataclassDocument に変換する関数。Cosmos DB への out 時には Document に戻す必要があるため作成しました。

from dataclasses import dataclass
from azfunc_extensions import doc2dc

@dataclass
class User:
    name: str
    age: int
    id: str

user = User("syakoo", 22, '1')
# User → Document
doc = dc2doc(user) # <azure.Document at 0x7f189f516160>

開発体験(DX) について

具体的にどのように変わったかというと、どんなパラメータがあるのかだったり、それぞれのパラメータの型が一目でわかるようになります!

具体例

具体的にこのライブラリを使用して関数を作ってみました。ぜひ参考にしてください:

おわりに

今回は Azure Functions × Cosmos DB の開発速度と開発体験を上げる Tips を紹介しました。リクエストからパラメータ持ってくる処理も結構めんどいので、それも型補完できればいいなーと思いました。