🐍

PyScriptのpy-envは記述に応じてどんな動きをするかを調べてみる(パッケージ名編)

2022/07/02に公開約3,300字1件のコメント

※「パッケージ名編」とは書いたものの、「相対パス編」をやるかは未定です。

概要

PyScriptに使われるpy-envタグの中身が、値に応じてどう解釈され、PyScriptはどう振る舞うかをつらつらと試してみた記事です。

前提

以下の環境での動作確認を踏まえて書いてます。

  • 2022年7月2日時点でのコード
  • https://pyscript.net/alpha/pyscript.js, https://pyscript.net/alpha/pyscript.css を利用したもの
  • Pythonのhttp.serverモジュールで動作させているビルトインサーバーへのアクセス
  • 簡易的な事実確認

書かない

PyScriptについての前説、アーキテクチャなどの大半について。

py-env 要素について

そのページにおけるPyScriptの動作において、追加でモジュールを利用する際に宣言する要素です。
PyScriptの起動時において、この要素を解釈して必要なライブラリ・モジュールを取りまとめることを可能にします。

スーパー雑に書くと、PyScriptにとってのrequirements.txtみたいなものです。

PyScriptのドキュメント上はここを参照してください。

結論:対応しているライブラリ

試して認識できている範囲では、次のいずれかなら対応しています。これ以外のものはwheelファイルを用意して相対パス指定が必要になりそうです。

  • Pyodideのpackagesとして登録されているライブラリ(この場合は、Pure Pythonでなくても可)
  • PyPIに登録されているPure Pythonなライブラリ

どんな動きをするかを個別に試してみる

前置き

  • py-script要素には、「ライブラリのインポート」まで書いて、locals()の結果出力までやります。
  • ブラウザのDevToolでリクエストの状況を眺めます。
  • (余裕があれば)複数のOSで試します。

Pyodide 内でまとめられているライブラリ

py-env のパッケージ指定として、「Pyodide」に登録されているものを使う場合。

<py-env>
- beautifulsoup4
</py-env>

この場合は、 beautifulsoup4と依存ライブラリであるsoupsieveをjsdelivrから入手しています。

Pyodide側では、次のライブラリはリポジトリのpackages配下で管理されており、条件を満たせばこの挙動が適用されそうです。

  • 汎用性の高い(とみなしている)ライブラリ
  • 科学計算系のライブラリ
  • これらの動作に必要とするライブラリ
<py-env>
- numpy
</py-env>

このあたりは、コンパイルが必要なタイプも同じで、Pyodideが予めWASM向けのwheelを用意してくれています。

Pyodide内で管理されていないライブラリ(pure-python編)

py-env のパッケージ指定として、「Pyodide」に登録されていないものを使う場合。

「PyScriptを利用してDNS問い合わせをしてみたくなった」と仮定して、DNSPythonを利用しようとしてみましょう。

<py-env>
- DNSPython
</py-env>

先程と違い、次の通信をしています。

  1. PyPI に対して https://pypi.org/pypi/dnspython/json のリクエストを実行
  2. dnspythonのstableバージョンを認識した上で、dnspython-2.2.1-py3-none-any.whlをダウンロード

つまり、探索順としてJsdelivr(Pyodide管理下)→PyPIという振る舞いをしており、PyPIにあるライブラリは割りと何でもインストールできそうな気がします。

Pyodide内では管理されていないライブラリ(none-pure-python編)

さて何を血迷ったかPyScriptで機械学習の何かをやってみたくなったとします。
とりあえず、機械学習ということでTensorflowをインストールさせてみましょう。

<py-env>
- Tensorflow
</py-env>

さて、この状態でブラウザにアクセスすると、PyScriptの初期化が完了しません。

リクエストを状況を見るとPyPIに https://pypi.org/pypi/tensorflow/jsonのリクエストをするところまでは、先ほどと同じようです。
しかし、wheelファイルの入手には進まないようです。(wheelファイル自体は存在します

改めてDevToolのコンソールを覗いてみましょう。

Couldn't find a pure Python 3 wheel for 'tensorflow'.と出ています。
どうやら、PyPI上にあるパッケージといえども、Pure Pythonなもの(~none-any.whl)に限定されるようです。

Pyodideに管理されているが、バージョン違いのライブラリ(pure-python編)

諸事情でdocutilsのちょっと古いバージョンが必要になったとします。

<py-env>
- docutils==0.17.1
</py-env>

jsdelivrにはdocutilsの0.18系しか無いらしく、PyPIから探しに行きます。

Pyodideに管理されているが、バージョン違いのライブラリ(none-pure-python編)

同様に、numpyのちょっと古いバージョンを使おうとしてみましょう。
諸事情でdocutilsのちょっと古いバージョンが必要になったとします。

<py-env>
- numpy==1.21.0
</py-env>

jsdelivrにあるnumpyは1.22系だったため、やっぱりPyPIから探しに行きます。
しかし、「numpyはpure-pythonのwheelが無い」というTensorflowと同様の理由でインストールに失敗しています。

まとめ

PyScriptはPyPIからもちゃんとパッケージを探索してくれているようです。
そのため「Pure Pythonなアプリケーション」を前提とした場合は色々と遊ぶ余地がありそうでした。

Discussion

素晴らしい検証記事ありがとうございます。

エラーメッセージを見ると、 <py-env> タグは Pyodideが提供する micropip パッケージを利用しているようですね。

私も困ったのですが、 micropip.install() はパッケージのバージョン指定を(少なくともpipと同じ方法では)対応していないようです。
一方で、PyPI掲載のパッケージの欲しいバージョンの Download files タブから pure Python の wheel のダウンロードURLをコピーして、直接指定すればインストールできました。

<py-env> タグでの動作は確認しておりませんし、もしかしたらすでにご存じかもしれませんが、参考までに。

ログインするとコメントできます