はじめに
本記事は、パッケージの作成からPyPI
に登録までの方法を記します。
どちらかというと、備忘録的な感じです。
自作パッケージ公開までの流れ
自作パッケージを公開するまでの流れは以下の通りです。
6ステップでPyPI
に公開できます。
(この中で一番大変なのは、(1 )のパッケージ作成の部分です)
- パッケージ作成(
Python
でコーディング) - pip でインストールできるように設定ファイルの追加
- 配布物の作成
-
test-PyPI
にテスト登録 -
PyPI
に登録 - deploy の自動化
1. ライブラリ作成
<package_name>
にはライブラリの名前にしておくといいです。
numpyやpandas、scikit-learnなどはこの形式です。
ただ、matplotlibは、src
になっているなど例外もあります。
├─ <package_name>/
| └─ __init__.py
└─ README.md
そして、この<package_name>
直下にある__init__.py
で宣言された関数や変数が、
import
後利用できるようになります。pandas
の例で言うと、以下の通りです。
import pandas as pd
pd.read_csv("...")
として、pd.read_csv()
が利用できるのは、__init__.py
の中に関数が宣言されているためです。
(厳密には、__init__.py
の中ではread_csv()
そのものは定義されていません)。
例として、Hoge
クラスを定義しておきます。
class Hoge:
def __init__(self):
pass
このようにしておくと、以下のように利用できます。
import <package_name>
hoge = <package_name>.Hoge()
2. 設定ファイルの追加
適当なライブラリのクラスを定義・作成したら、次は公開の準備をすすめていいきましょう。
最低限必要なファイルはsetup.py
のみです。
setup.py
は、パッケージの情報を記載します。
詳しくは「PyPIパッケージ定義ファイル作成方法 - init.py setup.py MANIFEST.in の書き方」をご覧ください。
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="<package name>",
version="<version>",
author="<your name>",
author_email="<your email>",
description="<short_description>",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/<your_github_name>/<repository_name>",
packages=setuptools.find_packages(),
install_requires=[
"pandas>=1.0.0",
"s3fs>=0.4.2"
],
license="MIT",
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.7',
)
また、必要に応じてMANIFEST.in
を作成します。
これは、配布するパッケージに含める/除くファイルを決められます。
include MANIFEST.in
include setup.py
include README.md
setup.py
とMANIFEST.in
を追加したあとのファイル構成は以下の通りです。
├─ <package_name>/
| └─ __init__.py
├─ setup.py
├─ MANIFEST.in (必要に応じて)
└─ README.md
3. 配布物の作成
setup.py
を作成したら、いよいよPyPI
に登録していきます。
配布用のパッケージ作成とPyPI
にアップロードするように以下のパッケージを install します。
$ pip install twine wheel
次のコマンドを実行し、ソースコード配布物を作成し、ライブラリのパッケージを作成します。
$ python setup.py sdist bdist_wheel
すると、以下のようにフォルダ作成されます。
├─ <package_name>/
| └─ __init__.py
├─ <package_name>.egg-info/
├─ dist/
├─ setup.py
├─ MANIFEST.in (必要に応じて)
└─ README.md
それぞれのファイルは、以下の通りです。
- <パッケージ名>.egg-info ディレクトリ
ソースコード配布物作成時の中間ファイルが書き出されるディレクトリです。
MANIFEST.in から配布物に含めるファイルを削ったとき、それだけでは反映されず、同ディレクトリのファイルを一度削除してリセットする必要があります。
- dist ディレクトリ
パッケージファイルが書き出されるディレクトリです。
パッケージファイルは、同ディレクトリに追加作成されます。
PyPIに不要なファイルをアップロードしてしまわないよう、最初にファイル削除することをお勧めします。
また、パッケージをアップデートする際には以下のコマンドを打ち、
以前のバージョンの配布物が入ってる<package_name>.egg-info
と dist 以下の中身を消すようにしましょう。
これらのファイルは再生成できるため削除してしまって構わないです。
$ rm -f -r <package_name>.egg-info/* dist/*
4. test-PyPI
に登録・アップロード
配布物の作成が終わったら、test-PyPIにテスト登録をしてみましょう。
test-PyPI
でアカウントを作成し、以下のファイルをホームディレクトリに作成します。
(以下ファイルには本番PyPI
の情報も記述してあります)
[distutils]
index-servers =
pypi
testpypi
[pypi]
repository: https://upload.pypi.org/legacy/
username: <本番用アカウント名>
password: <パスワード>
[testpypi]
repository: https://test.pypi.org/legacy/
username: <テスト用アカウント名>
password: <パスワード>
~/.pypirc
の作成が終わったら、次のコマンドを実行し、test-PyPI
に登録します。
$ twine upload -r testpypi dist/*
test-PyPI
に登録ができたら、pip
でインストールできるか確認しましょう。
$ pip install -i https://test.pypi.org/simple/ <package_name>
また、poetry
を利用している場合は以下のpyproject.toml
に以下を追加します。
+ [[tool.poetry.source]]
+ name = "testpypi"
+ url = "https://test.pypi.org/simple/"
+ secondary = true
[tool.poetry]
name = "python_env"
version = "0.1.0"
description = ""
authors = ["your_email"]
[tool.poetry.dependencies]
python = "^3.7"
pandas = "^1.0.3"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
そうすると、通常のpoerty add
コマンドでインストールできるようになります。
$ poerty add <package_name>
このtest-PyPI
を利用して、pip
でインストールできるか確認すると良いです。
ちなみに、test-PyPI
に登録して実際にpip
でインストールできるようになるまで最大で10分程度かかりました。
5. PyPIに登録
test-PyPI
から正しくpip install
ができたら、https://pypi.python.org/に登録しましょう。
まずは、test-PyPI
と同様にユーザーアカウントを作成し、~/.pypirc
にアカウント情報を追記します。
すでに、配布物は作成済みなので、以下のコマンドを実行するだけです。
$ twine upload -r pypi dist/*
実行後は、PyPI
に登録されているか確認後、実際にpip install
してみましょう。
(poerty などで実行する場合は、追加した url を削除しておきましょう)
test-PyPI
に登録が成功すれば、PyPI
への登録もすぐできます。
6. deployの自動化
毎回、同じコマンドを実行するのは大変なので
1つのコマンドで自動削除・配布分作成・PyPI
登録してくれるようにMakefile
を作成しましょう。
※この時、:
の後に続くのはspace
ですが、先頭から文字を入力する場合は、tab
じゃないとMakefile:-: *** missing separator. Stop.
というエラーが出ます。
(Qiita では表示の都合上 space になっているのでそのままコピーしてもエラーになります)
.PHONY: deploy
deploy: build
twine upload dist/*
.PHONY: test-deploy
test-deploy: build
twine upload -r testpypi dist/*
.PHONY: build
build: clean
python setup.py sdist bdist_wheel
.PHONY: clean
clean:
rm -f -r azfs.egg-info/* dist/* -y
上記のようなMakefile
を作成し、以下のコマンドを実行するとPyPI
に登録してくれます。
# テストPyPIの場合
$ make test-deploy
# 本番PyPIの場合
$ make deploy
おわりに
一通り、パッケージ作成からPyPI
登録までの流れを記事にしてみました。
これで皆さんもパッケージ配布できますね。
2020/05/09追記
poetry
ならもっと簡単にできました。
test-PyPI
に登録
# test-pypiのurlを登録
$ poetry config repositories.testpypi https://test.pypi.org/legacy/
$ poetry config --list
> cache-dir = "/Users/<user_name>/Library/Caches/pypoetry"
> repositories.testpypi.url = "https://test.pypi.org/legacy/"
> virtualenvs.create = true
> virtualenvs.in-project = true
> virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/<user_name>/Library/Caches/pypoetry/virtualenvs
$ poetry build
$ poetry publish -r testpypi -u <user_name> -p <password>
PyPI
に登録
$ poetry build
$ poetry publish -u <user_name> -p <password>