もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

Pythonのwebフレームワーク試してみた

はじめに

こんばんは。久々投稿です。

最近仕事もプライベートも忙しくて、全くブログ書く時間取れませんでした。

先週はかけてないので、今週は意地でも4記事書きます。

幸い先々月からの積本がいっぱいあるので、それを消化できるかなと。

で、今回はこれ。

WEB+DB PRESS Vol.104

WEB+DB PRESS Vol.104

  • 作者: 末田卓巳,林田千瑛,陶山嶺,八谷賢,辰己佳祐,竹澤俊季,服部智,藤岡裕吾,牧大輔,西郡卓矢,松木雅幸,穴井宏幸,新日出海,桑原仁雄,小田知央,ひげぽん,池田拓司,はまちや2,竹原,大場光一郎,大場寧子,松館大輝,日高尚美,Vu Xuan Dung,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/04/24
  • メディア: 単行本
  • この商品を含むブログを見る

そう。「先月号」のWEB+DB PRESSpython入門です。

ずーっと積んでて、全く消化のタイミングがなかったので、今回やろうと思いました。

pythonはポコポコ小さいツールを作るくらいしか触ったことなかったので、はやりの機械学習や、FWを使用したweb開発まで書かれてて、触りにはもってこいかなと。

で、今回は、本誌でチュートリアルまで紹介されている Bottle と、名前だけ紹介されている Flask Tornado Django を試してみようと思います。

では。さっそくやってみます。

やってみた

Bottle

軽量フレームワークとして紹介されてます。

FWのコアファイルは1ファイルのみで構成されてるみたいです。

インストール

$ mkdir bottle_test
$ cd bottle_test/
$ python3 -m venv bottle_test
$ source bottle_test/bin/activate
(bottle_test)$ pip install bottle
Collecting bottle
  Downloading https://files.pythonhosted.org/packages/bd/99/04dc59ced52a8261ee0f965a8968717a255ea84a36013e527944dbf3468c/bottle-0.12.13.tar.gz (70kB)
    100% |████████████████████████████████| 71kB 2.0MB/s 
Installing collected packages: bottle
  Running setup.py install for bottle ... done
Successfully installed bottle-0.12.13
(bottle_test)$ bottle.py --version
Bottle 0.12.13

ページ作成

index.pyを作成します。

from bottle import route, run

@route('/')
def index():
    return 'Hello Bottle!'

@route('/about')
def about():
    return 'About Page!'

run(host='localhost', port=1234, reloader=True)

起動

(bottle_test)$ python index.py 
Bottle v0.12.13 server starting up (using WSGIRefServer())...
Listening on http://localhost:1234/

ブラウザで表示された、 http://localhost:1234/ にアクセスすると、以下のような感じで表示されます。

f:id:kojirooooocks:20180629024015p:plain

ついでに作ったaboutページもこんなかんじで。

f:id:kojirooooocks:20180629024028p:plain

@route の第二引数にmethodを指定でき、POST通信指定などができます。

@route('/save', method='POST')
def save():
    return 'SavePage'

Post通信じゃないとこの通り

f:id:kojirooooocks:20180629024038p:plain

Rest通信ツールとかでPOST通信させるとちゃんと通ります。

f:id:kojirooooocks:20180629024049p:plain

テンプレートエンジン使ってみる

Bottleには、SimpleTemplate っていうテンプレートエンジンを使ってるようです。

早速やってみます。

views/base.tpl

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Bottle Test</title>
    <link rel="stylesheet" href="https://cdn.rawgit.com/Chalarangelo/mini.css/v3.0.0/dist/mini-default.min.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <header>
        <a href="/" class="button">Bottle Test</a>
    </header>
    {{ !base }}
</body>
</html>

views/index.tpl

% rebase('views/base.tpl')

<div>
    <p>はじめましてKojirockです</p>
    <p>音楽大好きです。よろしくね。</p>

    <fieldset>
        <legend align="left">お問い合わせ</legend>

        <div>
            <div><label for="name-form">お名前</label></div>
            <input type="text" id="name-form" name="name" placeholder="こじろっく" />
        </div>

        <div>
            <div><label for="mail-form">メールアドレス</label></div>
            <input type="email" id="mail-form" name="mail_address" placeholder="kojirock@kojikoji.com" />
        </div>

        <div>
            <div><label for="tel-form">電話番号</label></div>
            <input type="tel" id="tel-form" name="tel" placeholder="09011111111" />
        </div>

        <button>問い合わせる</button>
    </fieldset>
</div>

index.py

from bottle import route, run, template

@route('/')
def index():
    return template('views/index.tpl')

run(host='localhost', port=1234, reloader=True)

アクセスするとこんな感じです。

f:id:kojirooooocks:20180629024104p:plain

次行ってみます。

Flask

こちらも軽量フレームワークとしてうってるフレームワークらしいです。

拡張機能が多いようで、Bottleよりも大規模向きって感じ?みたいです。

インストール

$ mkdir bottle_test
$ cd flask_test/
$ python3 -m venv flask_test
$ source flask_test/bin/activate
(flask_test)$ pip install flask
Collecting flask
  Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
    100% |████████████████████████████████| 92kB 2.3MB/s 
Collecting Werkzeug>=0.14 (from flask)
  Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
    100% |████████████████████████████████| 327kB 2.3MB/s 
Collecting itsdangerous>=0.24 (from flask)
  Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB)
    100% |████████████████████████████████| 51kB 4.8MB/s 
Collecting click>=5.1 (from flask)
  Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB)
    100% |████████████████████████████████| 71kB 2.3MB/s 
Collecting Jinja2>=2.10 (from flask)
  Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
    100% |████████████████████████████████| 133kB 575kB/s 
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask)
  Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
Installing collected packages: Werkzeug, itsdangerous, click, MarkupSafe, Jinja2, flask
  Running setup.py install for itsdangerous ... done
  Running setup.py install for MarkupSafe ... done
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2 itsdangerous-0.24
(flask_test)$ flask --version
Flask 1.0.2

ページ作成

index.pyを作成します。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello Flask!'

if __name__ == '__main__':
    app.env = 'development'
    app.run(host='0.0.0.0', port=1234)

起動

(flask_test)$ python index.py 
 * Serving Flask app "index" (lazy loading)
 * Environment: development
 * Debug mode: off
 * Running on http://0.0.0.0:1234/ (Press CTRL+C to quit)

ブラウザで表示された、 http://localhost:1234/ にアクセスすると、以下のような感じで表示されます。

f:id:kojirooooocks:20180629024121p:plain

envを指定できたり、debugモードがあったり、結構多彩なことができるみたいです。

routing周りはBottleとほぼほぼ一緒でした。

テンプレートエンジン使ってみる

FlaskにはJinja2というテンプレートエンジンが備わってるので、早速使ってみます。

templates/base.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Bottle Test</title>
    <link rel="stylesheet" href="https://cdn.rawgit.com/Chalarangelo/mini.css/v3.0.0/dist/mini-default.min.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <header>
        <a href="/" class="button">Bottle Test</a>
    </header>

    {% block content %}{% endblock %}
</body>
</html>

templates/index.html

{% extends "base.html" %}
{% block content %}
<div>
    <p>はじめましてKojirockです</p>
    <p>音楽大好きです。よろしくね。</p>

    <fieldset>
        <legend align="left">お問い合わせ</legend>

        <div>
            <div><label for="name-form">お名前</label></div>
            <input type="text" id="name-form" name="name" placeholder="こじろっく" />
        </div>

        <div>
            <div><label for="mail-form">メールアドレス</label></div>
            <input type="email" id="mail-form" name="mail_address" placeholder="kojirock@kojikoji.com" />
        </div>

        <div>
            <div><label for="tel-form">電話番号</label></div>
            <input type="tel" id="tel-form" name="tel" placeholder="09011111111" />
        </div>

        <button>問い合わせる</button>
    </fieldset>
</div>
{% endblock %}

index.py

from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == '__main__':
    app.env = 'development'
    app.run(host='0.0.0.0', port=1234)

f:id:kojirooooocks:20180629024150p:plain

twigっぽくていいですね。

あとテンプレートファイルは templates ディレクトリ以下に置くと、自動で認識してくれるみたいです。

あとhtmlファイルのままってのも、コーダーさんは触りやすそう。

Tornado

非同期処理が得意なフレームワークらしいですね。

とにかく名前がかっこいいです。

インストール

$ mkdir tornado_test
$ cd tornado_test/
$ python3 -m venv tornado_test
$ source tornado_test/bin/activate
(tornado_test)$ pip install tornado
Collecting tornado
  Downloading https://files.pythonhosted.org/packages/cf/d1/3be271ae5eba9fb59df63c9891fdc7d8044b999e8ac145994cdbfd2ae66a/tornado-5.0.2.tar.gz (506kB)
    100% |████████████████████████████████| 512kB 2.2MB/s 
Installing collected packages: tornado
  Running setup.py install for tornado ... done
Successfully installed tornado-5.0.2

ページ作成

公式githubに書いてあったコードそのまま持ってきました。

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, Tornado")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(1234)
    tornado.ioloop.IOLoop.current().start()

f:id:kojirooooocks:20180629024207p:plain

表示されました。

テンプレート表示してみる

import os
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ],template_path=os.path.join(os.getcwd(), 'templates'))

if __name__ == "__main__":
    app = make_app()
    app.listen(1234)
    tornado.ioloop.IOLoop.current().start()

テンプレートは同じです。

f:id:kojirooooocks:20180629024218p:plain

簡単でした。

Django

あんまpython触ったことない自分でも知ってる、ど定番のフルスタックフレームワークです。

CakephpとかRailsとかの立ち位置かな??

インストール

$ mkdir bottle_test
$ cd flask_test/
$ python3 -m venv django_test
$ source django_test/bin/activate
(django_test)$ pip install django
Collecting django
  Downloading https://files.pythonhosted.org/packages/56/0e/afdacb47503b805f3ed213fe732bff05254c8befaa034bbada580be8a0ac/Django-2.0.6-py3-none-any.whl (7.1MB)
    100% |████████████████████████████████| 7.1MB 239kB/s 
Collecting pytz (from django)
  Downloading https://files.pythonhosted.org/packages/dc/83/15f7833b70d3e067ca91467ca245bae0f6fe56ddc7451aa0dc5606b120f2/pytz-2018.4-py2.py3-none-any.whl (510kB)
    100% |████████████████████████████████| 512kB 2.2MB/s 
Installing collected packages: pytz, django
Successfully installed django-2.0.6 pytz-2018.4

(django_test)$ python
Python 3.6.4 (default, Jun 29 2018, 00:24:39) 
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.get_version()
'2.0.6'

ページ作成

フルスタックフレームワークっぽい、プロジェクト作成コマンドがありました。

(django_test)$ django-admin startproject test_project
(django_test)$ tree test_project/
test_project/
├── manage.py
└── test_project
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

1 directory, 5 files

起動

(django_test)$ python test_project/manage.py runserver 1234
Performing system checks...

System check identified no issues (0 silenced).

You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

June 28, 2018 - 17:12:22
Django version 2.0.6, using settings 'test_project.settings'
Starting development server at http://127.0.0.1:1234/
Quit the server with CONTROL-C.

マイグレーションしろみたいなエラーが出ますが、とりあえず無視しときます。

f:id:kojirooooocks:20180629024237p:plain

でました。かっこいいな。

とりあえずDjangoはここまで。

終わりに

実際にweb開発で使いそうなのは、やっぱDjangoくらいのFWになりそうな気もしてます。

マジで触りなので、Djangoはもうちょい触ってみようと思いました。

スタートページだけなので、viewファイル追加したり、dbアクセスしたりなど、次はそのヘンもうちょいやってみようと思います。

お疲れ様でした。