📝
実行中にパッケージ追加可能なPythonアプリパッケージング
何が嬉しいのか/やりたいこと
要件1. 実行中にパッケージを追加できるようなPythonアプリ実行環境を作りたい。
要件2. Pythonインストーラは使いたく無い。
※要件1は、PyInstallerでは対応するのが難しそう。
必要なもの
Python埋め込み可能パッケージ, get-pip.pyを準備
-
Pythonパッケージ配布サイトの「embeddable package」と表記されているものを取得して、
python
ディレクトリに解凍 -
python/python{バージョン番号}._pth
の最終行(# import...
)の#
を削除して有効化 - https://bootstrap.pypa.io/get-pip.py をダウンロードしてこれもpythonディレクトリへ置いとく。
アプリ関連のスクリプト
- アプリのpyスクリプト,パッケージは、すべて
python/
ディレクトリへ配置する。(そうしないとアプリ本体起動スクリプトからimportできない。あるいはpython/python*._pth
ファイルにアプリ関連のスクリプト格納先ディレクトリのパスを記述すること) - アプリ本体起動スクリプトだけは、どこに配置しても良いが、他のアプリ関連スクリプトとまとめて
python/
ディレクトリに置いとくのが分かりやすそう。
起動スクリプト
以下のことを行うスクリプト ※スクリプトファイル名はお好みでどうぞ
- インストール状態の判定(
.\python\already_installed.txt
の存在チェック)。インストール終わってたら環境変数設定のステップへ。 - コマンド
.\python\python.exe .\python\get-pip.py
- コマンド実行
.\python\python.exe -m pip install -r .\requirements.txt
※デプロイするアプリで必要なパッケージのインストール - インストール完了ファイル(
.\python\already_installed.txt
)を作成 - 環境変数PATHに
.\python
,.\python\Scripts
を追加する。 ※これやっとくとsubprocessからこの環境のpythonとかpipとかを使える。 - コマンド実行
.\python\python.exe .\python\main.py
※アプリ本体の起動
上記スクリプトを、Windows版のbatファイルとしてGPT4に書いてもらったのが、こちら:
@echo off
setlocal
REM 1. インストール状態の判定
if exist .\python\already_installed.txt goto SetEnvVar
REM 2. コマンド実行
.\python\python.exe .\python\get-pip.py
REM 3. コマンド実行
.\python\python.exe -m pip install -r .\requirements.txt
REM 4. インストール完了ファイルを作成
echo Installation completed on %date% %time% > .\python\already_installed.txt
:SetEnvVar
REM 6. 環境変数PATHに追加
set PATH=.\python;.\python\Scripts;%PATH%
REM 7. コマンド実行
.\python\python.exe .\python\main.py
endlocal
exit
デプロイ作業
- 上記「必要なもの」に記載の、以下のファイルたちをデプロイ先環境にコピー
-
python
ディレクトリ- emmbeddableパッケージを解凍したもの
get-pip.py
- アプリ関連スクリプト一式
-
_pth
ファイルを編集したもの
- 起動スクリプト
-
- 起動スクリプトを実行する。すると...
- 初回はインストール&アプリ起動が走る。
- 二回目以降はアプリ起動のみ走る。
この配布方式のデメリット
- Pythonをアップデートするのが(できなくはないだろうけど)大変そうなこと。(まるごと作り直した方が早そう)
- venv同様に他と隔離された環境になること。(これはメリットでもある)
- ランタイム環境と同じOS, CPUアーキテクチャ(32 or amd64)の開発環境にしないと作るのに苦労しそうなこと。
参考
Discussion