Help us understand the problem. What is going on with this article?

使用Pythonモジュールをzip配布

More than 1 year has passed since last update.

Pythonスクリプト/スクリプトに使用しているサードパーティPythonモジュール群をzipファイル化して配布する方法を紹介します。

背景

pip経由で取得したサードパーティPythonモジュールを活用したPythonツール/スクリプトを配布するときに以下のように困った状況に陥ることがあります。

  • ツールを使用するマシンではpipコマンドを使用できないため、Pythonモジュールをインストールできない。
  • ツールを使用するマシンではDockerを使用できないため、PythonモジュールをDockerコンテナに同梱して配布できない。

Pythonは標準ライブラリが非常に充実しているため、ちょっと我慢して諦めてしまう人を結構見かけます。しかし上記の理由で「Pythonモジュールを使えば実装する時間を大幅に短縮できる」という選択肢を放棄するのは勿体なすぎます。

選択肢を放棄しないための手段の一つとして、本記事ではPythonモジュール群のzipファイルを作成し、これをPythonモジュールとしてimportする手順を紹介します。

手順

ここでは個人的にPythonスクリプトを作成する時によく利用するdocker, clickという2つのPythonモジュール(および依存関係)のzipファイルを作成してimportする手順を例として示します。

NOTE: コマンドラインインタフェース(CLI)を持つツールを簡単に作りたい場合、clickはとてもお勧めなので是非とも利用してください

zipファイルを作成

以下の手順で必要なPythonモジュール群のzipファイルを作成します。C言語モジュールが含まれている場合、作成したzipファイルはOS/プラットフォーム依存のものとなるため注意が必要です。

なおpipコマンドでPythonモジュール群を収集する手順については、requirements.txt等がある場合はそれを指定するようにしてください。

# 1. Pythonモジュール群を格納するディレクトリ作成
mkdir my-py-library

# 2. Pythonモジュール群をpip経由で収集
# -> この例ではdocker, clickを依存関係含めて収集
pip3 install docker click -t my-py-library

# 3. C言語モジュールがないかチェック
# -> 存在する場合は、OS/プラットフォーム依存となる
find my-py-library | egrep '\.so$|\.pyd$'

# 4. Pythonモジュール群のzip化
cd my-py-library
zip -r  ../my-py-library.zip *
cd ..

これで上記の例ではmy-py-library.zipというzipファイルが作成されます。これを次の手順でimportすることにより、このzipファイルに含まれているclick, dockerモジュールを利用できます。

zipファイルをimport

Pythonスクリプトと同じディレクトリにzipファイルが配置されている場合、以下のようにimportします。

  • sys.path.insert(0, <zipファイルパス>)でzipファイルをPYTHONPATHとして追加する
    • os.path.realpath(__file__)を使用することで、Pythonスクリプトの絶対パスを取得できる。この絶対パスを用いてzipファイルのパスを指定する。
  • PYTHONPATHを追加した後、必要なPythonモジュールをimportする。

なお、下記例のようにPYTHONPATHを設定した場合、どこからPythonスクリプトを実行した場合でもPythonスクリプトと同じディレクトリのzipファイルを参照されます。Pythonスクリプトとzipファイルをセットで配布する場合は、このようにPYTHONPATHを設定した方が色々と都合が良いです。

import os
import sys

# PYTHONPATHにzipファイルを追加
basepath = os.path.split(os.path.realpath(__file__))[0]
sys.path.insert(0, os.path.join(basepath, 'my-py-library.zip'))

# zipファイルに含まれるPythonモジュールをimport
import click
import docker

# Do something...

import文の箇所でエラーが発生しなければ正常にimportされています。

補足

  • zipファイルではなくディレクトリでも利用できます。zipにしているのは以下の利点があるためです。やや特殊な開発、運用ルールがあるところでは意外と重宝します。

    • 配布が容易である
    • バージョン管理システムでソースコードとして管理する必要がない
  • C言語モジュールが含まれる場合、動作環境がOS、CPUアーキテクチャ、Pythonバージョンに依存するようになります。また内部で特定環境(ex. Linux, mac OS)のコマンドを実行していたり、ライブラリにアクセスなどをしている場合はC言語モジュールが含まれていない場合でも同様です。

  • ここで紹介した手順はPython2/3の両バージョンで利用できます。

    • Python2.3で導入されたzipimportを使用した仕組みのため、基本的にPython2.3以上であれば利用可能。
yoichiwo7
秋葉原の某所でエンジニアとして働いてます。 開発ワークフロー改善、およびKubernetes等のインフラ関連の技術にハマってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした