Python の代表的なウェブアプリケーションフレームワークの1つに Flask があります:
2018053101


「マイクロフレームワーク」と称されるほどの計量な設計になっており、個人的にも Python でウェブアプリ開発する時のフレームワークとして使っています。この Flask でルーティング処理を行う場合は以下のように記述します:
  :
from flask import Flask
  :

app = Flask(__name__)

@app.route('/hello')
def hello():
  return "Hello!"

  :
  :

↑この例では GET /hello というリクエストに対して hello() 関数を割り当て、実行結果として "Hello!" という文字列を返すようにしています。


この "/hello" の部分を正規表現にして、例えば GET /(数字).xxx という形でリクエストを受け取って処理を行いたいのですが、どうすればよいか? というのが本エントリのテーマです。

答えはこんな感じになります:
  :
from flask import Flask
from werkzeug.routing import BaseConverter
  :

app = Flask(__name__)

class RegexConverter(BaseConverter):
  def __init__(self, url_map, *items):
    super(RegexConverter, self).__init__(url_map)
    self.regex = items[0]

app.url_map.converters['regex'] = RegexConverter

@app.route('/hello')
def hello():
  return "Hello!"

@app.route('/<regex("[0-9]*"):id>.xxx')
def xxx(id):
    return ( "id = %s" % (id) )

  :
  :

まず正規表現でパスを解釈するためのコンバータークラス: RegexConverter を定義し、
 <regex( XXX ):v>
という形で正規表現を処理できるようにします( XXX 部分の正規表現にマッチしたら、その結果を v という変数に代入する)。

その上で
 @app.route('/<regex("[0-9]*"):id>.xxx')
 def xxx(id):
  :

の定義によって、/(数字).xxx というパスへの GET リクエストを受け取り、この(数字)の部分を id 変数に代入した上で xxx( id ) 関数が呼び出される、という形で実現しています。

なので、例えば /123.xxx に GET リクエストを行うと、id = 123 が代入された状態で xxx( id ) 関数が実行されます。



(参考)