Open20

【Flet】 python main.py だと動くのに flet pack main.py だと動かない

ピン留めされたアイテム
AWtnbAWtnb

SUCCESS!

https://github.com/AWtnb/flet_yomi/releases

結論:ビルド時に sudachipysudachidict_core--add-data オプションで追加すればよかった。

sudachipy は resources\sudachi.jsonresources\system.dic を参照して動作する仕様なので、これらを同梱してビルドする必要がある(ちなみに後者はサイズが200MB超えのサイズなのでリポジトリには掲載不可)。

ところでこの同梱方法が所見では見抜けないトリッキーさ。

  • 追加のデータがある場合は ft.app()assets_dir を指定するが、それに加えてビルドコマンドで --add-data で明記してやる必要がある。
  • しかもこのとき、セミコロン区切りで (同梱したいファイル/フォルダ);(そのファイル/フォルダの中身の展開先) のように指定する。後者が 展開先 なのが肝。
  • 公式によると、 pyinstaller の --add-data は複数回指定できる。しかし、Flet がそのラッパーとして用意している flet pack コマンドは1つしか指定内容を引き受けてくれない模様。なのでビルド時は pyinstaller を直に使う。
AWtnbAWtnb

2024-04-03 追記

--add-data の代わりに --collect-data を使えばOK!

最終的なビルドコマンドは下記:

pyinstaller --onefile --name yomi --collect-data sudachidict_core --collect-data sudachipy --noconsole main.py

site-packageディレクトリからコピーしてくる必要はなかった!

AWtnbAWtnb

https://github.com/AWtnb/flet_yomi/

SudachiPy を使って読みを取得するアプリケーションを作りたい。

python main.py で実行すると、下記のように問題なく実行できるのに、

flet pack main.py で作られた exe ファイルを実行すると、 GO! のボタンを押しても何も起きない…

AWtnbAWtnb

試しに main の関数内で直接、該当の関数を呼ぼうとすると、os error 3 の表示。

AWtnbAWtnb

もちろん、python main.py で実行すると問題なく動作する。

AWtnbAWtnb

ブラウザで表示するようにして開発者ツールを開いても特に何のアラートもなし。

AWtnbAWtnb

コンパイル時に sudachipy を正しくインポートできていない?
と、そこまで思い至ってもそこから先のデバッグ方法がわからず止まっています。ダレカタスケテ…

AWtnbAWtnb

疑わしいのは Python を Scoop でインストールしたこと。
current とかパスまわりがいじられているようだし…

AWtnbAWtnb

しかし同じ環境でインストールした Pillow を使っている下記のケースでは問題なく動作しているので謎。

https://github.com/AWtnb/flet_4up_idphoto

sudachidict_code などをさらに呼び出しているのが一因?


環境:

  • Windows 11 Home
  • Python 3.10.5
  • Flet 0.3.2
AWtnbAWtnb

SudachiPy 関連を別ファイルに分けて import する方式を辞めて、全部 main.py のファイル単体にしてみたけれど効果なし

AWtnbAWtnb

( ゚д゚)ハッ!
pack コマンドが内部で呼んでいる PyInstaller の問題なのでは…?

AWtnbAWtnb

「PyInstaller OS Error 3」で検索してヒットした こちらの記事 を参考に、Dictionary() インスタンス作成時の config_pathsudachi.json のパスを指定してやるとエラー文が変化した!

AWtnbAWtnb

sudachi_dict がないとのことなので main.py 内では使用していないもののまずは先頭で import してみる。

読み込んだライブラリが使用されていませんよ、という警告をひとまず無視して flet pack main.py すると画面に変化が!

AWtnbAWtnb

しかし今度はなにもコントロールが読み込まれない…

AWtnbAWtnb

main.py ではなく、自作のモジュールとして書いている sudachi.py の中で関数を呼び出してみるとエラーの詳細が表示されることを発見。

でも sudachidict_core はインストール済なのに何故…?

AWtnbAWtnb

Dictionary() インスタンス作成時に dict_type を指定しても効果なし。上記の Issue で提案されている sudachipy link コマンドは廃止されている模様。

Stack Over Flow に似たような質問を発見。
シンボリックリンク関連だから管理者権限で実行してみてはという提案がされていて sudachidict_core の再インストールや flet pack main.py の再実行を管理者権限で実行しても効果なし

AWtnbAWtnb

auto-py-to-exe を使って GUI から PyInstaller の各種オプションを弄り回してみる。

hidden_importsudachidict_core を指定してコンパイル。ログを見るためにコンソールモードは有効化。
で、 exe を実行してみるとエラー文が変化。

system.dic が存在しない…?

AWtnbAWtnb

それではと試しに、 公式に書いてある方法 で Fly.io へのデプロイを試してみる。
すると以下のエラー文が出て失敗。

エラー文抜粋
#7 6.242   × Building wheel for sudachipy (pyproject.toml) did not run successfully.
#7 6.242   │ exit code: 1
#7 6.242   ╰─> [35 lines of output]
#7 6.242       running bdist_wheel
#7 6.242       running build
#7 6.242       running build_py
#7 6.242       creating build
#7 6.242       creating build/lib.linux-x86_64-cpython-311
#7 6.242       creating build/lib.linux-x86_64-cpython-311/sudachipy
#7 6.242       copying py_src/sudachipy/__init__.py -> build/lib.linux-x86_64-cpython-311/sudachipy
#7 6.242       copying py_src/sudachipy/command_line.py -> build/lib.linux-x86_64-cpython-311/sudachipy
#7 6.242       creating build/lib.linux-x86_64-cpython-311/sudachipy/dictionary
#7 6.242       copying py_src/sudachipy/dictionary/__init__.py -> build/lib.linux-x86_64-cpython-311/sudachipy/dictionary
#7 6.242       creating build/lib.linux-x86_64-cpython-311/sudachipy/tokenizer
#7 6.242       copying py_src/sudachipy/tokenizer/__init__.py -> build/lib.linux-x86_64-cpython-311/sudachipy/tokenizer
#7 6.242       creating build/lib.linux-x86_64-cpython-311/sudachipy/morphemelist
#7 6.242       copying py_src/sudachipy/morphemelist/__init__.py -> build/lib.linux-x86_64-cpython-311/sudachipy/morphemelist
#7 6.242       creating build/lib.linux-x86_64-cpython-311/sudachipy/morpheme
#7 6.242       copying py_src/sudachipy/morpheme/__init__.py -> build/lib.linux-x86_64-cpython-311/sudachipy/morpheme
#7 6.242       creating build/lib.linux-x86_64-cpython-311/sudachipy/resources
#7 6.242       copying py_src/sudachipy/resources/sudachi.json -> build/lib.linux-x86_64-cpython-311/sudachipy/resources
#7 6.242       copying py_src/sudachipy/resources/char.def -> build/lib.linux-x86_64-cpython-311/sudachipy/resources
#7 6.242       copying py_src/sudachipy/resources/rewrite.def -> build/lib.linux-x86_64-cpython-311/sudachipy/resources
#7 6.242       copying py_src/sudachipy/resources/unk.def -> build/lib.linux-x86_64-cpython-311/sudachipy/resources
#7 6.242       copying py_src/sudachipy/sudachipy.pyi -> build/lib.linux-x86_64-cpython-311/sudachipy
#7 6.242       running build_ext
#7 6.242       running build_rust
#7 6.242       error: can't find Rust compiler
#7 6.242
#7 6.242       If you are using an outdated pip version, it is possible a prebuilt wheel is available for this package but pip is not able to install from it. Installing from the wheel would avoid the need for a Rust compiler.
#7 6.242
manager and ensure it is on the PATH during installation. Alternatively, rustup (available at https://rustup.rs) is the recommended way to download and update the Rust compiler toolchain.
#7 6.242       [end of output]
#7 6.242
#7 6.242   note: This error originates from a subprocess, and is likely not a problem with pip.
#7 6.244   Building wheel for watchdog (setup.py): started
#7 6.244   ERROR: Failed building wheel for sudachipy
#7 6.677   Building wheel for watchdog (setup.py): finished with status 'done'#7 6.677   Created wheel for watchdog: filename=watchdog-2.2.1-py3-none-any.whl size=78958 sha256=50c11e86b95fc97eccbe7b93574854199ffc7c6cf65420bedf56cce88989ecca
#7 6.677   Stored in directory: /tmp/pip-ephem-wheel-cache-g7tmhfff/wheels/8d/98/0d/f9318ab1d63885b2dbd40c91dbfbde2a4e65fc6b40d135ad6b
#7 6.683 Successfully built watchdog
#7 6.683 Failed to build sudachipy
#7 6.683 ERROR: Could not build wheels for sudachipy, which is required to install pyproject.toml-based projects
------
Error failed to fetch an image or build from source: error building: executor failed running [/bin/sh -c pip install --no-cache-dir -r requirements.txt]: exit code: 1

そもそもの SudachiPy のビルドで失敗している模様。ローカルでは動いているのに。
そういえばローカルで初回設定したときに、SudachiPy が Rust で動くようになったので Rustup を入れた記憶がある。手元で動いているのはそのおかげに違いなく、であれば Docer 上でも同じことをすればいいはずなのにその方法が皆目わからずお手上げ。

少なくとも SudachiPy が一筋縄ではいかないことだけは確か。

AWtnbAWtnb

エラー文を読み込むと、 system.dic がないと書いてあるのはどうやら TEMP フォルダの中身。ここに sudachi_dict パッケージをうまくコピーできていないのではないか、という仮説。