ユーザー入力Webアプリ(GoogleAppEngine python3 Flask 

# 作成するもの
サンプルコードです（初心者にてお勉強中。）
コードはgitsに置いています。
https://github.com/sakurataiko1/GAE_userInput

フォームからユーザー入力された内容を表示する

①初めに表示される画面(login.html)
![20200103_python3flask_01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/8eab63b6-2727-e5ba-6a32-40607346a6dc.jpeg)

②送信ボタン押下後の画面(check.html)
![20200103_python3flask_02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/33227480-2a18-01de-286f-3631dfc56433.jpeg)


# 環境
windows10
GAE
Anaconda
python3
flask 1.1.1
jinjya2
Google Cloud SDK( Shellを使っている。 PowerShellは使っていない）

# 手順概要
・コード作成
・ローカル実行（動作確認 AnacondaPromptを使う）
・ GoogleAppEnginでのプロジェクト作成～公開




# ファイル構成
userInputフォルダを作成し、以下を置く

main.py
templatesフォルダ
　└login.html
　└check.html
　└error.html
(↑　ローカルでの動作確認まで)
(↓　GoogleAppEngineでの公開に必要)
app.yaml
requirements.txt

※staticフォルダは今回作っていない
　スタイルシート.cssファイルを使うときなどだけなので

# コード作成
main.py

```
from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/', methods=['GET'])
def render_form():
    return render_template('login.html')

@app.route('/', methods=['POST'])
def login():
    if request.form['username'] and request.form['email']:
        return render_template('check.html', email=request.form['email'], username=request.form['username'])
    else:
        return render_template('error.html')

if __name__ == '__main__':
    # This is used when running locally only. When deploying to Google App
    # Engine, a webserver process such as Gunicorn will serve the app. This
    # can be configured by adding an `entrypoint` to app.yaml.
    app.run(host='127.0.0.1', port=8080, debug=True)
# [END gae_python37_app]
```

templates/login.html

```
<!doctype html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <h1>メールアドレスと名前を送信してください</h1>
    <form method="POST" action="/">
      <input placeholder="名前" name="username" type="text"/>
      <input placeholder="メール" name="email" type="text"/>
      <input value="送信" type="submit"/>
    </form>
  </body>
</html>

```

templates/check.html

```
<!doctype html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <h1>確認</h1>
    <h2>メールアドレス</h2>
    <p>{{email}}
    <h2>名前</h2>
    <p>{{username}}</p>
  </body>
</html>

```

templates/error.html

```
<!doctype html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <h1>不正なリクエストです</h1>
  </body>
</html>

```

# ローカル実行 (動作確認のため）
※ AnacondaPromptでコマンド実行する (GoogleSDKShellではない）
※ 
①　作成したプログラムを起動する

```
cd (main.pyのあるフォルダ）
python main.py
↓　実行メッセージが表示される
 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 283-918-983
 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
127.0.0.1 - - [03/Jan/2020 14:37:01] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [03/Jan/2020 14:37:01] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [03/Jan/2020 14:37:14] "POST / HTTP/1.1" 200 -
```

②ブラウザを開いて http://127.0.0.1:8080 にアクセスして、動作確認する
![20200103_python3flask_result.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/78f4db64-aaa5-fad7-5e93-2dbe45c5f2e2.jpeg)


# GoogleAppEnginでのプロジェクト作成～公開
■手順概要

※ コマンド実行は　Google Cloud SDK Shell　を起動して打ち込む

１．プロジェクト作成 (コマンド実行)
２．プロジェクトが作成されたことを確認する(コマンド実行)
３．ブラウザでGCPコンソールで課金設定有効にする
    ※↑していないと gcloud deployでエラーになってしまう。
４. アプリを初期化 (コマンド実行)
５．アプリをデプロイ (コマンド実行)
６．WebブラウザにURLアクセスして見れることを確認する

■手順詳細 
フォルダの名前をプロジェクト名([YOUR_PROJECT_ID])にする。
※すでに公開済のものと同じだとアップできないので
　hoge1userinput のようにフォルダ名を変えておく。
※小文字、数字のみ6～30文字。記号も使えない。

Google Cloud SDK Shellでコマンド実行する
１． プロジェクト作成

```
gcloud projects create [YOUR_PROJECT_ID] --set-as-default
```

２．プロジェクトが作成されたことを確認する

```
gcloud projects describe [YOUR_PROJECT_ID]
↓
createTime: '2020-01-03T06:24:01.164Z'
lifecycleState: ACTIVE
name: hoge1userinput
projectId: hoge1userinput
projectNumber: '389895798291'
```

３．ブラウザでGCPコンソールで課金設定有効にする
※これをしていないと gcloud deployでエラーになってしまう。。
https://console.cloud.google.com/
→ 3-1 [App Engine]
→ 3-2画面上部にて今回のプロジェクト名を選んで、画面で課金設定を有効にする
![GAE_20200118.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/bb994f71-a5c0-1145-fcf1-463154f5b2de.jpeg)


４. プロジェクトで App Engine アプリを初期化し、そのリージョンを選択します。
↓リージョン選択メッセージが表示されるので2 を入力して東京を選ぶ.
※ asia-east2は香港なので選ばない。


```
gcloud app create --project=[YOUR_PROJECT_ID]

↓リージョン選択メッセージが表示されるので2 を入力して東京を選ぶ.
※ asia-east2は香港なので選ばない。

Please choose the region where you want your App Engine application
located:

 [2] asia-northeast1 (supports standard and flexible)
↓メッセージ表示されたらOK

Creating App Engine application in project [hoge1userinput] and region [asia-northeast1]....done.
Success! The app is now created. Please use `gcloud app deploy` to deploy your first app.
```

５．standard_python37/hello_world ディレクトリで次のコマンドを実行して、アプリをデプロイします。
※　実行前に、↑手順３のGCPコンソールで課金設定しないとエラーとして止まるので注意が必要
(https://console.cloud.google.com/ → 画面左[App Engine]　）

```
gcloud app deploy

↓メッセージ表示される
Services to deploy:

descriptor:      [C:\kuroda\work_google_GAE\book_py3Flask\hoge1userinput\app.yaml]
source:          [C:\kuroda\work_google_GAE\book_py3Flask\hoge1userinput]
target project:  [hoge1userinput]
target service:  [default]
target version:  [20200103t154111]
target url:      [https://hoge1userinput.appspot.com]


Do you want to continue (Y/n)?  y

Beginning deployment of service [default]...
Created .gcloudignore file. See `gcloud topic gcloudignore` for details.
Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 861, in emit
    msg = self.format(record)
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 734, in format
    return fmt.format(record)
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\core\log.py", line 337, in format
    msg = super(_LogFileFormatter, self).format(record)
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 465, in format
    record.message = record.getMessage()
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 329, in getMessage
    msg = msg % self.args
UnicodeDecodeError: 'ascii' codec can't decode byte 0x8e in position 10: ordinal not in range(128)
Logged from file context_util.py, line 386
#============================================================#
#= Uploading 4 files to Google Cloud Storage                =#
#============================================================#
File upload done.
Updating service [default]...failed.
ERROR: (gcloud.app.deploy) Error Response: [7] Access Not Configured. Cloud Build has not been used in project hoge1userinput before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbuild.googleapis.com/overview?project=hoge1userinput then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

C:\kuroda\work_google_GAE\book_py3Flask\hoge1userinput>gcloud app deploy
Services to deploy:

descriptor:      [C:\kuroda\work_google_GAE\book_py3Flask\hoge1userinput\app.yaml]
source:          [C:\kuroda\work_google_GAE\book_py3Flask\hoge1userinput]
target project:  [hoge1userinput]
target service:  [default]
target version:  [20200103t154426]
target url:      [https://hoge1userinput.appspot.com]


Do you want to continue (Y/n)?  Y

Beginning deployment of service [default]...
Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 861, in emit
    msg = self.format(record)
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 734, in format
    return fmt.format(record)
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\core\log.py", line 337, in format
    msg = super(_LogFileFormatter, self).format(record)
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 465, in format
    record.message = record.getMessage()
  File "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\lib\logging\__init__.py", line 329, in getMessage
    msg = msg % self.args
UnicodeDecodeError: 'ascii' codec can't decode byte 0x8e in position 10: ordinal not in range(128)
Logged from file context_util.py, line 386
#============================================================#
#= Uploading 0 files to Google Cloud Storage                =#
#============================================================#
File upload done.
Updating service [default]...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://hoge1userinput.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse

```

６． ブラウザを起動し、http://YOUR_PROJECT_ID.appspot.com にアクセスしてアプリを表示します。
（　gcloud app browse　コマンドでブラウザ起動できる）
![20200103_python3flask_result.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/b17543e5-5f7b-cdaa-798a-f54c236f4b04.jpeg)


# アプリ削除
クリーンアップ
課金されないようにするには、GCP プロジェクトを削除してプロジェクト内のすべてのリソースへの課金を停止します。　
（おそらく、小さいプログラムで負荷が小さければ課金なしだが念のため。）

GCP Console (https://console.cloud.google.com/) で
[リソースの管理] ページに移動

プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
![20200103_python3flask_05-GCPcondoleDel.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/43b4e878-f994-7bf8-dd9f-fa8416904716.jpeg)



方法２として
データを残して、アクセスはできないようにする場合（ただし課金はありになる）なら
[AppEngine]メニューからアプリケーション無効にするだけでもいいかもしれない。
![20200103_python3flask_08-GCPcondoleNonActive.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423803/7f6b8d29-f6d1-87d5-0a3a-0bb545170ded.jpeg)



手順は、以上です。

# 参考
■ サンプルコード：
・AmazonKindle書籍　
PythonでWebサービスを作る - Python3 + Flaskで作るWebアプリケーション開発入門 - その１ Kindle版
https://www.amazon.co.jp/dp/B07B2LFGH2

■ python-Flaskコード作成～GAEへアップするまでの手順
・GAE公式マニュアル　App Engine で Python 3.7 アプリをビルドする
https://cloud.google.com/appengine/docs/standard/python3/building-app/?hl=ja

・GAE公式マニュアル　App Engine スタンダード環境での Python 3 のクイックスタート
https://cloud.google.com/appengine/docs/standard/python3/quickstart?hl=ja

・Google App Engine/Python で無料でAIサービスをホストする
参考　★https://qiita.com/jiny2001/items/2180c4ddc5cc493b0cae

・自分メモ　GoogleAppEngine python3 HelloWorldプログラム
https://qiita.com/taiko1/private/ed4d11aabe2d39f4914f

■ 参考まで
・GAEではじめてのFlaskアプリをつくる[Progate修了レベル]
https://www.simonsnote.com/entry/flask-gae


本記事は以上です。