アプリケーション開発ポータルサイト
ServerNote.NET
Amazon.co.jpでPC関連商品タイムセール開催中!
カテゴリー【PythonUbuntu
Python3.10でWSGI準拠の簡易HTTPサーバーを書いて常駐させる(静的ファイル対応)
POSTED BY
2023-07-15

PythonスクリプトをWebアプリとして動かすにはCGIに似たWSGIという規格で実装する。これには、Python標準のWSGIモジュールを使って簡易HTTPサーバとして直接動かすか、Apacheのモジュールを使ってApache環境下で動かすかの方法がある。

後者の実践はこちら↓

Python3.10スクリプトをApache2 + mod_wsgi + Daemon Modeで動かす

今回は前者の、実行したいPythonスクリプト自体にWSGIに準拠したWebサーバの機能を持たせて、バックグラウンドで立ち上げる。

オールインワンのソースコードはこちら。

Pythonwsgi_server.pyGitHub Source
import os
from wsgiref.simple_server import make_server

CONTENT_TYPE = {
  '.html': 'text/html; charset=utf-8', '.txt': 'text/plain; charset=utf-8', '.json': 'application/json',
  '.js': 'text/javascript', '.css':'text/css', '.ico': 'image/vnd.microsoft.icon', '.jpg': 'image/jpeg',
  '.png': 'image/png', '.gif': 'image/gif', '.webp': 'image/webp'
};

def application(environ, start_response):
  content_type = 'text/plain; charset=utf-8'
  output_text = ''
  output_data = None
  path_info = environ['PATH_INFO']

  if 'program-a' in path_info:
    output_text = 'called wsgi program-a'

  elif 'program-b' in path_info:
    output_text = 'called wsgi program-b'

  elif '.' in path_info:
    full_path = '.' + ( path_info + 'index.html' if path_info.endswith('/') else path_info)
    file_name, file_ext = os.path.splitext(full_path)
    if file_ext in CONTENT_TYPE:
      if os.path.isfile(full_path):
        with open(full_path, mode='br') as f:
          output_data = f.read()
          content_type = CONTENT_TYPE[file_ext]
      else:
        output_text = 'file path not found'
    else:
      output_text = 'not supported ext type'
  else:
    output_text = 'not supported file path'

  headers = [('Content-type', content_type)]
  start_response('200 OK', headers)

  if output_data != None:
    return [bytes(output_data)]

  return [bytes(output_text.encode('utf-8'))]

with make_server('', 8000, application) as httpd:
  print('make_server port 8000...')
  httpd.serve_forever()

・標準モジュールwsgiref.simple_serverを使う。

・ブラウザからの要求PATHを解析して、それが静的ファイルであるなら、対応可能な拡張子とContent-Typeを紐づけて、カレントディレクトリからのPATHでその実ファイルを読み込んでそのままクライアントに返す。見つからなければnot found, 対応してない拡張子のファイルを指定されたらnot supportedエラー文字列を返す。

・PATHに特定の文字列(ここではprogram-a, prgram-b)が含まれていたら、プログラムの実行であると解釈し分岐し、ここで希望のPython処理を実行する。ここではprogramが正常に呼ばれたよ、とクライアントに文字列で返すのみ。

バックグラウンド実行

python3 -m wsgi_server.py > wsgi_server.log 2>&1 &

とすると、8000番ポートでHTTP待ち受けをバックグラウンドで開始する。
標準エラー出力を標準出力にまとめてリダイレクトしている。
出力はすべてwsgi_server.logに記録される。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】