💘HTML上でPythonコードが使える、PyScriptを用いて静的サイトを作成しました
こんにちは、B4の xryuseix です。今回はPythonのWeb上でのwasmを用いた実行環境である、 PyScript を用いて静的サイトを作成したお話をします。
作ったもの
画像をクリックするとデモページに飛びます。
レポジトリは こちら です。(←⭐️ を押すと幸せになれるらしいよ)
PyFuckとは
JsFuckのPythonバージョンです。デモサイトの上のテキストボックスにPythonコードを入力すると、e
,x
,c
,h
,r
,(
,+
,1)
の9文字しか使用しないPythonコードに変換します。
例えば、exec("print(1)")
は
exec(chr(111+1)+chr(111+1+1+1)+chr(11+11+11+11+11+11+11+11+11+1+1+1+1+1+1)+chr(11+11+11+11+11+11+11+11+11+11)+chr(111+1+1+1+1+1)+chr(11+11+11+1+1+1+1+1+1+1)+chr(11+11+11+11+1+1+1+1+1)+chr(11+11+11+1+1+1+1+1+1+1+1))
に変換されます。使用用途としては
- 簡単なPython難読化
- FlaskのSSTIとかで任意のPythonコードを実行でき、かつ文字種のvalidationがある場合のBypass
- CTFのPyjail問のBypass(リアルワールドでPyjailみたいなものはなさそうだが)
例えば、HSCTF9 paas (misc) で使用できました。
PyScriptとは
Hello World
PyScript とは、HTML内のpy-script
タグにPythonコードを入れると、Pythonコードとして実行できるソフトウェアです(進次郎構文)。内部ではPyoditeを用いたwasm(Web Assembly)として実行しています(たぶん)。
使用方法としては以下のように、head
タグにlink
タグとscript
タグでCDNリンクを設定し、py-script
タグにPythonコード入れるだけです。
<!DOCTYPE html>
<html lang="ja">
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<p id="title" class="text-center text-7xl"></p>
<py-script output="title">
print('Hello World!')
</py-script>
</body>
</html>
このHTMLファイルはそのままブラウザ上で動きますが、PyScriptの一部の機能はHTTPサーバを立てないと実行できません。その場合は例えばphp -S localhost:8080
などで起動します。
また、PyScriptのCDNは(ほとんどの?)Tailwind CSSが使用できます。例えば、class="text-center"
でテキストが中央に揃います。
モジュールのインポート
head
タグの中にpy-env
タグを入れ、その中にpathを設定すると、Pythonのモジュールをインポートできます。このようにすることでpy-script
タグ内のコードを最小限に抑えることができます。また、cliアプリケーションと同じレポジトリ上でモジュールを共有することができます。これはHTTPサーバ上でないと動きません。
<!DOCTYPE html>
<html lang="ja">
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- paths:
- ./modules/pyfuck.py
</py-env>
</head>
<body>
<p id="title" class="text-center text-7xl"></p>
<py-script output="title">
pyfuck = PyFuck.make_pyfuck("print(1)")
print(type(pyfuck))
</py-script>
</body>
</html>
内部的には webpack と同じように、HTMLのレスポンス後にpythonファイルのリクエストが走るようになっています。
要素の取得・イベント操作
以下、py-script
タグ内のお話です。Element
というPyScriptが定義しているクラスがあります。割とjQueryに近いような取得方法ですね(jQueryは関数ですが)。
foo = Element("sample-id").element.value
また、button
タグがonClick
属性が定義されているので、Element.element.onclick
でonClickイベントで発火する関数を指定できます。
def foo():
print("bar")
button = Element('sample-button')
button.element.onclick = foo
完成図
完成図は、satoki/PyFuck/index.html にあります。svgやTailwind CSSのせいでややこしくなっていますが、アプリケーションの特性と比較したらかなり簡潔なコードとなっています。PRは [satoki/PyFuck/pull/2] です。
まとめ
このように、PyScriptはすごく簡単にPythonプロジェクトをWeb上で公開できます。みなさんも既存のcliツールを静的Webサイトとして再実装してみてはいかがでしょうか。