初心者がChatGPT先生とWEB開発（IIS,Python,Athena,S3）その②

## 初めに

皆様、はじめまして。
今回初投稿をするMrTansansuiと申します。
何卒よろしくお願いいたします。

さて、AI, AWS Athena そしてPythonのお勉強のため、ChatGPT先生に教えてもらいながらシステムを構築していくよ。

作りたいシステムは、
【IISサーバでボタンを押すとS3にあるデータへSQLを投げて結果を取ってくる】
を目指すよ。

システム処理自体は下記を想定

1. IISサーバにてボタン付きの画面を作成
2. ボタンを押すとIISサーバからPythonサーバにリクエスト発行
3. PythonサーバからAmazon AthenaへSQLを発行し、結果をGET
4. GETした結果をIISサーバ上に表示

システム構成は下記イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989873/f51c9f31-34e2-aa11-4eec-a8ebc842b482.png)


@KAJITAKA さんが

https://qiita.com/KAJITAKA/items/c91e482b3a717348ae47

にて、Athenaの設定とPythonサーバからAthenaを操作できるようにするところまで実施してくれたので、本ページでは下記２点を対応していくよ

* Pythonサーバ上でSQL発行できるAPPを作成
* IISサーバからPythonサーバにリクエスト発行

本ページの構成は
* 通常文字が筆者のコメント
* 引用コメントはChat GPT先生のコメント
* 背景黒字は各種コード

なのでよろしく！


**Let's Try!**

### Chat GPTを用いてAPP作成およびリクエスト発行できる環境構築


前回は、Pythonサーバ上で手動でpythonコマンドを叩き、結果がAthenaから取得するところまでできました。APP作成に向けて、ChatGPTさんにバンバン聞いていきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989873/62c32180-2002-3ec6-fa89-6c17c82b14dc.png)

> AthenaをAPI化する方法としては、AWS LambdaとAPI Gatewayを使用する方法があります。AWS Lambdaは、サーバーレスでコードを実行するためのサービスであり、API Gatewayは、RESTful APIを作成するためのサービスです。これらのサービスを組み合わせることで、AthenaをAPI化することができます。
>以下は、AWS LambdaとAPI Gatewayを使用してAthenaをAPI化するための手順です。
> 1. AWS Lambdaで、Athenaからデータを取得するコードを作成します。Lambda関数には、Athenaのクエリを実行するコードと、クエリの結果をPandasのデータフレームに変換するコードが含まれます。
>2. Lambda関数をデプロイします。Lambda関数をデプロイするには、AWS CLI、AWS Management Console、またはAWS CloudFormationを使用できます。
>3. API Gatewayで、RESTful APIを作成します。API GatewayでAPIを作成するには、APIのリソース、メソッド、および統合を定義します。API Gatewayは、Lambda関数と統合されるように構成する必要があります。
>4. RESTful APIをテストします。APIをテストするには、API Gatewayコンソールまたはcurlなどのツールを使用できます。
> 
>以上の手順を実行することで、AthenaをAPI化することができます。この手順は、AWSの公式ドキュメントにも記載されていますので、詳細な手順についてはドキュメントを参照してください。


むむむ…　AWSで大人気のLambdaの提示を提示されたぞ。

今回Pythonを動かす用のサーバを既に立てているから、せっかくなのでサーバ活用できる手段を取っていきたいのです、すみません先生、、、

![MicrosoftTeams-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580112/611143ea-a646-95a6-507d-6a7f5d8f9e50.png)

**(頼むぞ、Ghat GPT先生…！！)**

>EC2にPythonを導入し、nginxからAPIを受け取り、その内容を基にAthenaを操作する方法については、以下の手順を実行することができます。
>
>1\. EC2にPythonをインストールします。Pythonをインストールするには、以下のコマンドを実行します。
>```
>sudo yum update
>sudo yum install python3
>```
> 2\. 必要なPythonライブラリをインストールします。Athenaを操作するためには、boto3ライブラリが必要です。以下のコマンドを使用して、boto3ライブラリをインストールします。
>```python
>pip3 install boto3
>```
>3\. Flaskを使ってAPIを作成します。FlaskはPythonのマイクロフレームワークで、APIを作成するために使用されます。以下は、Flaskを使用してAPIを作成するためのコード例です。
>```python
>from flask import Flask, request
>import boto3
>import pandas as pd
>
>app = Flask(__name__)
>
>@app.route('/query', methods=['GET'])
>def query():
>    query_string = 'SELECT * FROM "itwg_ai2"."test" LIMIT 10'
>    client = boto3.client('athena',
>                          aws_access_key_id='YOUR_AWS_ACCESS_KEY_ID',
>                          aws_secret_access_key='YOUR_AWS_SECRET_ACCESS_KEY',
>                          region_name='ap-northeast-1')
>
>    response = client.start_query_execution(QueryString=query_string,
>                                               QueryExecutionContext={
>                                                    'Database': >'itwg_ai2'
>                                                },
>                                                ResultConfiguration={
>                                                    'OutputLocation': 's3://itwg-ai2g-data/output/'
>                                                })
>
>    query_execution_id = response['QueryExecutionId']
>
>    query_execution_status = 'RUNNING'
>    while query_execution_status in ['RUNNING', 'QUEUED']:
>          query_execution_status = client.get_query_execution(QueryExecutionId=query_execution_id)['QueryExecution']['Status']['State']
>
>    # クエリ結果を取得
>    result_response = client.get_query_results(QueryExecutionId=query_execution_id)
>    column_names = [c['Name'] for c in result_response['ResultSet']['ResultSetMetadata']['ColumnInfo']]
>    rows = [[list(row.values())[i] if i < len(row) else None for i in range(len(column_names))] for row in result_response['ResultSet']['Rows'][1:]]
>    df = pd.DataFrame(rows, columns=column_names)
>
>    # 結果を整形して戻り値として返す
>    result = df.to_dict(orient='records')
>
>    return {'result': result}
>
> if __name__ == '__main__':
>    app.run()
>
> この例では、`/query`エンドポイントを作成し、POSTリクエストを受け取った場合にクエリを実行し、クエリ実行IDを返します。
>```
> 4\. nginxを設定します。nginxは、Webサーバーとして使用され、Flaskアプリケーションをホストするために使用されます。以下は、nginxの設定例です。
>```
>server {
>    listen 80;
>    server_name example.com;
>
>    location / {
>        proxy_pass http://127.0.0.1:5000;
>        proxy_set_header Host $host;
>        proxy_set_header X-Real-IP $remote_addr;
>    }
>}
>```
>この例では、Flaskアプリケーションがポート5000でリッスンするように設定されています。nginxは、ポート80でリッスンし、Flaskアプリケーションにリクエストを転送します。
>
> 5\. Flaskアプリケーションを起動します。Flaskアプリケーションを起動するには、以下のコマンドを実行します。
>```python
>export FLASK_APP=app.py
>flask run
>```
>
>これで、EC2にPythonを導入し、nginxからGET APIを受け取り、その内容を基にAthenaを操作する準備が整いました。
>GET APIを呼び出すためには、`/query`エンドポイントにGETリクエストを送信する必要があります。
>リクエストのボディには、クエリを含める必要があります。


先生の教えを元に実行するぞ！！と思ったら、、、

**サーバがWindowsでnginxではなくIISだったことが判明…**…

なので、4. については、IISに直した形で質問し直したよ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989873/de61611a-9eaf-2575-fc20-ba2fa8691b1e.png)

そうしたら

>了解です。以下は、IISでボタンをクリックすると`127.0.0.1:5000`にリダイレクトするHTMLのサンプルです。
> ```
> <!DOCTYPE html>
> <html>
><head>
><title>Redirect to 127.0.0.1:5000</title>
><meta charset="UTF-8" />
><script>
>		function redirectTo() {
>			window.location.href = "http://127.0.0.1:5000/query";
>		}
></script>
></head>
><body>
><h1>Redirect to 127.0.0.1:5000</h1>
><button onclick="redirectTo()">Go to 127.0.0.1:5000</button>
></body>
></html>
>```
>
>このHTMLコードでは、`<button>`要素を使用してリダイレクトボタンを作成し、JavaScript関数`redirectTo()`を呼び出します。
この関数は、`window.location.href`プロパティを使用して、ブラウザを`http://127.0.0.1:5000`にリダイレクトします。
>
>このHTMLファイルをIIS上で実行すると、ボタンをクリックすることで`127.0.0.1:5000`にリダイレクトされます。
ただし、`127.0.0.1:5000`にアクセス可能なサーバーが必要なため、必要に応じてサーバーを起動してください。


なるほど、これで無事動く…はずだったが、何かエラーが出た…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989873/655853f1-183a-ab53-f3a1-511c1b6307b4.png)


>おそらく`flask`ライブラリがインストールされていないため、エラーが発生している可能性があります。
`flask`ライブラリは、Flaskアプリケーションを開発するために必要なライブラリです。
>
>以下の手順に従って、`flask`ライブラリをインストールしてみてください。
>
>1. コマンドプロンプトを開きます。
>2. 次のコマンドを実行して、`pip`のバージョンを確認します。
>
>```python
>pip --version
>```
>3.`pip`のバージョンが古い場合は、アップグレードしてください。次のコマンドを実行します。
>```python
>python -m pip install --upgrade pip
>```
>4.次のコマンドを実行して、`flask`ライブラリをインストールします。
>```python
>pip install flask
>```
>5.インストールが完了したら、Flaskアプリケーションを再度実行してください。
>```python
>python app2.py
>```
>これで、`flask`ライブラリがインストールされ、Flaskアプリケーションが正常に実行されるはずです。

上記手順でflaskライブラリをインストールし、実行したら動いた！
でも何かワーニングっぽいのが表示されたので、ワーニングメッセージを確認してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989873/0ae87ce0-1c0b-cd1a-85da-41dd4b8dc984.png)


>`WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.`
というメッセージは、Flask開発用Webサーバーが開始されたことを示しています。
> 
>このメッセージは、Flaskの開発用Webサーバーが安全でないため、
本番環境で使用することは推奨されていないことを示しています。
>
>本番環境にFlaskアプリケーションをデプロイする場合は、開発用Webサーバーではなく、
>WSGIサーバー（例：Gunicorn、uWSGI）を使用することをお勧めします。
>WSGIサーバーは、Flaskアプリケーションを安全かつ高速に実行するためのWebサーバーです。
>
>ただし、開発用Webサーバーを使用してFlaskアプリケーションをテストすることは安全です。
>Flaskの開発用Webサーバーは、開発者が迅速にアプリケーションをテストおよびデバッグすることができるように設計されています。

ワーニング出たけど、大丈夫ということですね！やりました！！

IIS上のサーバでEdgeを起動し、作成したhtmlを開いてみると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989873/33398825-9ff3-f096-9621-21903fd2ff53.png)

htmlを読み込んだらしく表示されました！これは動きそうな予感…！！

実際にGo toのボタンを押下すると……


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989873/bde5133d-76be-371b-1c29-dac14313080b.png)

形が崩れているけど、結果が出ました！

実際にシステムを作ってみて、結果が出ると嬉しいです(´;ω;｀)


## 最後に

今回は固定のSQLを実行する形でpythonファイルに書き込みをしていたのですが、html上にデータ入力できる項目を作って表示し、その値をSQLのインプットデータとして利用すれば、S3が持つデータに対して、selectしたものを取得できたりと、何かできそうな感じです。

**最後まで読んでいただきありがとうございました。**