Databricks Apps でカスタムアプリのデプロイ

# はじめに

Databricks Apps でDashやFlask, Streamlitなどテンプレートが提供されていないライブラリ(今回はFastAPI)を使用したカスタムアプリをデプロイする方法を検証します。

## 前段
[Azure DatabricksでDatabrics Appsを検証するための環境構築](https://qiita.com/kei1-dev/items/c5d1f21687bd23489166)

# 前提環境
以下Databricks Appsのシステム環境に準じます。
[Databricks Apps System Environment](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/databricks-apps/#the-databricks-apps-system-environment)

- Ubuntu 22.04 LTS
- Python 3.11
- FastAPI 0.115.6 (Databricks Appsのデフォルトバージョンではなく、後述する手順でインストールします)

# カスタムアプリのデプロイ

## カスタムアプリの作成
カスタムアプリに必要なファイルは以下の通りです。
- アプリケーションコード(今回はFastAPIで作成したapp.py)
- `requirements.txt`
  - アプリケーションで使用するライブラリを記載する
  
今回はFlaskのサンプルで使用されていたgunicornによる起動コマンドと同等の起動をするためFastAPI, uvicornとgunicornを組み合わせた構成とします。

### アプリケーションコードの作成
サンプルAPIを含むapp.pyは以下の通りです。

**app.py**
```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
```

- `FastAPI` インスタンスを作成します。これがアプリケーションの中心となり、ルーティングやリクエストの処理が行われます。
- `@app.get("/")` デコレーターは、ルートエンドポイント（`/`）へのGETリクエストを処理するためのものです。この関数が呼び出されると、`{"Hello": "World"}` というJSONレスポンスを返します。
- `@app.get("/items/{item_id}")` デコレーターは、パスパラメータ`item_id`を持つエンドポイントへのGETリクエストを処理します。オプショナルなクエリパラメータ`q`も受け取ることができます。この関数は、受け取った`item_id`と`q`を含むJSONオブジェクトを返します。
- 最後のブロックでは、アプリケーションが直接実行された場合（`__name__ == "__main__"`）、`uvicorn`を使用してサーバーを起動します。`host="0.0.0.0"`はすべてのインターフェースでサーバーを利用可能にし、`port=8000`でリッスンします。

## requirements.txtの作成

requirements.txtは以下の通りです。

**requirements.txt**
```
fastapi==0.115.6
uvicorn[standard]==0.34.0
gunicorn==23.0.0
```

- `uvicorn[standard]==0.34.0`: Uvicornは、FastAPIが内部で使用するASGIサーバーです。非同期プログラミングをサポートし、高速なパフォーマンスを提供します。`[standard]`は、標準的な依存関係（例えば、Websocketsのサポート）を含むバージョンを指定します。
- `gunicorn==23.0.0`: Gunicornは、PythonのWSGI HTTPサーバーで、UNIXシステム上でのデプロイに適しています。Uvicornと組み合わせて使用することで、より堅牢な本番環境を構築することができます。

## ローカル動作確認

ローカルで動作確認を行います。

以下コマンドでライブラリのインストールとアプリケーションの起動を行います。
```bash
pip install -r requirements.txt
gunicorn main:app -k uvicorn.workers.UvicornWorker -w 1
```

正常に起動したら、`curl http://localhost:8000/`でアクセスしてみます。

```bash
curl http://localhost:8000/
# {"Hello": "World"}
curl http://localhost:8000/items/1?q=hoge
# {"item_id": 1, "q": "hoge}
```

正常にアクセスできたら、ローカルでの動作確認は完了です。

## Databricks Appsへのデプロイ
Databricks Appsにカスタムアプリをデプロイするためには最低限以下の３つのファイルが必要です。

- アプリケーションコード(今回はFastAPIで作成したapp.py)
- `requirements.txt`
- `app.yaml`
  - アプリケーションの設定(起動コマンド、環境変数)を記載する
  
### デプロイ用のファイルの作成
Databricks Appsにデプロイ時の起動コマンドや環境変数を設定するためのファイルが`app.yaml`です。(今回はgunicornによる起動コマンドのみ記載)

app.yamlの設定の書き方は
[Databricks Apps Configuration](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/databricks-apps/configuration#configuring-your-databricks-apps-with-the-appyaml-file)
を参照してください。

app.yamlは以下の通りです。

**app.yaml**
```yaml
command: [
  "gunicorn",
  "main:app",
  "-k",
  "uvicorn.workers.UvicornWorker",
  "-w",
  "4",
]
```

- `command`: アプリケーションの起動コマンドを指定します。この例では、`gunicorn`コマンドを使用してFastAPIアプリケーションを起動します。****


## Databricks Appsへのデプロイ

Databricks Appsへのデプロイはファイルアップロードとデプロイの2ステップで行います。

### ファイルアップロード

```bash
databricks sync --watch . /Workspace/Users/<username>/<app_name>
```

### デプロイ

```bash
databricks apps deploy <app_name> --source-code-path /Workspace/Users/<username>/<app_name>
```

デプロイが完了したら、Databricks Appsのページから払い出されたURLにアクセスしてみます。

```bash
curl https://<app_name>-XXX.databricksapps.com/
# {"Hello": "World"}
curl https://<app_name>-XXX.databricksapps.com/items/1?q=hoge
# {"item_id": 1, "q": "hoge}
```

正常にアクセスできたら、デプロイは完了です。

# まとめ
Databricks AppsにFastAPIを使用したカスタムアプリをデプロイする方法について説明しました。主なステップは以下の通りです：

- アプリケーションコードの作成
- requirements.txtの作成
- app.yamlの作成
- Databricksへのファイルアップロード
- Databricks Appsへデプロイ

この手順に従うことで、Databricks AppsにFastAPIを使用したカスタムアプリをデプロイすることができます。

# 参考

- [Databricks Apps Configuration](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/databricks-apps/configuration#configuring-your-databricks-apps-with-the-appyaml-file)
- [Databricks Apps Deploy](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/databricks-apps/deploy)