Python | Web フレームワーク:静的ファイル

Python
スポンサーリンク

概要(静的ファイル=「ただ置いておくだけで中身が変わらないファイル」)

静的ファイルは、

「サーバー側で中身を計算したり書き換えたりせず、そのままブラウザに渡すだけのファイル」

のことです。

具体的には、よくあるものだと

  • 画像(.png, .jpg, .gif)
  • CSS ファイル(デザイン)
  • JavaScript ファイル(フロント側の動作)
  • ダウンロードさせたい PDF やドキュメント

などが「静的ファイル」です。

Python の Web フレームワーク(FastAPI を例にします)では、

「/static みたいな URL に来たら、特定フォルダ内のファイルをそのまま返す」

という設定をしてあげることで、静的ファイルを配信できます。


動的レスポンスと静的ファイルの違いをイメージする

動的レスポンス(普通の API やテンプレート)は「その場で作るもの」

まず、普段書いている API を思い浮かべてください。

from fastapi import FastAPI

app = FastAPI()

@app.get("/hello")
def hello():
    return {"message": "hello"}
Python

これは「動的レスポンス」です。

リクエストが来るたびに関数が呼ばれ、
その場で JSON を作って返しています。

データベースを読んだり、
計算したり、
条件によって結果が変わったりします。

静的ファイルは「サーバーのフォルダに置いておいたものを、そのまま返す」

一方、静的ファイルは

  • サーバーの中の特定フォルダ(例:static/)に最初から置いてある
  • リクエストが来ても、中身は変えずにそのまま返す

という性質のものです。

例えば、

/static/logo.pngstatic/logo.png という画像ファイルを返す
/static/app.cssstatic/app.css という CSS ファイルを返す

というような対応です。

「Python の関数で作る」のではなく、
「ファイルシステムにあるものを読み出して返す」だけ、という感覚です。


FastAPI で静的ファイルを配信する基本(StaticFiles)

フォルダ構成の例を決める

まず、こんなフォルダ構成を考えます。

project/
  main.py
  static/
    logo.png
    app.css
    app.js

static/ フォルダの中に、
ブラウザに配りたいファイルを入れておきます。

StaticFiles をマウントするコード

FastAPI では、StaticFiles を使って静的ファイル配信を設定します。

from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

app = FastAPI()

app.mount("/static", StaticFiles(directory="static"), name="static")
Python

この 1 行が、とても重要です。

app.mount("/static", ...)
「/static というパス配下は、このアプリに任せる」という宣言です。

StaticFiles(directory="static")
この部分が、「static フォルダの中のファイルをそのまま返すアプリ」です。

つまり、

/static/logo.png にアクセス → project/static/logo.png が返る
/static/app.css にアクセス → project/static/app.css が返る

という動きになります。

ブラウザで http://localhost:8000/static/logo.png にアクセスすると、
画像がそのまま表示されます。

「mount して別のミニアプリをぶら下げる」という感覚

app.mount は、
「/static という URL パス以下を、StaticFiles という別アプリに委ねる」
というイメージです。

FastAPI 本体(/hello とか /users とか)は、普通の API を返す担当。
StaticFiles は、「/static 以下だけ担当するミニアプリ」。

URL 空間を分けて、「ここから先は静的ファイル係」と切り分けている、という感覚を持っておくと分かりやすいです。


非API系(HTML+JS+CSS)での静的ファイルの使い方イメージ

HTML から CSS や JS を読み込むときのパス

もし FastAPI で HTML を返していて、
その HTML から CSS や JS を読み込みたいとします。

例えば、テンプレートやシンプルな HTML を返している場合。

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def index():
    return """
    <html>
      <head>
        <link rel="stylesheet" href="/static/app.css">
      </head>
      <body>
        <h1>Hello</h1>
        <script src="/static/app.js"></script>
      </body>
    </html>
    """
Python

ここで href="/static/app.css" と書いているので、
ブラウザは /static/app.css にアクセスしに行きます。

StaticFiles を /static にマウントしているので、
FastAPI は static/app.css を返してくれます。

つまり、

HTML 側では「/static/ファイル名」で参照する
サーバー側では「StaticFiles(directory=’static’)」でフォルダを指定する

この 2 点を合わせることで、静的ファイルを自然に配信できます。


どんなものを静的ファイルにするか(設計の感覚)

1. 画像・CSS・JS は基本的に静的ファイル

  • サイトのロゴやアイコン画像
  • ページの見た目(レイアウトや色)を決める CSS
  • フロント側の動きを定義する JavaScript

これらは(ビルドのときに生成したとしても)
サーバー側では「ただ置いておくだけ」で中身を変えないことがほとんどです。

そのため、静的ファイルとして配信するのが自然です。

static/img/logo.png
static/css/app.css
static/js/app.js

のようにフォルダを分けておくと整理しやすくなります。

2. ダウンロードさせたいファイルも静的で OK な場合が多い

ユーザーに配布する PDF や、
ずっと変わらないマニュアル、テンプレートファイル(Excel など)も、
単純に static/ に置いて配信できます。

例えば、

/static/docs/manual.pdf

のように URL を設計しておけば、
ブラウザが直接開く・ダウンロードする挙動になります。


静的ファイルにしないほうがいいもの(動的に生成したいもの)

毎回中身が変わるものは「動的レスポンス」に任せる

逆に、「静的ファイルっぽく見えても静的にしないほうがいいもの」もあります。

例えば、

  • ユーザーごとに中身が違うレポート PDF
  • 毎回最新データを反映した CSV
  • 認可チェックが必要なファイル(特定ユーザーだけ見られるもの)

などです。

これらは、

エンドポイントにアクセスされたタイミングで生成する
または、事前に生成しておきつつも、認証チェックをしてから返す

といった「動的な処理」が必要になります。

FastAPI では、FileResponse などを使って
「ファイルを返す API」を作ることもできます。

from fastapi import FastAPI
from fastapi.responses import FileResponse

app = FastAPI()

@app.get("/download-report")
def download_report():
    # 本当はここでレポートを生成したりする
    file_path = "generated/report.pdf"
    return FileResponse(path=file_path, filename="report.pdf")
Python

これは「静的ファイルサーバー」ではなく、
「ファイルを返す動的 API」です。

静的ファイルとの違いは、

  • URL アクセスのたびに Python の関数が動く
  • 認証・認可チェックを挟める
  • ファイル生成やログ記録を柔軟に制御できる

というところです。


本番運用のイメージ(FastAPI が全部やるか、Nginx などに任せるか)

小規模・開発中:FastAPI の StaticFiles で十分

開発中や小さなサービスであれば、

app.mount("/static", StaticFiles(directory="static"), name="static")

だけで静的ファイルの配信を FastAPI に任せてしまって問題ありません。

Uvicorn で起動しながら、

http://localhost:8000/static/app.css
http://localhost:8000/static/logo.png

のようにアクセスして、
ブラウザで動作を確認できます。

大規模・本番:Nginx 等のフロントサーバーに任せることが多い

本番運用では、

  • 画像や CSS / JS の量が増える
  • キャッシュ制御(ブラウザや CDN)を細かく設定したい
  • ものすごく大量の静的ファイルアクセスが来る可能性がある

といった理由から、

Nginx や Apache などの Web サーバーが
静的ファイルの配信を担当し、

FastAPI は純粋に API や動的レスポンスだけに集中する

という構成を取ることが多いです。

その場合でも、開発中は FastAPI の StaticFiles を使っておいて、
本番のフロント設定ができた段階で
静的ファイルの扱いをフロントに移す、というやり方が自然です。

初心者のうちは、
「まずは FastAPI の StaticFiles で概念を掴む」が良いです。


まとめ(静的ファイルは「URL とフォルダの対応を決めておくだけ」)

Python の Web フレームワーク(FastAPI)における静的ファイルを整理すると、こうなります。

  • 静的ファイルは、サーバー側で中身を生成・変更せず、そのまま返すだけのファイル(画像・CSS・JS・PDF など)。
  • FastAPI では app.mount("/static", StaticFiles(directory="static"), name="static") と書くことで、「/static 以下の URL は static/ フォルダ内のファイルを返す」という設定ができる。
  • HTML からは /static/... を参照し、サーバー側では StaticFiles の directory でフォルダを対応させることで、CSS や JS を自然に読み込める。
  • 毎回中身が変わるファイルや、認可チェックが必要なものは「静的ファイル」ではなく、FileResponse などを使った動的なファイル配信 API として扱うほうがよい。
  • 開発・小規模なら StaticFiles で十分、大規模・本番では Nginx 等に静的配信を任せ、FastAPI は動的レスポンス専用にする構成がよく使われる。

タイトルとURLをコピーしました