Skip to content

Instantly share code, notes, and snippets.

@p--q

p--q/Python6.py Secret

Last active August 29, 2015 14:01
Show Gist options
  • Save p--q/558d9531cff0dcc8e103 to your computer and use it in GitHub Desktop.
Save p--q/558d9531cff0dcc8e103 to your computer and use it in GitHub Desktop.
マルチスレッド化したWSGIサーバの例
# -*- coding: utf-8 -*-
from wsgiref import simple_server
import socketserver
class ThreadedWSGIServer(socketserver.ThreadingMixIn, simple_server.WSGIServer): # WSGIServerをマルチスレッド対応にしたクラスを作成。
pass
def calculator(lst): # 初期値をリストで受け取るジェネレータ。
init_lst = lst.copy() # リストinit_lstに初期値を取得する。
while True: # next()かsend()が呼ばれるたびにyieldで値を返して一時停止する。
send_value = (yield lst) # sendメソッドの引数を受け取る。next()のときはNoneが返る。
if send_value: # sendメソッドでNone以外が返ったとき。
lst = init_lst.copy() # リストlstを初期化する。
else: # next()が呼び出されたとき。
lst[0] += 1 # リストの0番目の要素に1を加える。
lst[1] *= 2 # リストの1番目の要素を2倍にする。
def app(environ, start_response): # WSGIアプリ。辞書environを引数にとる。
start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')]) # start_responseを設定。
path = environ['PATH_INFO'] # 辞書environからURLのパスを取得。
if path == "/stop": # パスがstopのとき。
server.shutdown() # WSGIサーバを停止終了する。
yield "終了".encode() # 終了と出力。このあとにスクリプトが終了。
elif path == "/reset": # パスがresetのとき。
c, val = calc.send(path) # ジェネレータに引数を渡す。引数はNone以外なら何でも可。
else:
c, val = next(calc) # ジェネレータcalcの次の値を取得。
yield '{0}(=2<sup>{1}</sup>)を2倍にした計算結果 2<sup>{2}</sup>={0}<br>'.format(val//2, c-1, c, val).encode()
yield '<br>'.encode()
yield '<a href="http://{0}:{1}">この計算結果をさらに2倍する</a><br>'.format(host, port).encode()
yield '<br>'.encode()
yield '<a href="http://{0}:{1}/reset">最初に戻る</a><br>'.format(host, port).encode()
yield '<br>'.encode()
yield '<a href="http://{0}:{1}/stop">WSGIサーバを停止する</a>'.format(host, port).encode()
if __name__ == "__main__": # ここから開始。
calc = calculator([1, 2]) # calcにリスト[1, 2]を引数にしてジェネレータcalculator()を代入。グローバルスコープ。
host, port = "localhost", 8000 # ホスト名とポート番号を設定。
server = simple_server.make_server(host, port, app, ThreadedWSGIServer) # appへの接続を受け付けるThreadedWSGIServerを生成。
url = "http://{}:{}".format(host, port) # 出力先のurlを取得。
import threading
server_thread = threading.Thread(target=server.serve_forever) # 要求によりスレッドを生成するメソッドをtargetに指定。
server_thread.start() # スレッドの受付を開始。
import webbrowser
webbrowser.open_new_tab(url) # デフォルトのブラウザでurlを開く。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment