FastHTML × MonsterUIでつくる、モダンなWeb _by Python

# はじめに
もう6月ですね。
なんか、2025年ももうそろそろ半年すぎるっていうね...
月日の速さを感じます。じぶんがうごいていないようだー。

ということで！
**Pythonでちょー簡単にWebアプリケーション開発する方法**をちょー簡単にお届けします。
どうも！
この記事の投稿者のchi1180です。😆

# なんぞや

以下のYouTube動画をご視聴いただければ全てわかります：
[発見した動画-Modern Web Apps in Pure Python](https://www.youtube.com/watch?v=K6cXqv_yMCs)
↑この動画は、チャンネル登録者数42万人超えのYouTubeチャンネル*NeuralNine*が投稿してくださったもので、非常に有益でした（私にとって。そしてきっとこの記事を読んでくださっている貴方にとっても！）。

純粋に、Pythonだけで現代的なWebアプリを作成しよーぜという話です🚀

**FastHTML**と**MonsterUI**を使用して開発を行います！

### FastHTMLとは

Pythonで動作するWebアプリケーション開発のためのフルスタックWebフレームワークです。FastAPIからインスピレーションを受けて開発されており、PythonのAPIを通じてインタラクティブなWebアプリケーションを素早く開発できるのが特徴です。

#### PythonだけでWebアプリを作成可能

FastHTMLを使えば、**HTMLやCSS、JavaScriptの知識がなくても**、**Pythonコードだけで**Webアプリケーションを構築できます。**フロントエンドのUI構築には「htmx」を利用でき**、JavaScriptをほとんど書かずに動的な処理を実現できます。

#### シンプルなコード構成

コードやファイル構成が非常にシンプルで、動的で複雑なUIもコンポーネントごとに簡潔なコードで記述できます。余計なファイルを必要としないため、開発効率が高いです。

:::note info

#### htmxとは

JavaScriptを直接記述せずに、**HTMLの属性を拡張**して動的なWebページやインタラクティブなUIを実現できる軽量な**JavaScriptライブラリ**です。

**HTML属性による操作**
`hx-get`や`hx-post`、`hx-swap`などのカスタム属性をHTMLに追加することで、Ajax通信やページの一部更新、イベントトリガーなどを簡単に実装できます。

※**ぶち**人気者です。

[Click to more information about htmlx](https://qiita.com/tsmd/items/0d07feb8e02cfa213cc4)

:::

### MonsterUIとは

Pythonで書いたコードを最小限の手間で美しいWebアプリケーションに変換できるUIフレームワークです。

FastHTMLと**Tailwind CSS**を組み合わせており、データサイエンティストや機械学習エンジニア、開発者が、従来の複雑なUIフレームワークを使わずに、迅速にWebインターフェースを構築できます。

[Click to more information about MonsterUI](https://www.answer.ai/posts/2025-01-15-monsterui.html)

:::note info

#### tailwindcssとは

**ユーティリティファースト**のCSSフレームワークです。
従来のCSSフレームワーク（例：Bootstrapなど）のようにボタンやテーブルなどのコンポーネント用に定義済みのクラスを提供するのではなく、「ユーティリティクラス」と呼ばれる小さなスタイル単位のクラスを多数用意している点が特徴です。

これらのユーティリティクラス（例：bg-blue-500やtext-centerなど）をHTMLのclass属性に直接指定して組み合わせることで、**柔軟かつ効率的にデザインを作成**できます。
例えば、背景色や文字色、余白、フォントサイズなどの細かなスタイルを個別のクラスで指定できるため、**独自性の高いUIを簡単に実現**できます。

:::

# コード

:::note warn
事前に以下のインストールコマンドを実行しといてね💻️：
```bash:in your working space terminal
pip install python-fasthtml monsterui
````
:::

```python:main.py
# FastHTML x MonsterUI カウンターアプリ - 初学者向け詳細解説

# 必要なライブラリのインポート
from fasthtml.common import serve, Div, Span  # FastHTMLの基本機能
from monsterui.all import H1, H2, Card, Button, Form, Input, ButtonT, Container, ContainerT, Theme, fast_app

# アプリケーションの初期化
# fast_app()でFastHTMLアプリを作成
# Theme.blue.headers()で青いテーマのCSSヘッダーを適用
app, rt = fast_app(hdrs=Theme.blue.headers())

# カウンターの初期値を設定
# グローバル変数として定義（実際のアプリでは別の方法が推奨）
count = 0

# メインページのルート定義
# @rtデコレータでルートを登録（デフォルトは"/"パス）
@rt
def index():
    """
    メインページを表示する関数
    HTMXを使用してリアルタイムでカウンターを更新
    """
    return Container(  # 全体を包むコンテナ
        # ページタイトル
        H1("🚀 Counter App", cls="text-3xl font-bold text-center mb-6 mt-6"),
        
        # カウンター表示用のカード
        Card(cls="p-6 text-center mb-4")(  # パディング、中央揃え、下マージン
            # カードのタイトル
            H2("Click the button!", cls="mb-4"),
            
            # ボタンとカウンター表示の横並びレイアウト
            Div(cls="flex items-center justify-center gap-4")(
                # マイナスボタン
                # hx_post="/dec": クリック時に/decへPOSTリクエスト
                # hx_target="#count": レスポンスを#count要素に反映
                Button("-", hx_post="/dec", hx_target="#count"),
                
                # カウンター表示部分
                # id="count": HTMXのターゲットとして使用
                Span(id="count", cls="text-2xl font-bold")(str(count)),
                
                # プラスボタン
                # hx_post="/inc": クリック時に/incへPOSTリクエスト
                # hx_target="#count": レスポンスを#count要素に反映
                Button("+", hx_post="/inc", hx_target="#count")
            )
        )
    )

# カウンターを増やすエンドポイント
@rt("/inc", methods=["POST"])  # /incパスでPOSTメソッドを受け付け
def inc():
    """
    カウンターを1増やして新しい値を返す
    HTMXが自動的に#count要素を更新
    """
    global count  # グローバル変数にアクセス
    count += 1    # カウンターを1増やす
    return count  # 新しい値を返す（HTMLとして#count要素に挿入される）

# カウンターを減らすエンドポイント
@rt("/dec", methods=["POST"])  # /decパスでPOSTメソッドを受け付け
def dec():
    """
    カウンターを1減らして新しい値を返す
    HTMXが自動的に#count要素を更新
    """
    global count  # グローバル変数にアクセス
    count -= 1    # カウンターを1減らす
    return count  # 新しい値を返す（HTMLとして#count要素に挿入される）

# サーバーを起動
# デフォルトでlocalhost:5001で起動
serve()

"""
🔍 コードの動作の流れ：

1. ユーザーがブラウザでアクセス
2. index()関数が実行されてHTMLが生成・表示
3. ユーザーが+または-ボタンをクリック
4. HTMXが/incまたは/decにPOSTリクエストを送信
5. サーバーがinc()またはdec()関数を実行
6. 新しいカウンター値が返される
7. HTMXが#count要素の内容を自動更新
8. ページリロードなしでカウンターが更新される

💡 重要なポイント：
- HTMXのおかげでJavaScriptを書かずに動的な更新が可能
- MonsterUIのコンポーネントで美しいUIを簡単に作成
- FastHTMLのルーティングシステムで簡潔なコード
"""
````

以上のような感じです！
**めっちゃかんたん**でしょう🎉

あとは、このファイル（main.py）を実行すれば、[http://localhost:5001/](http://localhost:5001/)に飛ぶだけでOKです。

記事の冒頭で紹介した動画では、カウンター機能以外にも、hello機能とかが実装されていたりします。
また、To Doアプリの作成についても動画に含まれているので、ぜひ見てみてください。

# 最後に

今回は、
**FastHTML × MonsterUIでつくる、モダンなWeb _by Python** という体で記事を書かせていただきました！

最後まで読んでくれてありがとう！

# 雑談

記述したプログラムについてなんだけど、カウンターの部分で、たしかにはじめは`0`が表示されるんだけど、数値を変更するとcount=0になったときempty stringになるんだよね。
|クリック|countの数|webで表示されてるcount|
|------|--------:|-------------------|
|初期|0|0|
|+|1|1|
|-|0||

なんでか、わかる人いたら教えてほしい。いい加減な記事でごめんなさい🙇

ついでですが、YouTube動画の要約には以下の拡張機能がおすすめです：
[Clarify AI: YouTube Summary with Gemini FOR Firefox(or Zed) user](https://addons.mozilla.org/en-US/firefox/addon/clarify-ai/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search)
[Clarify AI: YouTube Summary with Gemini FOR Chrome user](https://chromewebstore.google.com/detail/clarify-ai-youtube-summar/ogihgbocgnbhhdcmcolhipjhkmkecpeg?hl=ja)