以下は、FastAPIでJinja2を使用してHTMLを返し、CSSとJavaScriptを読み込む方法の例です。
- 前提
- python、Fast API、uvicornがインストールされていること。
FastAPIアプリケーションのルートディレクトリに、templatesとstaticという名前のディレクトリを作成します。
templatesディレクトリに、index.html
というHTMLファイルを作成します。
staticディレクトリに、cssとjsという名前のディレクトリを作成し、それぞれstyles.css
とscript.js
という名前のファイルを作成します。(中身は適用に書いて)
myapp/
├─ main.py
└─ templates/
│ └─ index.html
└─ static/
├─ css/
│ └─ style.css
└─ js/
└─ script.js
次に、FastAPIでJinja2を使用するために、jinja2パッケージをインストールします。
pip install jinja2
Jinja2(ジンジャー・ツー)は、Python製のテンプレートエンジンで、Webアプリケーションにおいて、HTMLを動的に変化する内容を埋め込んだり、条件分岐やループ処理などの制御フローを記述することができます。
main.pyには以下のように記載します。(コードの説明は後述)
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
app.mount(path="/static", app=StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
context = {"request": request}
return templates.TemplateResponse("index.html", context)
app.mount
のpath引数
を "/static" として指定した場合、HTML内の静的ファイルへのリンクは次のようになります。
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<link rel="stylesheet" href="/static/css/styles.css">
</head>
<body>
<script src="/static/js/script.js"></script>
</body>
</html>
アプリケーションを起動して、
uvicorn main:app --reload
http://127.0.0.1:8000/static/js/script.js
にアクセスするとファイルの中身が表示されるはずです。
また、cssやjavascriptに記載したコードも適用されていると思います。
コードの説明
マウント
app.mount("/static", StaticFiles(directory="static"), name="static")
このコードはFastAPIのルーティングで、"/static"
というURLパスがリクエストされた場合に、"static"というディレクトリ内の静的ファイルを提供するために使用します。
ここでは、"static"ディレクトリ内のファイルを提供するように指定しています。
name="static
は、FastAPI が内部で使用できる名前を付けます。
jinja2のurl_for
を用いてhtmlにcssやjavascript等の読み込みでよく取り沙汰されていますが、構文が長いし使わなくても読み込めるので今回は使いません。
name="static_name"
にした場合、htmlではこう呼ぶ↓
<link rel="stylesheet" href="{{ url_for('static_name', path='/style/style.css') }}">
Jinja2 テンプレート
templates = Jinja2Templates(directory="templates")
Jinja2テンプレートを使用するには、Jinja2Templatesクラスをインスタンス化する必要があります。
directory引数には、Jinja2テンプレートが保存されているディレクトリのパスを指定します。
パス操作
@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
context = {"request": request}
return templates.TemplateResponse("index.html", context)
@app.get("/")
は、FastAPIにおいてGETリクエストを受け付けるエンドポイントのデコレーターを設定している部分で、"/"はエンドポイントのパスを指定しています。
response_class=HTMLResponse
は、レスポンスの形式をHTML形式に指定しています。
async def read_root(request: Request)
は、関数定義であり、asyncを付けることで非同期関数として定義しています。requestはHTTPリクエストのデータを受け取るためのパラメーターであり、Requestクラスを指定しています。
context = {"request": request}
は、テンプレートエンジンであるJinja2に渡すコンテキストの辞書型変数を定義しています。ここではrequestを含めています。
return templates.TemplateResponse("index.html", context)
は、Jinja2テンプレートエンジンを使ってHTMLを生成するためのレスポンスを返す部分です。
TemplateResponseはFastAPIが提供するレスポンスクラスの1つで、"index.html"はHTMLテンプレートのファイル名を指定しています。
contextはテンプレートに渡すデータの辞書型変数を指定しています。
以上が、FastAPIでJinja2を使用してHTMLを返し、CSSとJavaScriptを読み込む方法でした。