Azure Web AppsではじめるFlask入門

この記事は、[求ム！Pythonを使ってAzureで開発する時のTips！【PR】日本マイクロソフト Advent Calendar 2020](https://qiita.com/advent-calendar/2020/azure-python)の25日目の記事です。時間があると思って、最後の方にしたのですが、意外と忙しかったです...


# はじめに 
Pythonで便利ツール作った時、他の人にも使って欲しいってなりませんか？
Azureを使えば、簡単にWEBアプリケーションを作ることが出来ます。3月ぐらいにAzureを触り始めてこんなに簡単に作れるのかということに気がついたので、それらの手順とかをまとめてみます。
また、Flaskで作る記事が少なかったので、それを書いてみようと思います。

# 対象読者
- Azure Web Appsを使ってみたい人
- Pythonが使える。
- GitHub,Azureのアカウントがある。
    - (Googleで調べると色々出てきます)
- FlaskでWebアプリケーションを作ってみたい人

# 作るもの
今回作るアプリケーションの外形は、
htmlのテキストボックスに入力→ボタンを押す→処理を行う→htmlを表示する
というアプリケーションを作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/eca614e5-1a67-ed3c-c231-513f7a713023.png)

# Flaskアプリケーション作成編
はじめに、Pythonのインストールされている環境に、Flaskをインストールします。

```
pip install flask
```

Flaskをインストールできたら環境構築は完了です。

### HTMLを書く
ファイルの作成場所は、templates/page.htmlです。

```templates/page.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Page</title>
    </head>
    <body>
      <form action = "/" method = "POST">
         <H1>名前を表示するアプリケーション</H1>
         <h1>入力</h1>
         <textarea type="text" name="name" placeholder="名前"></textarea>
         <br>
         <input type="submit" value="実行">
      </form>
      <h1>出力</h1>
      <p>{{text}}</p>
   </body>
</html>
```

いらない部分も多いですが、テキストボックスに名前を入れて、出力する場所を作りました。Flaskや動的サイト特有の部分は、二重かっこ {{ text }}です。ここに結果を出力します。

## バックエンド編

次に、バックエンドを作りましょう。今回は、入力をそのまま、表示させます。

ファイルの作成場所はapplication.pyです。
後ほど述べますが、Azureでホスティングするときに、はじめに読み込まれるのが、**application.py**です。（ファイル名が意外と重要です！）
(Flaskのサンプルではapp.pyになっていたので、確認はしていませんが、そちらでも大丈夫かもしれないです。)

```application.py
from flask import Flask,render_template,request

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def main_page():
    if request.method == 'GET':
        text = "ここに結果が出力されます"
        return render_template("page.html",text=text)
    elif request.method == 'POST':
        name = request.form["name"]
        text = "こんにちは" + name + "さん"
        return render_template("page.html",text=text)

## 実行
if __name__ == "__main__":
    app.run(debug=True)
```

```
python3 application.py
```
実行し、 http://127.0.0.1:5000/ にアクセスすると表示されていることがわかります。

はじめに、FlaskのライブラリのFlask,render_template,requestをインポートを行なっています。

その後、```app = Flask(__name__)```でアプリケーションの作成を行なっています。
また最後に、実行用のコードを書いています。

```@app.route("/", methods=["GET", "POST"])```
で、エンドポイントの作成を行なっています。
今回の場合は、/のページのGETメソッドの時という条件で作っています。POSTだけやGETとPOSTを両方記載することで、動作を変えることができます。

その下に定義した関数が、実行される関数です。
```if request.method == 'GET':```
で、GETメソッドだった時の動作について記載しています。
GETだった場合、text = "ここに結果が出力されます"がpage.htmlに渡されます。

これで、入力された情報が得られるので、後はhtmlに値を渡すだけです。
```return render_template("page.html",text=text)
```

戻り値に、render_template(html名,渡す引数)
という形になります。
実行すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/a6bfaf0f-f79c-046b-44ad-bc4d1a3b485e.png)

一方POSTで送られた場合は、
```text = request.form["name"]```
でテキストボックスから送られた情報を取得しています。nameは、htmlファイル内で定義しているtextareaのidの名前になっています。

GETの時と同様に、textをpage.htmlに入れて表示しています。

これで、ローカル上で簡単な、アプリケーションを作ることが出来ました。では次に、Azureにデプロイするための準備をしましょう。

# GitHubにコードをあげる
今回、Azureにデプロイする際に、GitHub Actionsを使いたいので、GitHubにコードをデプロイします。また、必要なライブラリをrequirements.txtに記載します

```requirements.txt
Flask
```

requirements.txtには、pipなどでいつもインストールしているようなライブラリを記載します。記載の仕方は、```ライブラリ名(インストールするときの名前)==バージョン```です。バージョン名は省略すると最新のバージョンをインストールしてくれます。

GitHubでブランチを作って、コミットします。
ここら辺のやり方はネットに情報がたくさんあるので、Google検索をすると出てきます。個人的には、GitHub DesktopがGUIで操作できてわかりやすいと思います。

https://github.com/kurikinton105/AzureAppSample
今回私が作成したブランチです。

# Azureにデプロイする

[Azure Portal](https://portal.azure.com/)にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/2dd87ea3-5204-de3e-9ac4-e0bd16ef5288.png)

サービスの検索か、Azureサービスから「App Servise」を選択します。

![image.png](https://gyazo.com/92b5d2bbd91938a09a4b59e39e810e9f/thumb/1000)

追加から新しいインスタンスを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/52de43cc-c84f-e1d5-8c37-81716e852e5b.png)

インスタンスの詳細の名前がホスティングした時のURLになります。
ランタイムスタックはPythonを選びましょう。3.7と3.8を選ぶことができます。
地域は、日本も選択できますが、無料で使うことができなかったりするので、デフォルトで表示されているものを使っています。

最後に下にある「確認及び作成」を押します。
![39e05ac5e4e5401f45ffba5fa278d0df-png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/a3a0fc5a-b477-7696-6366-92836995e0e0.png)

「作成」を押します。
少し待つとデプロイが完成しましたと出てきたら完了です。

「リソースに移動」を押して、GitHubのコードをデプロイします。
![スクリーンショット 2020-12-25 15.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/b4a779f4-df59-5d67-1c54-a02a2c721929.png)


押すと色々出てくるので、「GitHub」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/a33c0efc-6588-ec8b-b3a5-c262baf012be.png)
GitHubActionsを選択して続行を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/a7bcfca0-0ca6-33cc-de00-2aa205c48c84.png)
先ほど作成したブランチを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/8c613fdb-31f4-dd30-972f-d79735ed43a2.png)
完了を押して終わりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/cc539f20-d6d2-d40d-bc4e-5a30fba43a9f.png)

5分ぐらい待つと、デプロイされていることがわかります。
デプロイ経過は、GitHubのリポジトリのActionsに行くと見ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/63a0bb0d-b266-3524-7b4e-46d3dfab2083.png)

今後変更があった時は、GitHubにコミットした段階でこのワークフローが動いて自動でデプロイしてくれます。非常に簡単です！

いつまで残しているかわかりませんが、デプロイの結果です。
https://azureappsamle-yama.azurewebsites.net/


このようにしてAzure Web Appを使ってFlaskのアプリケーションを簡単にデプロイすることができます！
今まで個人で使っていたアプリケーションを試しにデプロイしてみてはいかがでしょうか？
私は、[URLから参考文献を自動生成してくれるやつ](https://yama-code.azurewebsites.net/scraiping)や[文章要約のアプリ](https://summary-classes-web.azurewebsites.net/)とかを作りました。ただ無料のサーバーはヨワヨワなので、少し動作は遅いかもしれません。


## Flaskで画像やCSSを読み込む

Flaskのもう一つつまづきやすいところは、ファイルのパスが少し複雑になることです。
画像やCSSは**static/**フォルダ内に格納します
例えば、[Qiitaのアイコン](https://help.qiita.com/ja/articles/others-brand-guideline)qiita-qiita-jobs-favicon.pngをpage.htmlに表示するときは、```static/qiita-qiita-jobs-favicon.png```に画像を配置し、page.htmlに```<img src="/static/qiita-qiita-jobs-favicon.png">```を追加すると、表示することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548598/7c8de070-09e1-5323-9530-e74fad5e1c60.png)

## 次のステップ
render_templateを使ってHTMLファイルを一回一回返すという仕組みは珍しい気がするので、フロントエンドとバックエンドを分けて作ってみましょう。フロントエンドはAzure Static Appsが最近公開されたので、それを使いながら使えると良さそうです。（参考：[フロントエンド初心者でも無料でお手軽に Azure Static Web Apps に Web サイトをデプロイしちゃおう](https://qiita.com/kenchon/items/41d0b604770f9293bed9) )バックエンドは、returnで返すものをJSON形式にするなどして作ります。
また、REST APIにしてバックエンドを開発する（ついでにswaggerなどを使ってドキュメントも作っちゃう）などもできるのではないかと思います。

Azureでサーバーが使えて意外と簡単にWEBアプリケーションが作れちゃうということが伝わったら幸いです。私も3月にAzureに登録して勉強を初めて、簡単に使えるじゃんってなって今はハッカソンに出たりするまでになったので、そういう人の参考になればなと思い書きました。

# 参考文献
- 公式ドキュメント
    - https://docs.microsoft.com/ja-jp/azure/app-service/quickstart-python
- 公式サンプル
    - https://github.com/Azure-Samples/python-docs-hello-world
- Azure App Service（Web App）にPythonのFlaskのWebアプリをのせるサンプル | Qiita
    - https://qiita.com/567000/items/492ee5dd2974d3cf2094