chat-hatenablogをpip installでインストール可能にした - $shibayu36->blog; にて、pip installで直接CLIツールをインストールできるようにした。
pip install git+https://github.com/shibayu36/chat-hatenablog.git
この時に調べたことをメモしておく。
やったこと
setup.pyを配置し、entry_points.console_scriptsにCLIとして動かしたいものを指定するだけ。
import os from setuptools import setup, find_packages here = os.path.abspath(os.path.dirname(__file__)) about = {} with open(os.path.join(here, "chat_hatenablog", "__version__.py")) as f: exec(f.read(), about) setup( name="chat_hatenablog", version=about["__version__"], author="Yuki Shibazaki", author_email="shibayu36@gmail.com", description="AI-powered software to interact with your HatenaBlog", license="MIT", packages=find_packages(), install_requires=[ "python-dotenv==1.0.0", "html2text==2020.1.16", "langchain==0.0.132", "tqdm==4.65.0", "openai==0.27.4", "tenacity==8.2.2", "tiktoken==0.3.3", "numpy==1.24.2", ], extras_require={ "dev": [ "pytest==7.3.1", "mypy==1.2.0", "pytest-mypy-plugins==1.10.1", "types-tqdm==4.65.0.1", ], }, entry_points={ "console_scripts": [ "chat-hatenablog = chat_hatenablog.main:main", ] }, )
このように配置するだけで、pip install git+https://github.com/shibayu36/chat-hatenablog.git
するとchat-hatenablogコマンドがインストールされる。
もう少し詳しい説明をする。
基本はsetup.pyを置いておくだけでGitHubからインストールできる
そもそもpip installがgit repositoryに対応しているため、setup.pyを置いてpipが認識できるようにしたら良い。meta情報系を色々書き、依存パッケージをinstall_requiresに入れておく。
CLIツールで重要なポイントは、entry_points.console_scriptsへの指定だ。ここに コマンド名 = (package名):(関数名)
という指定を加えておくことで、そのコマンドを実行したときにどの関数を呼び出すか設定できる。chat-hatenablogの場合、chat_hatenablog/main.pyのdef mainの中にエントリーポイントとしての処理を書き、setup.pyからそこを指定した。
ちなみに最近の形式としてpyproject.tomlを使った方式もあるが、機能が多くていまいちよくわからず、一旦シンプルにsetup.py形式でやってみた。もちろん色々便利なグッズは揃っているはずなので、また試してみたい。 参考: https://qiita.com/ieiringoo/items/4bef4fc9975803b08671
extras_requireに開発向けの依存パッケージを置く
pytestなどはインストール時には不要で、開発向けに必要な依存パッケージである。このようなものもsetup.pyで管理ができる。具体的にはextras_requireにラベル付きで依存パッケージを書ける。
extras_require={ "dev": [ "pytest==7.3.1", "mypy==1.2.0", "pytest-mypy-plugins==1.10.1", "types-tqdm==4.65.0.1", ], },
このようにしておくと次のように指定することで、editorialモードでdevも含めてインストールし、開発を始めることができる。
pip install -e '.[dev]'
version情報を一箇所にまとめる
ツール内でバージョン情報を使うために、現在のchat-hatenablogのバージョン情報をchat_hatenablog/__version__.py
というファイル内に入れていた。setup.pyからもこれをimportして使えば良いだけと考えた。しかしこの状態でpip install -e '.[dev]'
すると、次のようなエラーでうまくいかなかった。
ModuleNotFoundError: No module named 'numpy'
おそらくこれはfrom chat_hatenablog/__version__ import __version__
したタイミングでいろんなモジュールの読み込みは走ってしまっており1、pip install時には依存モジュールは入っていないためエラーになってしまっているようだ。
これに関してはpipenvの例が参考になった。__version__.py
に定義されているデータだけ読み込むためにexecするという技。
here = os.path.abspath(os.path.dirname(__file__)) about = {} with open(os.path.join(here, "pipenv", "__version__.py")) as f: exec(f.read(), about)
これを参考にしてversion情報は__version__.py
で管理し、setup.pyではそれを利用することができた。この辺りはもしかすると別ツールを使うと簡単にできるかもしれないので、また調べてみたい。
まとめ
今回はchat-hatenablogをpip installできるようにした時に調べたことをまとめてみた。こうするともっと便利という情報があれば知りたい。
参考資料
- https://blog.shibayu36.org/entry/2023/04/30/161733
- https://pip.pypa.io/en/stable/topics/vcs-support/
- https://qiita.com/ieiringoo/items/4bef4fc9975803b08671
- https://github.com/pypa/pipenv/blob/678cffdfa358216efbe379b5a786164bf528e4c4/setup.py#L13-L16
-
もちろん
chat_hatenablog/__version__.py
にはversion情報しか入れておらず、他のimport文はなかったが、ロードのなんらかの仕組みで__init__.py
など別ファイルも読み込まれてしまっているのだろう↩