5
1

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 5 years have passed since last update.

WSGIを使ってDjangoをターミナルから叩いてみた

Posted at

概要

Djangoで開発しててWSGI(Web Server Gateway Interface)ってたまに聞くけどよくわかってなかったんで調べてみたら、(あれ、これってひょっとしてpythonで直接叩ける?)とふと思ったんで、検証してみました。

まずWSGIの概要

WSGIの詳細な仕様は各々調べてもらうとして、apache+djangoをWSGIで動かしたとして、大まかに以下の図のような関係になっています。

wsgi_01.PNG

図にあるようにapacheとdjangoがやり取りするインターフェースの規格がWSGIです。
django側の入り口となるのはwsgi.pyファイルで、そのファイル内に記述されているcallableなエントリポイント(ここではapplication)をapacheが呼び出すことでやり取りします。

と書くと分かりづらいかもしれまんせんが、要は、apacheからapplication関数を呼び出して、その結果をブラウザとかに返すというような感じです。

冒頭の疑問

WSGIの利点として、WSGIの仕様に対応していれば、呼び出し側(apacheとか)やWebアプリ側(djangoとか)が何であっても正常に動作する、というのがあります。
では、以下の場合でも動作するのでは?と考えました。

wsgi_02.PNG

WSGIの仕様さえ守っていれば何でもいいんだから、呼び出し側はpythonスクリプトにしてimportしてやってもいけるのでは?

というわけで検証してみました。

検証環境

  • Centos : 7
  • Python : 3.7.1
  • Django : 2.1.7

上記の環境で、こちらのチュートリアルに沿ってPollsのviewを作って、そのviewをPythonスクリプトからWSGIを通して呼び出してみました。

Pythonスクリプトの内容

以下が、applicationを呼び出すkick_wsgi.pyスクリプトです。

kick_wsgi.py
# wsgi.pyファイルのapplicationエントリポイントのimport
from mysite.wsgi import application

# applicationに渡すメソッド
# 検証だけなので適当、表示のみ    
def start_response(status, response_headers):
    print('status           => %s' % status)
    print('response_headers => %s' % response_headers)

# applicationでGETメソッドを動作させる為に必要な最低限のパラメータ
environ = {}
environ['PATH_INFO']      = '/polls/'
environ['REQUEST_URI']    = '/polls/'
environ['REQUEST_METHOD'] = 'GET'
environ['SERVER_NAME']    = 'localhost.localdomain'
environ['SERVER_PORT']    = '80'
environ['wsgi.input']     = '' # これは謎、無いと怒られる

# application呼び出し
response = application(environ, start_response)

# HTMLのコンテンツ表示
print('content          => %s' % response.content)

applicationの第2引数:start_responseはdjangoの結果を受け取るだけなんでここでは適当です。重要なのは第1引数:environで、上記のスクリプトを見るとenvironで渡すパラメータには見覚えのあるパラメータ名が並んでいると思います。とりあえずdjangoを騙くらかして動かせればいいんで、最低限必要そうなのをセットしてます。

スクリプトの実行結果

[guest@localhost hoge]$ PYTHONPATH=. python kick_wsgi.py 
status           => 200 OK
response_headers => [('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'SAMEORIGIN'), ('Content-Length', '40')]
content          => b"Hello, world. You're at the polls index."

想定通りの結果が返ってきました!

まとめ

djangoをWSGIを使ってキックするのは思いのほかシンプルで簡単でした。シンプルだからこそ、WSGIに対応しているWebサーバやWebアプリであれば部品のように交換して動作させられるんでしょう。

あと私のようなターミナル大好き人間にとってはフレームワークやらなんやらをターミナルから直接叩ける方法があると嬉しかったりするのでこの記事は備忘録用でもあります。(ターミナルから直接叩けて何が嬉しいのか・・それはターミナル好きにしかわからない・・)

5
1
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
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?