
Google colab で、シンプルな Flask アプリを動かしてみる。 200 円 記事
PC がない、Android タブレットならある、もしくは chromebook はある、という場合ブラウザがあるなら Google colab や、jupyter notebook などでPython web アプリ ( Streamlit とか ) をつくって動作させれると思います ( できます ) 。
PC がある場合でも、つくって壊せる Python を用意するのに、Google colab はひとつの選択です。
Flask を使う場合を例に、Google colab だけでアプリを動かすテストを書きます。
用意するもの、Google colab のページ。
まず、作るものはこちらのシンプルな pastebin のような web アプリです。
これは、Flask を使って、コードスニペットを記録して、表示させるときはプログラム言語のシンタックスハイライトでレンダリングさせるものをつくるチュートリアルです。
このチュートリアルで使用されている Flask アプリのコードを使って、Google colab で web アプリとして動作させます。
問題となることは、 Google colab では、ノート内ではプログラムは動きますが、それをサーバ側のプログラムとして、ノートに外からアクセスできないこと、それをどうするかということです。
どうなってほしいかというと、Google colab に local web サーバーとして動いてもらって、インターネットからその指定の local web サーバーへアクセスできてほしい、ということになると思います。
こういうのを、 expose IP とか、 expose localhost とか言うと思います。
日本語だとわかりませんが、 表現に揺れがあるので expose localhost とかで検索する方があまりぶれないようです。
そうすると、いろいろと方法があり、そういったサービスもいくつかあるようです。
一番シンプルには、Google colab が用意している、それ用のもの があります。
from google.colab import output
output.serve_kernel_port_as_window(8501) # この数字は Flask で指定したポートナンバーと同値にする。8501 は必須ではなく一例。
この場合は、今回の pastebin アプリでは、コードスニペットが記録されたあと、URL リンクとしてコードスニペットへのジャンプアドレスが表示されるのですが、生成されたリンクのアドレスが不正になるようなので、少なくともアプリのプログラムコードを修正しないと使えません。
ですので、こちらは使用しません。
他の選択肢としては、 ngrok というサービスがよくこの用途に使われているようです。
それ以外では、サービスでは cloudflare の cloudflared tunnel というのもあります。こちらは、Google colab でも使えます。
node.js の localtunnel も npm でインストールした場合は使えます。
今回は、Rust でつくられた bore という同様のトンネルのためのプログラムで、expose localhost をします。
Google colab や jupyter notebook などの場合、プログラムコードのエントリーポイントというのは、特になく、再生ボタンのようなのを押せば、そのコードのセルが実行されるというようになっています。
エントリーポイントというのは、
Java だと
class Main {
// Java main メソッド
public static void main(String[] args) {
// ...
}
}
こういうところです。
Python だと、こうなっているところから
if __name__ == '__main__':
main 関数となっているところへ 入る感じ です。
jupyter notebook などだとこういう風に書けないようだけど、 Flask とかのフレームワーク系のものは全部、サンプルコードが、こういうエントリーポイント風になっているけど、これはどうすんの ? ということがまずわからないかと思います。
Google colab もブラウザで完結したユーザーインターフェイスですが、セル上に書いたコードをターミナルコマンドのようなものから実行するようにもできます。
ですから、そのまま Flask のコードをセルに書いて、ファイルに書き込みします。
セルのなかの先頭行に
%%writefile index.py
とすれば、そのセルのなかの次の行からのコードが、`index.py` というファイルになります。
`index.py` は、どこに行くのかというと、`/content/index.py` という path になります。
今回の pastebin アプリの Flask のコードは、 `index.py` ですから、全文書くとこうなります。
下記アドレスをクリックするとコードスニペットの web ページ魚拓が開きます。
最後の方の二行が、
if __name__ == '__main__':
app.run(debug=True, host="", port=5000)
となっています。
host="",
というところを、
host="localhost",
と書き換える必要があります。

指定する port が 5000 だったり 8501 だったりどっちなんだということが気にはなりますが、expose IP するときに Flask で指定したポートナンバー(つまりこの箇所で指定しているポートナンバー)に合わせてコマンドで指定すれば問題ないです( expose IP の設定は後述 )。ちなみに、streamlit のデフォルトで待ち受けるポートは 8501 になっていると思います。
これで、このコードが書かれたセルの左がわにある再生ボタンみたいなのを押すと、プログラムが走るかわりに、ファイルができます。
ファイルに書き込む方法がわかれば、あとは簡単ですね。
このシンプルな patebin Flask アプリのコード自体の説明は、この記事では扱いません。 それは、こっちの↓ページでチュートリアルとしてステキに解説されていますので、ご覧ください。
さて、ノートのセルに書いたものがファイルに書き出せて、そのファイルへの path もなんとなくわかった、というところで、この Google colab って 仮想化された Ubuntu OS のコンピューターだよね ? ということにも気がついていると思います。
デスクトップのコンピューターの chrome 系ブラウザで Google colab を見ている場合は、Chrome Dev Tools で web ページのネットワークのやり取りを見聞できますから以下の記事を見てもらえば、chromebook の linux terminal みたいな感じをリモートで動かしてる感じ ? かしら、という印象になるのではないでしょうか。



Flask のアプリの Python コード部分がファイル化されて、
/content/index.py
になりました。
チュートリアルを確認すると、

必要なファイルとフォルダーを作成しましょう。( Google colab 用コマンド )
!mkdir -p pastes templates static && touch templates/index.html static/styles.css
フォルダ構造は次のようになります。

ディレクトリーとファイルぽいものができてますね。すばらしい。
上のスクリーンショットで、水色の字のはディレクトリーですね。sample_data のディレクトリーのファイルたちは、元々そこにあるもので、必要ありません。
ファイルぽいものは、ファイルはできていても中身は空っぽですから、ディレクトリ構造にあわせてファイルの中身をセルに書いて、さきほどの index.py のファイルと同じように、ファイルに書き込みます。
%%writefile templates/index.html
ですね。
/content/templates/index.html
%%writefile templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pastebin Service</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
{% if highlight_css %}
<style>
{{ highlight_css|safe }}
</style>
{% endif %}
</head>
<body>
<h1>Pastebin Service</h1>
{% if paste_url %}
<p>Your paste URL: <a href="{{ paste_url }}">{{ paste_url }}</a></p>
{% endif %}
{% if paste_content %}
<div class="highlight">
{{ paste_content|safe }}
</div>
{% endif %}
<form method="post">
<textarea name="content" rows="10" cols="50" placeholder="Paste your text here..."></textarea><br>
<select name="language">
{% for code, name in languages %}
<option value="{{ code }}">{{ name }}</option>
{% endfor %}
</select><br>
<button type="submit">Submit</button>
</form>
</body>
</html>
%%writefile static/styles.css
/content/static/styles.css
%%writefile static/styles.css
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
color: #333;
}
textarea {
width: 100%;
margin-top: 10px;
}
select, button {
margin-top: 10px;
}
.highlight {
background-color: #f5f5f5;
padding: 10px;
border: 1px solid #ccc;
margin-top: 20px;
}
この二つが、それぞれ web アプリの web ページのデザインにかかわるテンプレートの html ファイルと css 定義ファイルになりますね。
そして、再生ボタンみたいなのをそれぞれのセルで押します。
再生ボタン、こういうのですよ。左がわのやつです。

ファイルができたら、もうほとんど終わりです。最重要なものを残して。
この記事の本題は、ここから。
index.html
style.css
この三つのファイルが所定のディレクトリーにできたら、Flask web アプリ としては完成です。
では、実行して pastebin アプリ を動かします。
チュートリアルの方には、
python index.py
というコマンドで実行と書いてあります。
これは、ターミナルから
python index.py
と、コマンドでパイソンプログラムファイルを実行することを意味していますが、 Google colab だと、それはこうなります。
!python index.py
セルのなかで ! をつけてコマンドを書いて、再生ボタンみたいなのを押すと、同じことになります。
そうすると、通常の PC のターミナルだと、上のコマンドで、ブラウザのページが開いて、 pastebin アプリページになるわけですが、 Google coab は、それ自体がブラウザの中で完結しているものなので、そうはならないわけです。
ちょっとめんどくさい回りくどい表現ですが、
「Google colab は、Google のどこかにあるコンピューターの仮想化された Ubuntu OS のコンテナみたいなのをクラウドコンピューターと言い、それを起動してユーザー側のブラウザでログインしてリモートとして使っている、ということになりますが、そのリモートしている Ubuntu のなかで local host で、web サーバーを動かして、その local host のアドレスにインターネットからアクセスしたい」 ということ
ですよね。
local host を外部に公開する = expose IP
で、それをするのが ngrok, localtunnel ( node.js ), cloudflared tunnnel だったりする、その同種の機能で Rust で書かれたものが bore ということ、で その bore を使います。
bore の使い方は、プログラムをダウンロードして実行するだけです。
Google colab の自分の Ubuntu OS のなかで実行するので、Google colab のノートのセルの中に Ubuntu でのターミナルでやるようにダウンロードして、圧縮ファイルを展開して、Unix ぽい実行権限を bore プログラムに与えて、bore コマンドを使えるようにします。
# bore
#!wget -nc https://github.com/ekzhang/bore/releases/download/v0.5.1/bore-v0.5.1-x86_64-unknown-linux-musl.tar.gz
# updated v.0.5.1 => v.0.5.2
!wget -nc https://github.com/ekzhang/bore/releases/download/v0.5.2/bore-v0.5.2-i686-unknown-linux-musl.tar.gz
!tar -zxvf *.tar.gz
!chmod 764 bore
そうして、Flask アプリを起動して、bore で expose IP するには、以下のコマンド一行 です。
!python index.py & ./bore local 8501 --to bore.pub
bore local 8501
について
先述の Flask で以下のようにポートナンバーを 8501 に指定している場合、それに合致させて 8501 にしているわけで、Flask のプログラムコードを確認して、ポートナンバーを正しく指定してください。

そうすると
こうなります。

おそらくGoogle colab の方で、Flask コードで port=8501 とした場合でも、内部的にポートが移動されて、結局この場合 44439 で外部からのアクセスを待ち受けていて、それをまた bore の方で外部公開を port 44439 で待ち受ける、というようになてっているようです。
ということで、
https://localhost:8501
ではなく、ブラウザを開いて。ジャンプするアドレスを
https://bore.pub:44439
とタイプしてアクセスするとこうなりました。

44439
の部分は都度都度で変化しますので、listening at 以降を毎度毎度確認してください。

最後まで読んでくれてありがとう。
この記事を書くのも、プログラムを書くのも全部アマゾンの FireHD というけして高スペックではないタブレットで完結しています。
この Flask pastebin の動作については検証済み。
( Node.js の localtunnel でも検証しました。これは記事が他にもありますので、他で探してみてください。localtunnel の場合だと、決まった設定不可能のドメインにオプションでサブドメインを追加して指定して、さらにパスワードぽい数字なんかがあると思いますが、他の方の記事の頃合いと多少様子が違っているかもしれません。npm で Google colab に新たにインストールした方がいいと思います。また、cloudflared tunnel も検証しました、そちらも cloudflare のドキュメントを読めば、この記事で bore の場合を経験していれば、なんとなく手順はわかると思います。ドキュメントを読んでもどこまで読めばいいのか理解しづらいんですが、順番的に Node.js の localtunnel でやってみると〈 こういうことね 〉ということが肉体的に解釈できると思いますのでおすすめです。 ngrok については未検証です。 )
200 円記事なので、200 円以内で熱いコーヒーの薫りでリラックスしてください。( または、この Flask チュートリアルをつくったひとへ投げ銭を )
わたしは、豆を切らしました。
以上です。
以下は、現在時点 ( 2024.12月 ) だけ通用する cloudflared tunnel の場合のメモです。他のドキュメントをよくよく読めば必要のない余分なオマケです。
現時点では動作確認しましたが、Google colab のOS の変更や、cloudflare のプログラムの変更によって、現時点以降は、どうなるかは保証できません。
cloudflare の該当のドキュメントや、この cloudflared tunnel について書かれた記事について読んでも、どうも指し示しているものが、自分の目の前の状況と違うのか、なんかちょっと違うんだけどなということが確かにあります。
なので、そういうなにいってんのかわからないものと同じ ようなオマケということになりますが、上記の bore 使用のケースの記事とほぼ同様にワンタイムだけ疎通する、何処かでアカウント登録とかする必要の無い方の cloudflared tunnel ( 名称が時によって変わるようです ) の quick tunnel ↓ のケースでの必要事項だけを書いています。
ここから先は
¥ 300
この記事が気に入ったらチップで応援してみませんか?