Symfoware

Symfowareについての考察blog

Python webサーバー、フレームワークを使用せずにwebアプリ作成

個人的なツール用として簡単なwebアプリを作成したかったのですが、
なんとか素のPythonだけで実装できないか考えてみました。


BaseHTTPServer,SimpleHTTPServer



Python 2系の場合、BaseHTTPServerが標準で組み込まれています。
※Python 3系ではhttp.server

これらを使用すれば良さそうです。

作成するwebアプリでは、htmlやjsファイルは通常通りget。
javascriptからのデータ取得はPOSTのみで行うことにし、
実装を簡単にしました。



POSTデータの解析



POSTデータの解析をどうやれば良いかわからず探したところ、
このドキュメントが参考になりました。

BaseHTTPServer – web サーバを実装するベースクラス

cgi.FieldStorageを使用すれば解析できそうです。



サンプルアプリケーション



アプリケーションは
・index.html
・app.js
・view.py
の3つのファイルで構成しました。

名前を入力すると、応答してくれる簡単なものです。

731_01.png


・index.html


  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Simple Web</title>
  6.     <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  7.     <script type="text/javascript" src="./static/js/app.js"></script>
  8. </head>
  9. <body>
  10. <h3>Pythonのみで簡易Webアプリ</h3>
  11. <input type="text" id="name">
  12. <input type="button" id="echo" value="ajaxでデータ取得">
  13. <div id="result"></div>
  14. </body>
  15. </html>




・app.js


  1. $(function() {
  2.     
  3.     // 入力された値をPOSTで送信
  4.     // 応答を表示する
  5.     $('#echo').on('click', function(){
  6.         var name = $('#name').val();
  7.         $.ajax({
  8.             type: 'POST',
  9.             dataType: 'json',
  10.             data: {'name':name},
  11.             url: 'echo',
  12.         }).done(function (data) {
  13.             $('#result').html(data.message);
  14.         });
  15.     });
  16.     
  17. });




・view.py


  1. # -*- coding: utf-8 -*-
  2. import cgi
  3. import json
  4. import BaseHTTPServer
  5. import SimpleHTTPServer
  6. class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  7.     
  8.     # POSTの実装(GETは継承元にある)
  9.     def do_POST(self):
  10.         
  11.         # リクエストに対応したメソッドを呼び出す
  12.         route = self.path.split('/')[-1]
  13.         if not hasattr(self, route):
  14.             self.send_response(500)
  15.             self.end_headers()
  16.             return
  17.         
  18.         # POSTデータの解析
  19.         form = self._parse_form()
  20.         response = getattr(self, route)(form)
  21.         
  22.         # レスポンス作成
  23.         self.send_response(200)
  24.         self.send_header("Content-type", 'application/json')
  25.         self.send_header("Content-Length", len(response))
  26.         self.end_headers()
  27.         self.wfile.write(response)
  28.         
  29.         
  30.     def _parse_form(self):
  31.         if 'Content-Type' not in self.headers:
  32.             return None
  33.         
  34.         # POSTデータがあれば内容を解析する
  35.         return cgi.FieldStorage(
  36.             fp=self.rfile,
  37.             headers=self.headers,
  38.             environ={
  39.                 'REQUEST_METHOD':'POST',
  40.                 'CONTENT_TYPE':self.headers['Content-Type'],
  41.             }
  42.         )
  43.     
  44.         
  45.         
  46.     # --- router
  47.     def echo(self, form):
  48.         
  49.         name = u'名無し'
  50.         
  51.         # データが送信されていれば、内容を応答
  52.         if 'name' in form:
  53.             name = form['name'].value
  54.         
  55.         message = u'%sさんこんにちは' % name
  56.         data = {'message' : message}
  57.         return json.dumps(data)
  58.     
  59.     
  60. if __name__ == '__main__':
  61.     
  62.     server_address = ('0.0.0.0', 8000)
  63.     httpd = BaseHTTPServer.HTTPServer(server_address, MyHandler)
  64.     print('Serving HTTP on 0.0.0.0 port %d ...' % server_address[1])
  65.     print('use <Ctrl-(C or break)> to stop')
  66.     httpd.serve_forever()
  67.     





$ python view.py

と実行して、http://localhost:8000にアクセスします。

731_02.png


適当な文字列を入力してボタンをクリックすると、応答が得られました。

731_03.png


なんとかPython単独でwebアプリケーションが作成できそうです。



【参考URL】

SimpleHTTPServer — 簡潔な HTTP リクエストハンドラ
BaseHTTPServer – web サーバを実装するベースクラス
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/01/30(月) 23:53:09|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ