16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Bottle、Flaskを使ってWebサーバを起動する(Apacheも使ってやってみた)

Last updated at Posted at 2019-12-25

はじめに

PythonでWebサーバを起動する方法を学んだので、アウトプットする目的で投稿します。
どなたかの参考になれば、幸いです。

本稿では標準ライブラリであるhttpモジュールやurllibモジュールは取り上げず、bottleFlaskを使用したサンプルコードを元に説明します。
また、ApacheとPythonスクリプトを接続する方法についても説明します。

環境

  • Windows 10 home
  • Python 3.7.4

WSGI

PythonでWebの勉強をしているとWSGIという言葉がよく頻出します。

WSGIはPythonのWebアプリケーションとWebサーバーの間の標準化されたAPIのことを指します。

PythonのWebフレームワーク、Webサーバの多くはWSGIを使っています。
フレームワークやサーバの開発者以外がWSGI自体の仕組みを知る必要性は高くないことが言われています。

これから取り上げるフレームワークはすべてWSGIを使用しています。

Bottle

Bottleは1つのPythonファイルだけから作られているので、非常に試しやすく、デプロイが容易です。

次のコードでWebサーバを実行し、 http://localhost:9999 にGETメソッドでアクセスしたとき、レスポンスを返します。

前準備としてBottleをインストールしましょう。

$ pip install bottle
bottle1.py
from bottle import route, run

@route('/')
def myhome():

    return "It's my home page"

run(host='localhost', port=9999)
$ python bottle1.py
Bottle v0.12.18 server starting up (using WSGIRefServer())...
Listening on http://localhost:9999/
Hit Ctrl-C to quit.

http://localhost:9999 にアクセスします。
ステータスコード200で、ボディに It's my home page と表示されており、レスポンスの内容がわかります。
bottle1-api.png

サーバ側では、以下のように出力されています。


127.0.0.1 - - [17/Dec/2019 08:30:39] "GET / HTTP/1.1" 200 17

コードについて

BottleはURLと直後の関数を対応付けるために @route デコレータを使用します。
この場合、 /myhome() 関数 が処理するようにしています。今回はGETメソッドでリクエストを受け取りましたが、
@route(method='POST') と指定すれば、POSTメソッドによるリクエストを受け取ることができます。

run() 関数により、ウェブサーバを実行します。
このように簡単実装できるためテスト用として役に立つと思われます。

上記のコードでは、コード内でテキストを作成していましたが、
HTMLファイルを作成してそのファイルをブラウザで表示することもできます。

HTMLファイルの埋め込み

まず、bottle2.pyとindex.htmlを同じフォルダ内に用意します。

index.htmlを次のように記述します。

index.html
It's my <b>new</b> home page

bottle2.pyを次のように記述します。

bottle2.py

from bottle import route, run, static_file

@route('/')
def main():
    return static_file('index.html', root='.')

run(host='localhost', port=9999)

それではサーバーを立ち上げます。

$ python bottle2.py

http://localhost:9999にブラウザでアクセスします。
bottle2-browser.png

コードについて

static_file() 関数を呼び出すことで、引数の root が示すカレントディレクトリの index.html をレスポンスとして返すことができます。

他にも様々な機能があります。
例えば、
run() の次の引数を追加することもできます。

  • debug=True : HTTPエラーが返されたときにデバックページが作られます。(本場稼働するウェブサーバでは設定してはいけません。)
  • reloader=True : Pythonコードに変更を加えたときにブラウザにページが再ロードされる。

また、URLに引数を渡して、渡された値を使うこともできます。以下のコードで実現できます。

@route('/<thing>')
def main(thing):
    return f'{thing}'

開発者サイト:https://bottlepy.org/docs/dev/

Flask

FlaskもBottleと同じように簡単に使用できます。

まずはインストール。

pip install flask

では、flask1.pyを用意します。
要件として、

  • URL「 / 」にアクセスするとindex.htmlファイルがマッピングされるようにしましょう。
  • URL「 /sample/some 」にアクセスすると、「some」を引数の値としてブラウザに「some」と表示しましょう。
  • URL「 /sample1?thing=hello&something=world 」にアクセスすると、クエリ文字列で指定した値を flask1.html に埋め込んで表示しましょう

ここで、Flaskの静的ファイルのデフォルトディレクトリは static であるため、そのディレクトリのファイルに対するURLも /static で始まります.

flask1.py
from flask import Flask, render_template, request

app = Flask(__name__, static_folder='.', static_url_path='')

# http://localhost:9999/でアクセスされたときに返す内容
@app.route('/')
def myhome():

    return app.send_static_file('index.html')

@app.route('/sample/<thing>')
def echo(thing):

    return thing

# sample1/以降のクエリ文字列を複数の引数として受け取る
@app.route('/sample1/')
def echo1():

    kwargs = {}
    kwargs['thing'] = request.args.get('thing')
    kwargs['something'] = request.args.get('something')
    return render_template('flask1.html', **kwargs)

app.run(host='localhost', port=9999, debug=True)

次にflack1.htmlを作成します。
新しく templates というフォルダを作成します。その配下に以下のコードを保存します。

flask1.html
<html>

<body>
    It's my <b>new</b> home page
    <br>{{ thing }}
    <br>{{ something }}
</body>

</html>

サーバーを起動した後、ブラウザでhttp://localhost:9999/sample1/$thing=hello&something=worldにアクセスすると以下のように表示されます。
flask1-kwargs.png

Apache

次にApache HTTP Serverを使用して、Pythonのスクリプトを埋め込みましょう。

apacheウェブサーバーで特に優れているWSGIモジュールは mod_wsgi らしいのでこれを使用します。(引用: 入門Python3)

参考mod_wsgi公式ドキュメント

このモジュールはPythonコードをApacheプロセスの中で実行することも、Apacheと通信する別プロセスで実行することもできます。

使用OSがWindows以外であれば、すでにApache入っていますが、Windowsならダウンロードしなければなりません。
私はApache Loungeからhttpd-2.4.41-win64-VS16.zipsをダウンロードしました。
ダウンロードしたファイルにApache24があるのでそれをc:の直下におきましょう(必須ではない)

mod_wsgiを使った方法は2種類あります。
詳しくは https://pypi.org/project/mod-wsgi/

今回はpipを使用してmod_wsgiをインストールします。

$ pip install mod_wsgi

次にPythonスクリプトを記述します。
適当な場所に以下のようにwsgi.pyに記述します。(ちなみに場所はc:/var/www/test/wsgi.py)

wsgi.py

import bottle

application = bottle.default_app()


@bottle.route('/')
def home():
    return "apache ok"

次に、c:\Apache24\binに移動して
mod_wsgi-express module-configとコマンドを入力します。これによりモジュールの場所を確認できます。この情報は後述するApacheの設定に必要です。

c:\Apache24\bin>mod_wsgi-express module-config                                                   
LoadFile "c:/users/appdata/local/programs/python/python37/python37.dll"                     
LoadModule wsgi_module "c:/users/appdata/local/programs/python/python37/lib/site-packages/mod_wsgi/server/mod_wsgi.cp37-win_amd64.pyd"                                                        
WSGIPythonHome "c:/users/appdata/local/programs/python/python37"

次にC:\Apache24\conf\httpd.confのファイル末尾に以下を追記します。

httpd.conf
LoadModule wsgi_module "c:/users/appdata/local/programs/python/python37/lib/site-packages/mod_wsgi/server/mod_wsgi.cp37-win_amd64.pyd"
WSGIPythonHome "c:/users/appdata/local/programs/python/python37"

<VirtualHost *:80>
    WSGIScriptAlias / c:/var/www/test/wsgi.py
    <Directory "c:/var/www/test">
            Require all granted      
    </Directory>
</VirtualHost>

LoadModuleWSGIPythonHomeの記述はmod_wsgi-express module-configの出力を参考に適宜変更してください。
WSGIScriptAliasによって当該のwsgi.pyを探させます。

ここまでできたらapacheを起動します。C:\Apache24\binの作業ディレクトリでhttpd -k startのコマンドで起動します。

ブラウザでhttp://localhost:80にアクセスすると、wsgi.pyで記述した通りにapache okと表示されます。
apache.png

注意点

application = bottle.default_app()によりWSGI仕様にソースを改良しています。なので、コード内をWSGI仕様にしなければ外部接続ができません。またapplicationappとかにすると読み込みができません。
mod_wsgiはウェブサーバとPythonコードを結びつけるためにapplication変数を探します。

16
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?