【Flask簡単すぎwww】Railsしか使ったことない大学生エンジニアがPyathonのFlaskを使ってみる。

#はじめに
お恥ずかしながら僕はRailsしかサーバーサイドのフレームワークを使ったことがなかったのですが、Flaskを人に教えることになったので頑張って覚えます！

正直Pythonすら触ったことないけど多分何とかなる！

##そもそもFlaskって？

![logo-full.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/8102de1d-e8f7-8c17-81b4-444e08c9a07d.png)


FlaskはPython用のウェブアプリケーションフレームワークです。
RailsやLaravelと違ってとってもシンプルで軽量らしい。

##実行環境
windows10
Python 3.7.2

#Flask使ってみる
まずはおなじみのHello Worldからやっていきましょう

##Flaskをインストールする
今回Pythonのセットアップは省かせていただきます。

Flaskのインストールは以下のコマンドを実行するだけです。

```
pip install flask
```

##とりま書いてみる
FlaskはPythonコード内でインポートすることで使用できるらしい。
特別なコマンドも特にないのでとっても簡単ですね！
ただ、Railsと違ってファイルが最初から生成されるわけではないっぽい。

以下はflaskの公式チュートリアルから引っ張ってきたコードに少し手を加えたものです。

```hello_world.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World!'

#追記
if __name__ == "__main__":
    app.run()
```

これだけでRailsで言うところのコントローラとルーティングが実装できました。
簡単すぎるっ...！

以下簡単な解説
1行目：Flaskをインポートしています。
2行目：Flaskをappに定義して使えるようにしています。
4行目以降：ルーティングの設定とアクションを定義します。今回の場合`http://{ドメイン名}/`にアクセスしたとき`Hello, World!`を返します。
8行目以降：チュートリアルには記載されていない内容ですが追記しました。hello_world.pyを実行したときにウェブサーバを起動します。

##実行してみよう
実行方法は通常のpythonファイルと同じように実行すればサーバが立ち上がります。

```
> python3 hello_world.py
 * Serving Flask app "hello_world" (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: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

これでサーバが立ち上がったので`http://127.0.0.1:5000/`にアクセスしてみます。

![resultscn.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/b8157e39-8efd-e48f-71af-cbb9f9f01ee3.png)


このように表示されれば成功です。

また、環境変数`FLASK_APP`に実行したいファイルを設定しておけば`flask run`と入力するだけでサーバを立ち上げることもできます。

```
>set FLASK_APP=hello_world.py
>flask run
 * Serving Flask app "hello_world.py"
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

基本的なひな形としてはこれだけです！
なんとシンプル！
ここまで見た感じ、Railsよりも圧倒的にコンパクトですね。

さすがにこれではシンプルすぎて不十分なので、ここから付け加えていきます。

#HTML/CSSを作ってみよう
ここからwebアプリケーションには欠かせないHTML/CSSを付け加えていきます。

##HTML

HTMLを扱うとき、Flaskではデフォルトで`templates`というフォルダを参照します。
というわけでtemplatesと、その中にindex.htmlをそれぞれ作っておきます。

```
HelloWorld/
　├ templates/
  │　└ index.html
　└ hello_world.py
```

index.htmlの中身を適当に記述しておきます

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
      <meta charset="UTF-8">
      <title>HELLO</title>
  </head>
  <body>
      <p class="hello">HTMLが正常に読み込まれています</p>
  </body>
</html>
```

これでhtmlの準備はできたのでpythonファイルのなかでHTMLを返すように変更します

```hello_world.py
from flask import Flask, render_template #"render_template"を追記
app = Flask(__name__)

@app.route('/')
def hello():
    return render_template('index.html') #返り値にindex.htmlを返すように変更

if __name__ == "__main__":
    app.run()
```
1行目に`render_template`を追記するのを忘れないでください。

`render_template()`で`templates`フォルダ内のhtmlファイルを返すことが可能です。引数に返したいHTMLファイル名を記述するだけなので簡単ですね。

余談ですが、`render_template()`を`jsonify()`に変えることでJSONを返すこともできます。
これでAPIサーバなんかもつくることができちゃいますね。

では実際にサーバを立ち上げなおして確認してみます。

![htmlは正常に読み込まれています.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/2261d4d3-1ea3-43ba-26cd-954dea1b29b2.png)

文字が見づらくて申し訳ないですが、このように表示されれば成功です。

##CSS
次にCSSを組み込んでいきます。
Flaskのデフォルトでは、CSSやjavascriptは`static`というフォルダ名から参照するのでHTMLと同じようにフォルダとファイルを作っていきます。

```
HelloWorld/
  ├ static/
  │　└ style.css
  ├ templates/
  │　└ index.html
  └ hello_world.py
```

続いてCSSの中身も適当に作っていきます。

```style.css
.hello {
    color: blue;
}
```

ここまで出来たら確認してみましょう。

![css成功.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/f00f4552-745f-bc62-5233-30812ebe5c6c.png)

文字が青色になっていれば成功です。

#データベースとつなげてみる
アプリケーションを作るうえでデーターベースは欠かせないですよね。

今回はSQLiteを使おうと思っていましたが、Firebaseを使っていこうと思います。
~~なんとなく簡単そうだったから...。~~

Firebaseとは簡単に説明すると、サーバーサイドの役割をほとんど賄える開発プラットフォームです。
今回はそんなFirebaseのデータベース機能を使っていきたいと思います。
NoSQLなのでSQLに慣れている方は少し違和感あるかも。

##firebaseのセットアップ
まずfirebaseのトップページからプロジェクトを作成します。

![firebaseTop.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/285afee0-edcd-b3fa-a8ba-e8242d3b2111.png)


`プロジェクトを作成`から作成していきます。
今回は
プロジェクト名：Hello Flask
アナリティクス：日本
でプロジェクトを作成します

![firebaseProjectName.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/3b800c48-b537-1434-bb14-b6a850cd4d09.png)

プロジェクトが作成できたらデータベースを作って設定していきます。

`開発`→`Database`→`データベースの作成`で作成できます。

![databaseCreate.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/49204a88-3831-b296-1464-0e1b9dc26f37.png)

今回はテストモードを選択します。

![databaseTestMode.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/2b1aebf6-8e83-a641-e378-007607ee0050.png)

ロケーションは`asia-northeast1`を設定していきます。

![databaseLocation.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/529cb403-995d-342b-30be-b6f9cbb10403.png)

作成できたらRealtimeDatabaseに変更します。

![dbconsole.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/cb4175d1-74b8-4671-ac01-c592fa2e22b8.png)

![realtimedb.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/57120d32-e47f-b6e5-6892-23eb03d4517b.png)

最後に`ルール`から設定を以下のように変更します。
これによってデータベースの読み書きが許可されます。

![dbrules.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/b69c2956-2901-07e1-771b-e5877adac5f5.png)


これでデータベースは作成できました。

##アプリケーションとDBを連結
ここからFlaskアプリケーションとデータベースを連結していきます。

`プロジェクトの設定`からマイアプリにFlaskアプリケーションを登録します。
ウェブアプリなので`</>`のマークから登録します。

![myapp.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/0780d9a3-afd9-3c73-6456-c429cbde7b90.png)

アプリケーションの名前を適当に決めて入力します。
![myappname.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/50ff39c6-2823-372c-4ea6-874b3fbfa521.png)

スクリプトが表示されれば完了です。

![myappscript.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456493/55946b25-3a34-60d8-a444-b91e26e8690d.png)

今後はこの内容を張り付けることで認証します。

##pyrebaseのセットアップ
pyrebaseはPythonでFirebaseを操作するためのAPIラッパーです。

まずはFlaskと同じようにインストールしていきます。

```
pip install pyrebase
```

**注意：僕がpyrebaseをインストールしたとき文字コードのエラーが発生しました。
以下の記事に詳しい対処法が書かれていたので、同じエラーが出た場合は参考にしてください。**
[pip install pyrebase しただけなのに... (UnicodeDecodeError)](https://qiita.com/kitarikes/items/beb33f72077f9d8374f2)

`hello_world.py`にpyrebaseをインポートし、firebaseと連結していきます。

```hello_world.py
from flask import Flask, render_template
import pyrebase #追記

#configとその内容を追記
config = {
  "apiKey": "*****",
  "authDomain": "*****",
  "databaseURL": "*****",
  "projectId": "*****",
  "storageBucket": "*****",
  "messagingSenderId": "*****",
  "appId": "*****",
  "measurementId": "*****"
}

#firebaseを初期化&DBの関数を'db'へ代入
firebase = pyrebase.initialize_app(config)
db = firebase.database()

app = Flask(__name__)

@app.route('/')
def hello():
    return render_template('index.html')

if __name__ == "__main__":
    app.run()
```
先ほどのスクリプトの一部をコピペして`config`に代入しています。

これでpyrebaseのセットアップは終わりです。

##データベースに保存&削除
これでDB周りも設定できたので実際に読み書きしていきたいと思います。

```hello_world.py
from flask import Flask, render_template, redirect, request
import pyrebase

config = {
  "apiKey": "**************",
  "authDomain": "**************",
  "databaseURL": "**************",
  "projectId": "**************",
  "storageBucket": "**************",
  "messagingSenderId": "**************",
  "appId": "**************",
  "measurementId": "**************"
}

firebase = pyrebase.initialize_app(config)
db = firebase.database()

#peopleキーをセットする
db.set('people')

app = Flask(__name__)

#ルーティングで許可するメソッドを明示的に記述する
@app.route('/', methods=['GET', 'POST'])
def hello():
  #メソッドによって処理を分岐させる
  if request.method == 'POST':
    if request.form['act'] == 'create' :
      person = request.form['name']
      #フォームの内容をpeopleキーの子として保存する
      db.child('people').push(person)
    
    if request.form['act'] == 'delete' :
      #peopleキーの子をすべて削除する。
      db.child('people').remove()
    return redirect('/')

  #db内のpeopleキーの内容を取得する
  people = db.child("people").get()
  #キーの内容を辞書型オブジェクトとしてpへ代入
  p = people.val()

  #何も保存されていない場合は空の辞書型のオブジェクトを代入
  if(p == None) :
    p = {}

  #辞書型オブジェクトの値のみをHTMLに返す
  return render_template('index.html', people = p.values() )

if __name__ == "__main__":
    app.run()
```

```index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>HELLO</title>
    <link rel="stylesheet" href="/static/style.css">
</head>

<body>
    <form action="/" method="post">
        <input type="text" name="name">
        <input type="submit" name="act" value="create">
    </form>
    <br>

    <form action="/" method="post">
        <input type="submit" name="act" value="delete">
    </form>

    <br><br>
    <p>名前リスト</p>
    <ul>
        {% for p in people %}
        <li>{{ p }}</li>
        {% endfor %}
    </ul>
</body>

</html>
```

実際に動かしてみて正常に動作すれば完成です。

#さいごに
最終的にはhello_world.pyを複数のファイルに分割する予定でしたが、疲れたのでここまでで簡便してください...w

Flask本体はRailsと比べてとてもシンプルでした。個人開発にはもってこいなフレームワークなのではないでしょうか。

なにか説明不足があれば追記しますので、コメントにてお願いします。