はじめに
PythonでWebサーバを起動する方法を学んだので、アウトプットする目的で投稿します。
どなたかの参考になれば、幸いです。
本稿では標準ライブラリであるhttp
モジュールやurllib
モジュールは取り上げず、bottle
、Flask
を使用したサンプルコードを元に説明します。
また、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
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
と表示されており、レスポンスの内容がわかります。
サーバ側では、以下のように出力されています。
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を次のように記述します。
It's my <b>new</b> home page
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
にブラウザでアクセスします。
コードについて
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
で始まります.
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
というフォルダを作成します。その配下に以下のコードを保存します。
<html>
<body>
It's my <b>new</b> home page
<br>{{ thing }}
<br>{{ something }}
</body>
</html>
サーバーを起動した後、ブラウザでhttp://localhost:9999/sample1/$thing=hello&something=world
にアクセスすると以下のように表示されます。
Apache
次にApache HTTP Serverを使用して、Pythonのスクリプトを埋め込みましょう。
apacheウェブサーバーで特に優れているWSGIモジュールは mod_wsgi
らしいのでこれを使用します。(引用: 入門Python3)
このモジュールは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
)
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
のファイル末尾に以下を追記します。
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>
LoadModule
、WSGIPythonHome
の記述はmod_wsgi-express module-config
の出力を参考に適宜変更してください。
WSGIScriptAlias
によって当該のwsgi.py
を探させます。
ここまでできたらapacheを起動します。C:\Apache24\bin
の作業ディレクトリでhttpd -k start
のコマンドで起動します。
ブラウザでhttp://localhost:80
にアクセスすると、wsgi.py
で記述した通りにapache ok
と表示されます。
注意点
application = bottle.default_app()
によりWSGI仕様にソースを改良しています。なので、コード内をWSGI仕様にしなければ外部接続ができません。またapplication
をapp
とかにすると読み込みができません。
mod_wsgi
はウェブサーバとPythonコードを結びつけるためにapplication
変数を探します。