Python
Flask

Flaskで静的ファイルの格納ディレクトリとURLを変更する

More than 1 year has passed since last update.

1. はじめに

今回はflaskで静的ファイルにアクセスするためのURLのパスと、格納ディレクトリの変更方法について説明します。また、通常REST APIでは静的ファイルは不要なため、これを無効にする方法についても説明したいと思います。

1.1. 検証環境

  • Python 2.7.13
  • Flask 0.12.2

2. 格納ディレクトリはstatic_folderで変更

flaskで静的ファイルを格納するディレクトリはstatic_folderで変更することができます。
デフォルトの設定はstaticディレクトリです。

2.1. ソースコード

dir_change_app.py
# -*- coding: utf-8 -*-
import os
from flask import Flask

# flask
# app = Flask(__name__)
# 相対パスで指定
app = Flask(__name__, static_folder='resources')
# 絶対パスで指定(ディレクトリは/)
# app = Flask(__name__, static_folder='C:/tmp/www')
# 絶対パスで指定(ディレクトリは\\)
# app = Flask(__name__, static_folder='C:\\tmp\\www')

# main
if __name__ == "__main__":
    # Flaskのマッピング情報を表示
    print app.url_map
    app.run(host=os.getenv("APP_ADDRESS", 'localhost'), \
    port=os.getenv("APP_PORT", 3000))

flaskのurl_mapで現在のマッピング情報を確認することができます。

2.2. 動作確認

デフォルトのまま、指定なし
C:\demo>python dir_change_app.py
Map([<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>])
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
127.0.0.1 - - [19/Aug/2017 14:17:28] "GET /static/memo.txt HTTP/1.1" 200 -

デフォルトでは、カレントディレクトリにstaticディレクトリがある前提で起動します。ですので、staticディレクトリを作成してmemo.txtを格納した後、Webブラウザでhttp://localhost:3000/static/memo.txtにアクセスするとmemo.txtが表示されます。

相対パスで指定
C:\demo>python dir_change_app.py
Map([<Rule '/resources/<filename>' (HEAD, OPTIONS, GET) -> static>])
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
127.0.0.1 - - [19/Aug/2017 14:03:36] "GET /resources/demo.js HTTP/1.1" 200 -

相対パスでresourcesディレクトリを指定すると、Webブラウザからはhttp://localhost:3000/resources/demo.jsのようにアクセスすることになります。

絶対パスで指定
C:\demo>python dir_change_app.py
Map([<Rule '/www/<filename>' (HEAD, OPTIONS, GET) -> static>])
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
127.0.0.1 - - [19/Aug/2017 14:04:57] "GET /www/demo.js HTTP/1.1" 200 -

絶対パスでも指定することができます。Windowsの場合はディレクトリの区切りは/\\で記述します。
絶対パスの場合、パスの最後尾のディレクトリ名がURLのパス名となります。デモのstatic_folder='C:/tmp/www'の場合は/wwwになります。
URLを変更する方法がこの後の説明になります。

3. アクセスするURLはstatic_url_pathで変更

flaskで静的ファイルにアクセスするURLはstatic_url_pathで変更することができます。
デフォルトの設定はstatic_folderで指定したディレクトリ名と同じになります。

3.1. ソースコード

url_change_app.py
# -*- coding: utf-8 -*-
import os
from flask import Flask

# flask
app = Flask(__name__)
# URLのパスを指定
app = Flask(__name__, static_url_path='/js')
# URLのパスに複数の区切りを利用
# app = Flask(__name__, static_url_path='/h/o/g/e')
# URLのパスに何も指定したくない場合は空文字を指定
# app = Flask(__name__, static_url_path='')

# main
if __name__ == "__main__":
    # Flaskのマッピング情報を表示
    print app.url_map
    app.run(host=os.getenv("APP_ADDRESS", 'localhost'), \
    port=os.getenv("APP_PORT", 3000))

ここではstatic_folderで格納ディレクトリを指定していないため、デフォルトの通り、カレントディレクトリのstaticディレクトリに静的ファイルを格納します。

static_url_pathで指定する値は必ず/で始まる必要があるので注意してください。

3.2. 動作確認

普通にURLのパスを指定
C:\demo>python url_change_app.py
Map([<Rule '/js/<filename>' (HEAD, OPTIONS, GET) -> static>])
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
127.0.0.1 - - [19/Aug/2017 14:57:08] "GET /js/demo.js HTTP/1.1" 200 -

格納ディレクトリはstaticですが、/js/demo.jsでアクセスできるようになります。

URLのパスに複数の区切りを指定
C:\demo>python url_change_app.py
Map([<Rule '/h/o/g/e/<filename>' (HEAD, OPTIONS, GET) -> static>])
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
127.0.0.1 - - [19/Aug/2017 14:57:51] "GET /h/o/g/e/demo.js HTTP/1.1" 200 -

URLでアクセスする際に利用するパスのため、複数の区切りを指定しても問題なくdemo.jsにアクセスできます。

パスに何も指定しない場合
C:\demo>python url_change_app.py
Map([<Rule '/<filename>' (HEAD, OPTIONS, GET) -> static>])
 * Running on http://localhost:3000/ (Press CTRL+C to quit)
127.0.0.1 - - [19/Aug/2017 14:58:39] "GET /demo.js HTTP/1.1" 200 -

/demo.jsのように不要なパスを指定することなく、格納ディレクトリ内のファイル名を指定するだけでアクセスできます。

4. 無効にするにはstatic_folder=Noneを設定

4.1. ソースコード

no_static_app.py
# -*- coding: utf-8 -*-
import os
from flask import Flask

# flask
# 静的ファイルの機能は無効
app = Flask(__name__, static_folder=None)

# main
if __name__ == "__main__":
    # Flaskのマッピング情報を表示
    print app.url_map
    app.run(host=os.getenv("APP_ADDRESS", 'localhost'), \
    port=os.getenv("APP_PORT", 3000))

4.2. 動作確認

静的ファイルの機能は無効
C:\demo>python no_static_app.py
Map([])
 * Running on http://localhost:3000/ (Press CTRL+C to quit)

マッピング情報を見ると何も設定されておらず、静的ファイルの機能が無効になっていることが分かるかと思います。

5. さいごに

今回はflaskにおける静的ファイルの格納ディレクトリと、静的ファイルにアクセスするURLの変更方法について説明しました。

Pythonでマイクロサービス(概要編)のとおりマイクロサービス(REST API)を作成するのが目的のため、本来、静的ファイルの機能は不要なのですが、マッピング情報を見て自動でこの機能が有効になっていることが分かりました。

自分と同じく気付いていない人もいるのではと思い、今回記事としてまとめてみました。

flask以外のライブラリでもそうですが、セキュリティ的な観点から、デフォルトで有効になっている機能についてはしっかりと調査し、内容を把握してから利用したいと思います。