デスクトップ用に書いた Flet アプリのサイズや表示位置などをいじり、同じコード&操作感でウェブアプリとして使えるようにしました。今回のビルド方法はクライアントサイドで動くので (公式で言うところの、Static website) 、WordPress 等のホスティングサーバがあれば公開できるはずです。ついでに Google AdSense の広告も表示させています。
下準備
環境の構築方法などは以前の投稿に書いてあるので今回は省きます。以下の記事を参考に構築してください。
Python のフレームワーク Flet で macOS 用デスクトップアプリをビルド
サーバサイドでデプロイする場合
本記事はクライアントサイドなので、要するに HTML と JavaScript で動く公開方法です。サーバサイド、特に Apache ウェブサーバへデプロイする場合は以下の記事をご覧ください。Nginx ウェブサーバへのデプロイは公式サイトを見てもらうのが良いです。
Flet のウェブアプリを Apache ウェブサーバのリバースプロキシで動かす
ウェブアプリとしてビルドする
以前の macOS アプリビルドの記事の、ビルド実行 (手順 13) 直前まで終わっている事を前提に進めます。ウェブアプリに指定できる項目はあまりないようなので、簡単に以下のコマンドでビルドします。ビルドにかかる時間は、macOS 用にビルドした時と特に変わりないようです (本記事では、上記記事で紹介している fletpassgen を使用しています)。
flet build web
ローカル環境で動作確認
完成したファイル群は、build/web
にまとめられています。まずは、ローカルのブラウザで動作することを確認しましょう。以下を実行し、ブラウザで http://localhost:8000 を開きます。一通りいじってみて問題無ければ、いよいよサーバへデプロイします。
python -m http.server --directory build/web
# 終了するときは Ctrl + C
サーバにアップロードする前の作業
ディレクトリを指定
今回の例では、https://blog.peddals.com/fletpassgen にアクセスしたときにウェブアプリが開くようにします。そのために、index.html を一箇所書き換えます (ビルドするときにオプション --base-dir "/fletpassgen/"
を追加していればこの手順は省けますが、ローカルでテストできません。なので、ビルド後に書き換えましょう)。お使いのエディタで build/web/index.html
を開き、以下のように書き換えます。ディレクトリ名前後のスラッシュ (/
) は必須です。
<base href="/fletpassgen/">
フォルダを固める
フォルダ名自体も上記ディレクトリ名に変更し、一つのファイルに固めてアップロードしやすくします。以下実行後、fletpassgen.tar.gz
が作られます。
cd build
mv web fletpassgen
tar cvzf fletpassgen.tar.gz fletpassgen
サーバにアップロード&その後の作業
固めたファイルをアップロード
ホスティングサーバへ fletpassgen.tar.gz
をアップロードします。Terminal.app から実行する場合は以下のようなコマンドになります。指定するユーザ名、ホスト名、ディレクトリ名は適宜変更してください。
scp fletpassgen.tar.gz username@hostname:~/public_html
圧縮ファイルを展開
その後サーバでアップロードしたファイルを展開します。ssh
が使える場合はこんな感じです。最後のコマンドは、不要になった圧縮ファイルを削除しています。
ssh username@hostname
cd ~/public_html
tar xvf fletpassgen.tar.gz
rm fletpassgen.tar.gz
Web ブラウザでアクセス
これまでの作業で、Flet のクライアントサイド (static) ウェブアプリがアップロードできました。実際にアップしたものがこちらからアクセスできます: https://blog.peddals.com/fletpassgen/
最初に数秒アイコンが表示され、その後ローカルでテストしたものと同じウェブアプリが表示されれば成功です。
うまくいかない時は
この方法でビルドした場合、ファイル容量が大きくなります。今回使ったサンプルで、展開後のトータルサイズは 28MB あります。なので、最初にアクセスしたときにはブラウザに必要なファイルを読み込むために多少の時間がかかります。まずはとにかく待ってみましょう。
いくら待ってもアイコンすら表示されない場合は、index.html
内のディレクトリ名の設定、実際に展開したディレクトリ名、ディレクトリやファイルのユーザ・グループ・アクセス権それぞれを見直しましょう。既存のファイルやディレクトリを参考に修正してみてください。
Tips と追加情報
デスクトップアプリと同じコードを使う
こぢんまりとしたデスクトップアプリは、ウィンドウサイズを指定し、リサイズを許可しない事で適当にレイアウトしてもどうにかなったりします (当初 fletwebapp がそうでした)。もちろん作るアプリ次第ですが、ウェブアプリにしたときにデザインが崩れないようにするには、page.window_width=
で指定した幅を、ft.Container
の width=
プロパティでも指定するのが良いと思います。
サイズが大きいので注意
上にも書きましたが、こんな簡単なアプリ (Python コード単体で 約 3.9KB) でも、ビルドすると Python 自体や Flet、その他必要なファイルが追加されて約 28MB になってしまいます。デプロイの際には注意が必要です。
一度開けばネットワークが切れても動く
サーバサイドのデプロイではサーバとの接続が切れたときにも動作するように設計する必要がありますが、ブラウザにダウンロードするこの方法では、ネットが切れても動きます。用途によってはこの方法で十分でしょう。
Safari はコピーボタンが動かない
いつか修正されると思いますが、Chrome では動作する Copy ボタンが今回のデプロイ方法では動作しません。コード自体には、Safari だと Copy ボタンを表示しない設定を入れていますが、クライアントサイド (static website) デプロイではブラウザのエージェントを確認することができないためボタンを消すこともできませんでした。サーバサイドでのデプロイであれば、コピーはできないものの、ボタンが消えるハズです (そのうちテストします)。
おまけ: Google AdSense の広告を追加する
こちらのサイトを大いに参考にさせていただきました。ありがとうございます。
Flutterで作ったWebアプリでGoogleAdSenseの広告を表示する。
AdSense の HTML コードを取得
上記サイトを参考にコードを作成し、以下の部分をどこかに保存しておきます。
Google AdSence > 広告 > 広告ユニットごと > ディスプレイ広告 > 名前を付けて、作成
data-ad-client="xxxxxxxx"
data-ad-slot="yyyyyyyy"
index.html に style を追加
Flet ウェブアプリのディレクトリ (本記事では fletpassgen
) 内にある index.html
に以下 CSS の設定を追加します。追加場所は </style>
タグのすぐ上あたりが良いでしょう。行番号は、Flet 0.19.0 の場合の参考としてください。
footer{
width: 100%;
height: 100px;
text-align: center;
padding: 0;
position: absolute;
bottom: 0;
z-index: 100;
}
index.html に <footer></footer> ブロックを追加
最終行 </body></html>
の上に、以下を追加します。ハイライトした data-ad-client
と data-ad-slot
にはそれぞれ、先ほど AdSense からコピーした内容を貼り付けます。行番号に関しては同じく参考まで。
<footer>
<style>
.example_responsive_1 { width: 320px; height: 100px; }
@media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 60px; } }
@media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 90px; } }
</style>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Home_Page -->
<ins class="adsbygoogle"
style="display:inline-block"
data-ad-client="AdSence でコピーした内容を貼る"
data-ad-slot="AdSence でコピーした内容を貼る">
</ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</footer>
変更内容を保存し、ウェブアプリの画面最下部に広告が表示されていれば成功です。
Image by Stable Diffusion
Date:
2024年1月29日 0:04:44
Model:
realisticVision-v20_split-einsum
Size:
512 x 512
Include in Image:
masterpiece, best quality, retro future, successful upload of application
Exclude from Image:
Seed:
3400661084
Steps:
20
Guidance Scale:
20.0
Scheduler:
DPM-Solver++
ML Compute Unit:
CPU & Neural Engine