1. はじめに
今回はflaskで静的ファイルにアクセスするためのURLのパスと、格納ディレクトリの変更方法について説明します。また、通常REST APIでは静的ファイルは不要なため、これを無効にする方法についても説明したいと思います。
1.1. 検証環境
- Python 2.7.13
- Flask 0.12.2
2. 格納ディレクトリはstatic_folder
で変更
flaskで静的ファイルを格納するディレクトリはstatic_folder
で変更することができます。
デフォルトの設定はstatic
ディレクトリです。
2.1. ソースコード
# -*- 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. ソースコード
# -*- 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. 動作確認
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
でアクセスできるようになります。
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. ソースコード
# -*- 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以外のライブラリでもそうですが、セキュリティ的な観点から、デフォルトで有効になっている機能についてはしっかりと調査し、内容を把握してから利用したいと思います。