自分は最近,paiza のプログラミング問題に取り組んでいます.
問題に取り組んでいく中で,問題を解く側だけでなく,作る側もやってみたいと考えるようになりました.
そこで,まずは簡単にPythonが動くWebサイトを作ってみました.
この記事では,Pythonが動くWebサイトの作り方を紹介します.
色々な方法があるようですが,今回は GitHub Pages だけで完結させます.
サーバーやクラウドサービスは利用せず,Node等も使いません.
こちらの32行のhtml だけで動きます.こちらのサイトで,実際にPythonを動かせます.
是非,一度試してみてください.
1. Hello World
まずは,Hello World
を表示します.
最初に用意するhtmlファイルは,以下の通りです.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
</head>
<body>
<pre>Hello World</pre>
</body>
</html>
pre
は,整形済みテキストを表し,その中身を等幅フォントで表示します.
最終的にPythonプログラムの出力が表示される部分なので,最初からpre
を利用します.
他の解説は,省略します.Web画面の表示は,以下になります.
次は,JavaScriptでHello World
を表示させます.
~~~略~~~
<body>
- <pre>Hello World</pre>
+ <pre id="output"></pre>
+ <script type="text/javascript">
+ document.getElementById("output").innerText = "Hello World";
+ </script>
</body>
</html>
元のHello World
は消して,pre
内のテキストを空にします.
代わりに,pre
部分にid="output"
を設定します.
そして,JavaScriptでid="output"
を持つ要素の内部テキストをHello World
に変更します.
Web画面の表示は,前と同じです.
次は,ボタンをクリックした時にHello World
を表示します.
~~~略~~~
<body>
+ <button onclick="main()">実行</button>
<pre id="output"></pre>
<script type="text/javascript">
+ async function main() {
document.getElementById("output").innerText = "Hello World";
+ }
</script>
</body>
</html>
実行
ボタンをクリックすると,非同期の関数main
が実行されます.
Web画面の表示は,以下になります.
最後は,Pythonを利用してHello World
を表示します.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>タイトル</title>
+ <script src="https://cdn.jsdelivr.net/pyodide/v0.27.2/full/pyodide.js"></script>
</head>
<body>
<button onclick="main()">実行</button>
<pre id="output"></pre>
<script type="text/javascript">
async function main() {
+ let pyodide = await loadPyodide();
+ let result = pyodide.runPython(`"Hello World"`);
+ document.getElementById("output").innerText = result;
- document.getElementById("output").innerText = "Hello World";
}
</script>
</body>
</html>
WebでPythonを使うため,pyodideを利用します.
上記のように数行記述するだけで,簡単にPythonプログラムが動きます.
Web画面の表示は,前と同じです.
2. Webサイト上で記述したPythonを動かす
html
ファイルにべた書きしたPythonプログラムを動かせました.
次は,Webサイト上で記述したPythonプログラムを動かします.
そのプログラムは,以下になります.
~~~略~~~
<body>
Pythonプログラム<br>
<textarea id="code" rows="10" cols="79">"Hello World"</textarea><br>
<button onclick="main()">実行</button>
<pre id="output"></pre>
<script type="text/javascript">
async function main() {
let code = document.getElementById("code").value;
let pyodide = await loadPyodide();
let result = pyodide.runPython(code);
document.getElementById("output").innerText = result;
}
</script>
</body>
</html>
textarea
にPythonプログラムを記述します.
"Hello World"
は,初期表示です.
記述されたPythonプログラムをdocument.getElementById("code").value;
で読み取り,それをpyodide.runPython
で実行します.
以下は,Web画面の例です.
今回の目的に適した,望ましい動作が実行されていません.
また,エラー処理を書いていないため,エラー時に反応がありません.
そこで,main
関数を以下のように変更します.
async function main() {
let code = document.getElementById("code").value;
let pyodide = await loadPyodide();
- let result = pyodide.runPython(code);
+ let result = "";
+ try {
+ pyodide.setStdout({ batched: (msg) => { result += msg + "\n"; } });
+ pyodide.runPython(code);
+ } catch (error) {
+ result = error
+ }
document.getElementById("output").innerText = result;
}
Pythonプログラムの標準出力ですが,pyodide
の初期設定では,コンソールに出力します.
index6.html
では,出力先を変数result
に変更しています.(改行も追加しています)
また,エラー時のメッセージも変数result
に渡すようにしました.
この変更で,Web画面は以下のように変わります.
標準出力の内容が画面に表示できました.
また,複数行の表示,エラーの表示もできました.
3. 代表的なパッケージのサポート
Pythonが動くWebサイトはできました.
しかし,実はこのままでは,numpyやscipyが動かせません.
そこで,main
関数を以下のように変更して,代表的なパッケージをサポートします.
async function main() {
let code = document.getElementById("code").value;
let pyodide = await loadPyodide();
+ await pyodide.loadPackage(["matplotlib", "numpy", "pandas", "scikit-learn", "scipy"]);
+ document.querySelectorAll("canvas, img.matplotlib").forEach(el => el.remove());
let result = "";
try {
pyodide.setStdout({ batched: (msg) => { result += msg + "\n"; } });
pyodide.runPython(code);
} catch (error) {
result = error
}
document.getElementById("output").innerText = result;
}
この変更で,pyodide.loadPackage
内に記述したPythonパッケージがサポートされます.
利用可能なパッケージの一覧は,こちらを確認ください.
canvas
関連の記述は,matplotlib
の実行に対応したものです.
実行ボタンを押した時,既に描画されている画像を消すように設定しています.
これが無いと,画像が消えず,Web画面上に画像が増え続けることになります.
Web画面で,以下のようなプログラムも実行可能になります.
普通に実行するより時間がかかりますが,曲線近似,最適化,図の描画ができました.
4. サイト構築
プログラムに対して自由にstyle
を適用したり,script
を追加してください.
この記事では,そこには言及しません.(次の記事で言及します)
完成したファイル群をGithubリポジトリにpush
します.
そして,Githubリポジトリにアクセスし,「Settings」⇒「Pages」⇒「Pages」を選択します.
Build and deployment の Sorce で Github Actions を選択し,Github Pages Jekyll の Configure をクリックします.
後は「Commit changes」ボタンを押すだけでサイト構築は完成です.
https://<ユーザー名>.github.io/<リポジトリ名>/<ファイル名>
にアクセスするとWebサイトが見られるはずです.
あるいは,https://github.com/<ユーザー名>/<リポジトリ名>/deployments
からアクセスするのが確実です.
ここでデプロイが成功していればURLが表示されます,
失敗の場合,Webサイトが構築できていないので,修正が必要となります.
終わりに
Pythonが動くWebサイトの作り方を紹介しました.
30行程度でサイトが作れた事に,驚かれた方も多いのではないでしょうか.
見た目や便利な機能に拘らなければ,Webサイト構築は意外と難しくありません.
次回は,このWebサイトの改善に取り組みます.
関連記事・リポジトリ: