Python のプログラムを実行環境ごと配る

2020年10月17日

はじめに

Python で作ったプログラムを使ってもらうために配るときに、Python の動作環境のセットアップ方法をいちいち指示するのもめんどうなので、Python の動作環境も一緒に配りたい。どうせなら Python で動いていることも意識させないようにしたい。これを Miniconda で実現することを考える。

環境

  • Windows 10 64 bit/Ubuntu 16.04 LTS
  • Miniconda3

Miniconda の取得

こちら から Minicoda を取得する。

Windows

Miniconda の用意

Miniconda ごと配布する

Miniconda ごと配布してしまいたい場合は、一度自分のマシンにインストールして、環境を設定後、インストールフォルダを ZIP か何かで固めればよい。

個別の問題

  • Jupyter

    Jupyter を pip で入れると Python のパスを実行ファイルに埋め込んでしまうようである。本目的に関しては conda で入れるのが望ましい。

  • Qt

    bin/qt.conf の中のパスを見ているので、設定を修正する必要がある。

Miniconda のインストール

配布先で Miniconda をインストールすることを考える。コマンドプロンプトを起動し、コマンドでインストールする。

>start /wait "" Miniconda3-latest-Windows-x86_64.exe /InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /S /D=%CD%\miniconda3

ただし、すでに Miniconda (Anaconda) がインストールされていると、ショートカットを上書きしてしまう。それを避けるためには、以下のようなバッチファイルを使う。

setup.bat

@echo off
set shortcut_path="%APPDATA%\Microsoft\Windows\Start Menu\Programs\Anaconda3 (64-bit)"
set temp_name=""

if exist %shortcut_path% (
	goto shortcut_exist
)
goto shortcut_exist_end

:shortcut_exist
set data_str=%date:~0,4%%date:~5,2%%date:~8,2%
set time_str0=%time: =0%
set time_str=%time_str0:~0,2%%time_str0:~3,2%%time_str0:~6,2%
set temp_name="Anaconda-%data_str%%time_str%"
echo "%TEMP%\%temp_name%"
move %shortcut_path% "%TEMP%\%temp_name%"
:shortcut_exist_end

start /wait "" Miniconda3-latest-Windows-x86_64.exe /InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /S /D=%CD%\miniconda3
rmdir /s /q %shortcut_path%

if not %temp_name% == "" (
	move "%TEMP%\%temp_name%" %shortcut_path%
)

すでにショートカットが存在すれば、それを一旦退避し、インストール終了後にもとに戻している。少し処理が複雑になっているのは、一時ファイル名を一意にするためである。

Miniconda を有効にするために、以下のようなバッチファイルを用意する。

activate.bat

@echo off
set DIR=%~dp0
set MINICONDA3=%DIR%\miniconda3
call %MINICONDA3%\Scripts\activate.bat

変数 DIR は activate.bat の置き場所、MINICONDA3 は Miniconda3 のパスである。

コマンドプロンプトで activate.bat を実行する。

>activate

あるいは、コマンドプロンプトのショートカットを用意し、リンク先を以下のようにする。

%windir%\system32\cmd.exe /k activate

このショートカットで起動すれば、Miniconda が自動的に有効になる。

前もって別の環境で仮想環境の設定を行い、エクスポートしておく。以下では、"env1" という名前で Python 3.7 の仮想環境を作っている。

>conda create -n env1 python=3.7
>conda activate env1

... (必要なパッケージをインストール) ...

>conda env export > env.yaml

これをインストールした環境にインポートすればよい。

>conda env create -f env.yaml

インストールを自動化するには、以下のようなバッチファイルを用意すればよい。

setupt.bat

@echo off
Miniconda3-latest-Windows-x86_64.exe /InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /S /D=%~dp0\miniconda3
call activate
call conda env create -f env.yaml
call conda deactivate

配布先では、このバッチファイルを実行してもらえばよい。

>setup

Python プログラムの設定

作成した Python プログラムを "prog.py" とする。Python プログラム実行のため、以下のようなバッチファイルを用意する。

prog.bat

@echo off
set DIR=%~dp0
set MINICONDA3=%DIR%\miniconda3
call %MINICONDA3%\Scripts\activate.bat

conda activate env1

set PYTHONPATH=%DIR%\python;%PYTHONPATH%
python %DIR%\prog.py %1 %2 %3 %4 %5 %6 %7 %8 %9

conda deactivate
conda deactivate

変数 DIR は prog.bat の置き場所、MINICONDA3 は Miniconda3 のパスである。prog.bat と同じ場所に "python" というフォルダがあり、ここに必要なモジュールが入っているものとしている。prog.py も prog.bat と同じ場所にあるものとしている。実行環境は仮想環境 env1 に入っているものと想定している。

コマンドプロンプトで次のように実行する。

>call prog.bat

単体で実行するなら call はいらないが、たとえばバッチファイルで引数を変えて何度も実行する場合は、call が必要である。

Linux

Miniconda の用意

Miniconda ごと配布する

Miniconda ごと配布してしまいたい場合は、一度自分のマシンにインストールして、環境を設定後、インストールフォルダを tar/gzip で固めるという方法が考えられるが、Linux の場合はうまくいかないことがある (パスがハードコードされていろいろ問題が起こることがある)。ネットがつながるなら、以下の自動インストールの方法を試みたほうがよい。スタンドアロン環境なら、ダメ元で Miniconda ごと配布してみるしかない。

Miniconda のインストール

Windows のようにインストールしたものを配布すると、うまく動作しないことがある。配布先でインストールさせたほうがよい。その場合、バッチインストールを用いる。

$ sh Miniconda3-latest-Linux-x86_64.sh -p ./miniconda3 -b

以下のようなファイルを用意する。

activate

DIR=`dirname $0`
MINICONDA3=$DIR/miniconda3

if [ "$SHELL" = "/bin/zsh" ] ; then
    CONDA_SETUP=`$MINICONDA3/bin/conda shell.zsh hook`
else
    CONDA_SETUP=`$MINICONDA3/bin/conda shell.bash hook`
fi

eval "$CONDA_SETUP"

Miniconda を有効にするには次のようにする。

$ . ./activate

前もって別の環境で仮想環境の設定を行い、エクスポートしておく。以下では、"env1" という名前で Python 3.7 の仮想環境を作っている。

$ conda create -n env1 python=3.7
$ conda actiavte env1

... (必要なパッケージをインストール) ...

$ conda env export > env.yaml

これをインストールした環境にインポートすればよい。

$ conda env create -f env.yaml

以上の操作をシェルスクリプトにすれば、Miniconda のインストールを自動化できる。

setup

#!/bin/sh
sh ./Miniconda3-latest-Linux-x86_64.sh -p ./miniconda3 -b
. ./activate
conda env create -f env.yaml
conda deactivate

配布先では、スクリプトをひとつ実行してもらうだけでよい。

$ sh ./setup

Python プログラムの設定

作成した Python プログラムを "prog.py" とする。Python プログラム実行のため、以下のようなスクリプトを用意する。

prog

#!/bin/sh
DIR=`dirname $0`
MINICONDA3=$DIR/miniconda3

if [ "$SHELL" = "/bin/zsh" ] ; then
    CONDA_SETUP=`$MINICONDA3/bin/conda shell.zsh hook`
else
    CONDA_SETUP=`$MINICONDA3/bin/conda shell.bash hook`
fi

eval "$CONDA_SETUP"

conda activate env1

export PYTHONPATH=$DIR/python:$PYTHONPATH
python $DIR/prog.py

conda deactivate
conda deactivate

変数 DIR は prog の置き場所、MINICONDA3 は Miniconda3 のパスである。prog と同じ場所に "python" というフォルダがあり、ここに必要なモジュールが入っているものとしている。prog.py も prog と同じ場所にあるものとしている。実行環境は仮想環境 env1 に入っているものと想定している。

実行権限を設定しておき、端末で次のように実行する。

$ prog