【2023年版】PyScript 逆引きリファレンス

どうもです、タドスケです。

約一年前、PyScript というブラウザ上でPythonのプログラムを動かすためのライブラリを使っていました。

あわせて読みたい
【PyScript】サンプル集(alpha 版) どうもです、タドスケです。 PyScriptを触っていて、基本的な機能に関する使い方を色々と調べましたので、サンプル集として公開しておきます。 このページにあるサンプ...

当時の PyScript はまだα版で、リファレンスすらろくに無い状態だったので、まともなアプリを作ろうとすると大変でした。

それから1年後、久しぶりに公式サイトをのぞいたところ、リファレンスが整備されてだいぶ使いやすくなっていました。

あわせて読みたい
Pyscript.net Run Python code in your HTML.

そこで、現在のバージョン(latest 版)に合わせて、使い方ベースでまとめた逆引きリファレンスを作りました。

各コードは 2023年7月時点での PyScript を利用しています。
PyScript のバージョンは頻繁に更新されているようなので、新しいバージョンでは動かないことがあります。

目次

PyScript に関する日本語の解説サイトは?

PyScript に関する日本語の情報はまだ少ないです。

α版が出た1年前には話題になったものの、最近のバージョンについて解説しているサイトはほとんど見かけません。

僕が調べた限りでは、以下が比較的新しい情報でした。

gihyo.jp
WebブラウザでPythonが動作する!PyScriptの詳解 | gihyo.jp 今月の「Python Monthly Topics」では、Webブラウザ上でPythonが動作するPyScriptについて、内部構造なども含めて詳しく解説したいと思います。

PyScript の基本的な使い方や仕組みなどが詳しく解説されていますので、PyScript を使ったことがない人は先に読むことをオススメします。

コード

これから紹介するコードは全てGitHub で公開しています。

GitHub
GitHub - tadosuke/pyscript_example_latest: PyScript(latest)のサンプル集 PyScript(latest)のサンプル集. Contribute to tadosuke/pyscript_example_latest development by creating an account on GitHub.

各項目のリンクから、実際に動作するサンプルページに飛べます。

Hello world

まずはここから、プログラミングではおなじみの Hello world(PyScript 版)です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">

    <!-- PyScript を使うために必要な2行 -->
    <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
    <script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
    <py-script>
        print('Hello world!')
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/hello_world.html

body タグ以外の部分は変わらないため、以降の説明では省略します。

Element

エレメントの情報を取得する

<body>
    <div id="my_div">content</div>
    <input id="my_input" value="value"/>

    <py-script>
        # エレメントの取得(idを指定する)
        my_div = Element('my_div')
        my_input = Element('my_input')

        # content, value を取得
        print(f'{my_div.innerHtml=}')
        print(f'{my_input.value=}')
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/element_property.html

エレメントに書き込む/クリアする

<body>
    <div id="my_div">content</div>

    <py-script>
        # エレメントの取得(idを指定する)
        my_div = Element('my_div')

        # 書き込み
        my_div.write('Hello!')

        # クリア
        my_div.clear()
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/element_write_clear.html

子エレメントを取得する

<body>
    <div id="my_div">
        <input id="my_input" value="value"/>
        <button id="my_button1">Button1</button>
        <button id="my_button2">Button2</button>
        <button id="my_button3" class="name">Button2</button>
    </div>

    <py-script>
        # 親エレメントの取得
        my_div = Element('my_div')

        # my_div の子からエレメントを選択
        print(my_div.select('input').id)
        print(my_div.select('button').id)  # 複数ある場合は先に定義したほう
        print(my_div.select('#my_button2').id)  # id を指定して取得
        print(my_div.select('.name').id)  # class を指定して取得
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/element_select.html

JavaScript → Python へのアクセス

イベント発生時

イベント発生時に Python 側の関数が呼ばれるようにするには、2通りのやり方があります。

HTML 側か Python 側のどちらかに PyScript 専用コードが必要になるため、都合の良いほうを選んでください。

<body>
    <!-- ボタンをクリックすると関数が呼ばれる -->
    <button id="my_button" py-click="hello()">クリック</button><br>

    <!-- テキストをマウスオーバーすると関数が呼ばれる -->
    <span id="my_div" py-mouseover="hello()">マウスオーバー</span>

    <py-script>
        from pyscript import when

        def hello():
            print('Hello')

        # 関数に when デコレータを設定すると、html 側で py-* イベントを指定しなくても呼ばれる
        @when('click', selector='#my_button')
        def bye():
            print('Bye')
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/call_python_on_event.html

グローバル変数・関数

<body>
    <py-script>
        name = 'tadosuke'

        def func(name_):
            return f'Hello {name_}'

        class Hoge:
            def hello(self):
                return 'Hello Hoge'
        hoge = Hoge()
    </py-script>

    <button onclick="jsFunc()">jsFunc</button>
    <script>
        function jsFunc(){
            // Python 側のグローバル変数・関数を取得
            py_name = pyscript.interpreter.globals.get('name')
            py_func = pyscript.interpreter.globals.get('func')
            py_hoge = pyscript.interpreter.globals.get('hoge')

            console.log(py_func(py_name))  // グローバル関数を呼び出す
            console.log(py_hoge.hello())  // インスタンス経由での呼び出しも可能
        }
    </script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/interpreter_globals.html

コンソールの出力は、Chrome の開発者ツール(F12) などから確認できます。

Python → JavaScript へのアクセス

自分で定義した変数・関数

<body>
    <div id="my_div">content</div>
    <input id="my_input" value="value"/>

    <script>
        name = "tadosuke"

        function hello(name){
            console.log("Hello " + name)
        }
    </script>

    <py-script>
        # 変数名、関数名を import に指定する
        from js import name, hello

        hello(name)
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/python_to_js_original.html

JavaScript 側のオブジェクト(DOM)

<body>
    <div id="my_div">content</div>
    <input id="my_input" value="value"/>

    <py-script>
        # JavaScript の要素を使う際にはインポートが必要
        from js import document, window, console

        console.log('Hello')  # 開発者ツールのコンソール(Chrome なら F12)などで確認できる
        print(f'{window.innerWidth=}')
        print(f'{document.title=}')
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/python_to_js_dom.html

他のファイルを読み込む

自作モジュール(.py)を読み込む

src で指定する

html と同じ階層に以下のファイルがあるとします。

print('Hello from ex_module.py')
x = 10

ex_module.py を読み込むコードは以下です。

<body>
    <py-script src="./ex_module.py">
        # src を指定した場合、ここに書いたコードは実行されない
        print('Hello from main')
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/ex_module_src.html

py-config で指定する

以下のようなディレクトリ構成があるとします。

  • xxx.html (今回のサンプル)
  • ex_module.py
  • sub/
    • ex_module_sub.py

ex_module.py、sub/ex_module_sub.py を読み込むコードは以下です。

<body>
    <!-- ローカルのモジュールを読み込む -->
    <py-config>
        [[fetch]]
        files = ["ex_module.py"]

        [[fetch]]
        from = "sub"
        files = ["ex_module_sub.py"]
    </py-config>
    <py-script>
        import ex_module
        import ex_module_sub  # import 時はサブディレクトリを指定しない

        print(f'{ex_module.x=}')  # モジュール内変数にもアクセス可能
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/ex_module_fetch.html

サードパーティ製のパッケージを読み込む

<body>
    <!-- パッケージを読み込む(PyScript が対応しているパッケージのみ指定可能) -->
    <py-config>
        packages = ["numpy"]
    </py-config>
    <py-script>
        import numpy as np

        print(np.array([1, 2, 3]))
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/ex_module_packages.html

PyScript から利用できるパッケージには制限があります。
・PyScript が公式に対応しているパッケージ(α版用ですがこちらが参考になるかと)
・PyPI で公開されていて、C依存でないパッケージ

画像を読み込む

<body>
    <div id="canvas"></div>
    <py-config>
        packages = ["pillow"]

        [[fetch]]
        from = "image"
        files = ["face.png"]
    </py-config>
    <py-script>
        from PIL import Image

        # サブフォルダ名の指定は不要
        img = Image.open('face.png')

        # 取得したエレメントに書き込む
        canvas = Element('canvas')
        canvas.write(img)
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/image.html

ターミナル

ターミナルを非表示にする

<body>
    <!-- ターミナルを非表示にする -->
    <py-config>
        terminal = false
    </py-config>

    <py-script>
        print('Hello')  # ターミナルは出ない
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/terminal_disable.html

ターミナルを好きな場所に置く

<body>
    <div>テキスト1</div>
    <!-- ここにターミナルを置く -->
    <py-terminal></py-terminal>
    <div>テキスト2</div>

    <py-script>
        print('Hello')
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/terminal_manually.html

WEB API

requests にパッチをあてる

PyScript では、WEB API 利用に定番の requests はそのままでは使えません。

pyodide_http..patch_all() を呼んでパッチをあてることで、requests が使えるようになります。

<body>
    <py-config>
      packages = ["requests", "pyodide-http"]
    </py-config>
    <py-script>
        import requests
        import pyodide_http

        # PyScript では requests をそのまま利用できないので、
        # pyodide_http を使用してパッチをあてる
        pyodide_http.patch_all()

        # 以降は通常通り使える
        response = requests.get("https://httpbin.org/get")
        print(response.json())
    </py-script>
</body>

サンプル:https://tadosuke.github.io/pyscript_example_latest/requests.html

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次