FastAPIを使用したBox分類サービスの構築

Yuko Taniguchi
Box Developer Japan Blog
8 min readJan 31, 2023

Boxの分類の入門ガイドの記事では、Box内のコンテンツに自動的に適用される分類ラベルや分類ポリシーを作成する方法について説明しました。

これらのポリシーでは多くのカスタマイズを行うことができますが、

コンテンツの分類のために非常に複雑なビジネスロジックが必要な場合はどうなるでしょうか。

そのためのAPIが用意されているので、今回は、PythonとFastAPIを使用してカスタム分類サービスを構築する例を紹介します。

概要

このユースケースは、以前のサンプルアプリを基に作成されています。この場合、ダイバーの証明書と保険証がユーザーによってアプリにアップロードされたら、このコンテンツにPIIラベルを適用する必要があります。

このために、Webhookを使用して、コンテンツに関連するイベントを取得します。 Webhookが分類サービスにpingを実行すると、コンテンツに適切なラベルが適用されます。

イベントと分類呼び出しの間に、必要なビジネスルールを挿入できます。

ここまでの経緯を振り返って確認したい場合は、以下に示す以前の記事を読むことをお勧めします。

設定

Boxアプリでいくつかの設定を行う必要があります。

最初に、管理コンソールに移動し、[分類] で新しいラベルを作成します。

新しい分類ラベルの作成

次に、開発者コンソールで、アプリにWebhookを作成する必要があります。

Webhookの作成

この例をわかりやすくするために、ClassificationServiceフォルダ内の任意のファイルに対するイベントを監視するWebhookを適用しました。

コードの説明

メインのエントリポイントは単純です。

@app.post("/box/classify")
async def classify(
request: Request,
settings: config.Settings = Depends(get_settings),
db: Session = Depends(get_db),
):
""" Classify endpoint"""

body_json = await request.json()
body = await request.body()

# check for valid signatures
is_valid = box_webhooks.webhook_signature_check(
webhook_id, body, request.headers, db, settings
)

if not is_valid:
raise HTTPException(status_code=404, detail="Invalid signature")

box_webhooks.classify_file(body_json["source"]["id"], db, settings)

return {"ok": True}

Boxでリクエストに署名されると、まずvalidate_messageメソッドを使用してその署名を検証する必要があります。

def webhook_signature_check(
webhook_id: str,
body: bytes,
header: dict,
db: Session,
settings: Settings,
) -> bool:
"""check the signature of the webhook request"""
# get a client object
client = jwt_check_client(db, settings)
# get a webhook object
webhook = client.webhook(webhook_id)

# get the signature keys
key_a = settings.WH_KEY_A
key_b = settings.WH_KEY_B

# validate message body
return webhook.validate_message(body, header, key_a, key_b)

さらに、(構成を間違えた場合に備えて) webhook_idがアプリで想定されているかどうかを確認するほか、考えられる反射攻撃を防ぐためにリクエストIDを記録する必要もあります。

すべて確認できたら、実際にファイルの分類に進むことができます。

def classify_file(file_id: str, db: Session, settings: Settings):
"""classify a file"""

classification = settings.CLASSIFICATION
client = jwt_check_client(db, settings)

file = client.file(file_id)
# file.get()
# file.get_all_metadata()

# the super complex file classification rules go in here

file_class = file.get_classification()

if file_class is None or file_class != classification:
file_class = file.set_classification(classification)

実際はclient.file(file_id)によってファイルがダウンロードされることも、ファイルオブジェクト全体が取得されることもないことに注意してください。file.get()file.get_all_metadata()など、ファイルに関する情報を取得するためのメソッドは多数あります。

ここでは、ファイルを分類するために必要なすべてのビジネスルールを組み込むことができます。 分類のためのAIモデルに情報やファイルを送信したり、他のデータと関連付けたりすることもできます。

ここではユースケースを説明することが目的なので、例はシンプルにしています。シンプルな既存のポリシーを使用して、何も確認することなくこのフォルダ内のすべてのファイルにPIIラベルを適用するだけです。

実際の動作の確認

いつものように、この実践的な例の完成版は、こちらのGitHubリポジトリから複製できます。

指定されたフォルダにファイルをアップロードするとどうなるか確認しましょう。

ファイルのアップロード

ファイルをアップロードすると、Webhookは分類サービスにpingを実行します。

INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: Started reloader process [3292] using WatchFiles
INFO: Started server process [3311]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: 10.1.1.70:39278 - "POST /box/classify HTTP/1.0" 200 OK

その結果、ファイルはPIIとして分類されます。

分類されたファイル

Boxの自動分類は非常に強力ですが、Box Platformを使用すると、コンテンツを分類するために必要なビジネスロジックを実装できます。

Box Shieldと分類のシリーズに関する以下の記事もご覧ください。

--

--