概要
前回ご紹介した、ブラウザ上でサーバ上の音源を再生するFlask実装を、Blueprintを使って実用化した例です。
※前回の記事も合わせて読んでいただければ幸いです。
ディレクトリ構成
devディレクトリの中に、flask_play_audio
のようなアプリをいくつも制作することを想定しています。
project_root ├ dev/ │ ├ another_yourapp/ │ │ │ └ flask_play_audio/ │ ├ music/ │ │ └ audio.mp3 │ ├ templates/ │ │ └ dev │ │ └ flask_play_audio │ │ └ index.html │ └ views.py └ run.py
ソースコード
views.py
from flask import Blueprint from flask import render_template, send_from_directory app_name = 'flask_playback_audio' app_path = f"dev/{app_name}" flask_playback_audio = Blueprint(app_name, __name__, template_folder='templates') @flask_playback_audio.route('/') def index(): return render_template(f'{app_path}/index.html') #ポイント1 @flask_playback_audio.route("music/<path:filepath>") def flask_playback_audio_send_music(filepath): return send_from_directory(f"{app_path}/music", filepath) #ポイント2
Blueprintを使うにあたっての注意すべき点がポイント1、2です。
ポイント1:index.htmlの配置とディレクトリ構成
Blueprintでは、どうやら全てのtemplates/
のファイルを参照するような実装になっているようです
例えば、上記ディレクトリ構成において、another_yourapp
とflask_play_audio
のtemplates
ディレクトリにそれぞれ同名のindex.html
を置くと正しく動作しないようです。
そのため、templates
以下にプロジェクトのディレクトリ構成を反映させてindex.html
を配置するという
手法がよく採用されているようです。
今回の場合ですと、上記ディレクトリ構成のように、templates/apps/flask_play_audio/index.html
という配置になります。
Python + Flask + Blueprint で複数のアプリケーションを登録する際に気をつけること - Qiita
Flask Blueprint における template_folderパス解決の罠 - 真面目に、強く、上品に
ポイント2:サーバから送るファイルの配置
ローカルサーバ、本番サーバ両方で試したところ、以下の実装で動きました。
send_from_directory
に、project_root
から見たファイルパスを与えてやることで実現できました。
run.py(一部掲載)
公式のBlueprintの使い方通り、Blueprintインスタンスをappに登録します。 Modular Applications with Blueprints — Flask Documentation (1.0.x)
Pythonの仕様やパッケージ構成における混乱を避けるため、ディレクトリ名やURLはスネイクケースもしくはキャメルケースで命名するのがよいと思います。
from dev.flask_playback_audio.views import flask_playback_audio app = Flask(__name__) # Regiter apps app.register_blueprint(flask_playback_audio, url_prefix="/dev/flask_playback_audio")
index.html
<!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Download audio</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <audio src="music/audio.mp3" controls></audio> </body> </html>
デモ
http://www.wizardcraft.works/dev/flask_playback_audio/www.wizardcraft.works