ローカル環境のJupyterLabからAthenaにクエリしたい

自分が初めてPythonを触った時、Jupyter Notebookには大変お世話になりました。

そんな感謝の一方で、AWS re:Invent 2021では[SageMaker Studio Lab](https://www.publickey1.jp/blog/21/awsjupyterlab_idesagemaker_studio_labaws_reinvent_2021.html)が発表されてJupyter環境がまた注目されているなーというにわか心もあったので、JupyterLabの使い方を考えてみました。

機械学習しなくても、手元でJupyterLabを使い始めることが目的です。

## 前提
- Assume RoleかつMFAを設定したIAMユーザ情報を`~/.aws/**`に保存
    - Athena実行に足りるIAMロール権限を持っていること
    - 参考: [Amazon Athena でクエリを実行したとき「Access Denied (アクセスが拒否されました) 」というエラーが表示される理由](https://aws.amazon.com/jp/premiumsupport/knowledge-center/access-denied-athena/)
- Athenaは構築済み
- pipenv環境を使う
    - 下記パッケージを追加

```
[packages]
aws-mfa = "*"
jupyter = "*"
jupyterlab = "*"
pyathena = "*"
pandas = "*"

[requires]
python_version = "3.8"
```

## JupyterLabの関連パッケージインストール
割愛しても良かったのですが、、JupyterLabに関しては[公式ガイド](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html)の通りワンライナーでインストール可能です。

```bash
pipenv install jupyterlab
```

むしろ[aws-mfa](https://github.com/broamski/aws-mfa)を使っていることが個人的にはポイントです。
ローカル環境を便利に使いたいのは当然ですが、認証情報も保護したいためMFA設定は大前提でした。

`aws-mfa`は`~/.aws/**`の認証情報プロファイルをもとにAWS STSが発行する一時トークンを受け取り、アプリ(AWS SDK)にMFA認証を仲介するような動作です。

自分の環境では環境変数`AWS_PROFILE`を設定済みだったので、本当にインストールする以外は準備なしでした。

## JupyterLab起動
pipenv環境に入ってから`jupyter lab`を実行すると、デフォルトブラウザが起動するのでそのままログインします。
![01_JypyterLab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215094/91ae2916-fe5f-8cc3-3873-e602af4d2cfe.png)


```python
from IPython.lib import passwd
passwd()
```

ちなみに上記メソッドを実行するとコンソールパスワードをすぐ設定できるので、検討の余地ありです。

## Athenaにクエリ実行
[pyathena](https://pypi.org/project/pyathena/#basic-usage)の基本通り、試しにクエリを実行するとMFA認証が効いていることが分かります。

```python
from pyathena import connect

cursor = connect(s3_staging_dir="s3://aws-athena-query-results-{account_id}-ap-northeast-1/jupyter/",
                 region_name="ap-northeast-1").cursor()
cursor.execute('SELECT * FROM "athena_cur_billing"."billing" limit 10;')
print(cursor.description)
print(cursor.fetchall())
```
![02_Athena_query.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215094/7420f15e-c022-fd57-91cf-2ed5f7a18cc2.png)

### 実行結果
レスポンス冒頭はテーブル定義でした。
![03_query_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215094/9b91d93a-c676-59fb-ea64-3304e79720db.png)


## クエリ結果をAthenaコンソールと同じように見たい
その場合はpandasを使うと簡単でした。
Jupyter環境でもAthena APIを実行しているため、`s3_staging_dir`バケットから実行結果ファイル(csv)を取得してopen&出力でも良いのですが、分析作業を繰り返したい場合はpandasが便利そうです。

### 実行結果
![04_query_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215094/99afa257-764d-2792-906c-a6ab1f88bb19.png)

クエリ結果がすぐ分かる点はやっぱり魅力的です。
`boto3`を使ってS3から実行結果ファイル(csv)も取得すれば、分析結果をさらに整形したり、ローカル保存したりすることも可能です。

## 今後の使い方（願望）
JupyterLab環境はコードとしてリポジトリ管理可能なため、複数人での環境共有もできます。
また、個人的にJupyterLabの好きなところはコードと同じページにMarkDownやLaTeXを混ぜて記述できることです。仕事をきれいにまとめる仕組みがあるとモチベーションも維持できて、レポート形式で作成すればエンジニア以外にも受けが良さそうなフォーマットも可能なんじゃないかと期待してます。

今回のお試し手順をPDF出力した例はこちら。
![05_jupyter_report.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215094/f3929a2e-8498-1bf8-aa3e-3b1d83309ad3.png)


## 参考記事
Connect Jupyter with Amazon AWS Athena
https://myresearchworks.wordpress.com/tag/jupyter-notebook/

Jupyter Notebook でとりあえず Redash へクエリを投げておけばデータソースはなんでも良い状態にする
https://techlog.voyagegroup.com/entry/2017/06/30/185015