Pythonのパッケージ管理に使うpipコマンドはデフォルトでは https://pypi.org/ からパッケージをダウンロードします。しかしpipではこれ以外のリポジトリを追加することができ、この機能を使うことで自分しか使わないパッケージを独自のリポジトリに配置してそこからpipでインストールできるようにすることが可能です。本稿ではその方法を解説します。
独自のリポジトリを作る方法はいろいろあるようですが、単にパッケージ名(とバージョン)を指定して pip install できるようにするだけならとても簡単にできます。必要なものは Nginx 等の静的ウェブサーバだけ です。
1. 配布パッケージを作成する
Pythonのモジュール群を.tar.gzで圧縮された配布パッケージにします。この辺りはググれば出てくるので経験がなければ他の記事も参考にしながら行ってください。ここではモジュールのディレクトリ構造や __init__.py の話等、触れてないことも多いので。python setup.py sdist で行うのが現時点でも主流なのでそのキーワードでググればたくさん出てきます。
ここでは setup.py sdist を使わない、これから主流になるであろう新しいやり方でやります。必要なファイルは2つ、./pyproject.toml と ./setup.py です。./setup.py は過去の方法との互換性が目的で、いらないかもしれません。それぞれの中身は以下のようにします。
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "packageA"
version = "1.0.0"
description = "パッケージの説明"
dependencies = ["numpy", "requests"]
from setuptools import setup
setup()
./setup.py の中身は固定でいじることはありません。./pyproject.toml において編集が必要な重要な項目は [project] セクションの中の name 、 version 、 dependencies です。それぞれパッケージの名前、バージョン、依存するパッケージリストです。依存するパッケージのリストはこのパッケージがインストールされる時に同時にインストールしてくれます。
配布パッケージファイルを生成するには build というパッケージがいるのでインストールします。
$ pip install build
この build を使って配布パッケージファイルを生成します。
$ python -m build
実行すると ./dist/ ディレクトリ以下に packageA-1.0.0.tar.gz というファイルが生成されます。これが配布パッケージファイルです。
2. 静的ウェブサーバを用意
NginxでもApacheでもなんでもいいのでウェブサーバを用意し、ローカルのディレクトリ内をHTTPで公開するようにします。そして重要なのはディレクトリ(/で終わるURL)にアクセスしたときに、ディレクトリ内のディレクトリやファイルのリストを自動で生成して返す機能をオンにします。Nginxならautoindex on;がこれにあたります。Apacheはデフォルトでオンだったと思います。
以下の例ではNginxをDockerで立てており、./public/ディレクトリ以下が公開されます。
services:
web:
image: nginx
volumes:
- "./nginx-default.conf:/etc/nginx/conf.d/default.conf:ro"
- "./public/:/usr/share/nginx/html:ro"
ports:
- "80:80"
server {
listen 80;
location / {
alias /usr/share/nginx/html/;
autoindex on;
}
}
3. 配布パッケージを配置
公開したディレクトリ内に規定のディレクトリ構造で配布パッケージを配置します。そうすることで pip install で扱えるリポジトリとなります。規定のディレクトリ構造とは パッケージ名のディレクトリの下に配布パッケージファイルを置く だけです。例えばpackageAとpackageBという名前のパッケージをバージョンの違いで複数公開するなら、
+ packageA + packageA-1.0.0.tar.gz
| + packageA-1.0.1.tar.gz
| + packageA-2.0.0.tar.gz
+ packageB + packageB-1.0.0.tar.gz
+ packageB-1.1.0.tar.gz
といった感じです。.tar.gzのパッケージファイルの名前は生成した時のまま変えないようにします。
これでリポジトリを立てられました。
4. 立てたリポジトリを使ってpip install
立てたリポジトリ内のパッケージを pip install するには --extra-index-url オプションを使います。オプションの引数には立てたリポジトリのURLを指定します。例えば https://example.net/pypi/ 以下に配置されたパッケージ packageA のバージョン1.0.1をインストールするなら、
$ pip install --extra-index-url https://example.net/pypi/ packageA==1.0.1
のようになります。
上の例はhttpsでしたが、httpだとおそらくエラーになります。その場合は --trusted-host example.net のように --trusted-host オプションを追加します。
オプションを毎回書くのが面倒な場合は pip.conf ファイル内に設定を書いておくこともできます。pip.conf の配置場所は仮想環境を使っているなら $VIRTUAL_ENV/pip.conf です。
[global]
extra-index-url = http://example.net/
trusted-host = example.net
あとがき
ググるとなんか複雑なことしてる記事が多かったので書いた記事。おそらく検索とか配布パッケージのアップロードをコマンドラインからやるとかしたいなら、特別なソフトがいるのだと思うが、単にパッケージ名を指定してインストールできれば良いだけならすごく簡単にできるよという話。