
Pythonパッケージの依存関係とライセンスを確認する
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
データアナリティクス事業本部のkobayashiです。
Pythonを使って開発を行っていると、AWSのリソースを扱う際にはboto3でしたりデータ解析を行う場合はPnadas,Scipyなど様々なパッケージを使っているかと思います。
今回、その利用しているパッケージの依存関係やパッケージを調べる機会があったのでその方法をまとめたいと思います。
環境
- Python 3.7.4
- pipdeptree 1.0.0
- pip-licenses 2.2.1
パッケージ依存関係とライセンスを調べるツール
今回使用したツールは以下になります。どちらのツールもきちんと継続的にメンテナンスされており、pipでインストールできるのでこれらを使いました。
- パッケージ依存関係をツリーで表示するツール
- pipdeptree · PyPI
pipでインストールしたPythonパッケージを依存関係ツリー形式で表示するCLIツール
- pipdeptree · PyPI
- パッケージのライセンス上表を表示するツール
- pip-licenses · PyPI
pipでインストールしたPythonパッケージのソフトウェアライセンスを確認するCLIツール
- pip-licenses · PyPI
pipdeptreeとpip-licensesを使いパッケージを調べる
pipdeptreeとpip-licensesもpip listで表示されるパッケージが対象になるので、マシンにインストールされたPythonパッケージを調べる際は特に環境を作るなどは必要なくpipでこれらのツールをインストールして使えばよいのですが、これらのツールを使う場面としてはプロジェクト単位で利用するPythonパッケージの依存関係やライセンス情報を使う場面だと思います。
今回はこのように特定のPythonパッケージだけを対象にした場合を想定して進めます。
準備
まずはじめにPythonの仮想環境を作成します。簡単にPython3.3で追加されたvenvで構築します。
# ディレクトリを作成
$ mkdir {プロジェクト名}
$ cd {プロジェクト名}
# venvの名前で仮想環境を作成
$ python3 -m venv venv
# 仮想環境を有効化
$ source venv/bin/activate
パッケージをインストール
調査したいパッケージをrequirements.txtにまとめてインストールします。
今回は以下のパッケージを調べてみたいと思います。
$ cat requirements.txt pipdeptree pip-licenses boto3 pandas pyodbc scipy matplotlib scikit-learn scrapy MoviePy bottle
pipdeptreeとpip-licensesもpipでインストールする必要があるのでrequirements.txtのリストに含めて一緒にインストールしてしまいます。
# 仮想環境のPythonバージョン確認
(venv) kobayashi@localhost% python -V
Python 3.7.4
# パッケージリストを表示
(venv) kobayashi@localhost% pip list
Package Version
---------- -------
pip 19.0.3
setuptools 40.8.0
# requirements.txtファイルからパッケージのインストール
(venv) kobayashi@localhost% pip install -r requirements.txt
Collecting pip-licenses (from -r requirements.txt (line 1))
Using cached https://files.pythonhosted.org/packages/2e/8a/b8eb114545d9e984fcc013ef544c487aa2c02489a66185a82108625784a5/pip_licenses-2.2.1-py3-none-any.whl
Collecting pipdeptree (from -r requirements.txt (line 2))
Using cached https://files.pythonhosted.org/packages/5c/3f/4a3e02c283fb7d3084456cbca8d22b790b9e176b4c0075bc38e5abe166c6/pipdeptree-1.0.0-py3-none-any.whl
Collecting boto3 (from -r requirements.txt (line 3))
Downloading https://files.pythonhosted.org/packages/94/8b/42119ee46d95952d082876d4d00f74f381f0a9d987de18781a15ba34057d/boto3-1.14.28-py2.py3-none-any.whl (128kB)
100% |████████████████████████████████| 133kB 3.1MB/s
Collecting pandas (from -r requirements.txt (line 4))
Using cached https://files.pythonhosted.org/packages/5d/24/91ad2da4a1da2747595d2f47f858a131036f598fb495ec6346d08d8b8df6/pandas-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl
Collecting pyodbc (from -r requirements.txt (line 5))
Downloading https://files.pythonhosted.org/packages/4a/a3/3de345058cccc78f43a11f9b08ac9b756542cf3d36457704f2432b2f344d/pyodbc-4.0.30-cp37-cp37m-macosx_10_9_x86_64.whl (63kB)
100% |████████████████████████████████| 71kB 7.3MB/s
...
# パッケージリストを表示
(venv) kobayashi@localhost% pip list
Package Version
---------------- ---------
attrs 19.3.0
Automat 20.2.0
boto3 1.14.33
botocore 1.17.33
bottle 0.12.18
certifi 2020.6.20
cffi 1.14.1
chardet 3.0.4
constantly 15.1.0
cryptography 3.0
cssselect 1.1.0
cycler 0.10.0
decorator 4.4.2
docutils 0.15.2
hyperlink 19.0.0
idna 2.10
imageio 2.9.0
imageio-ffmpeg 0.4.2
incremental 17.5.0
itemadapter 0.1.0
jmespath 0.10.0
joblib 0.16.0
kiwisolver 1.2.0
lxml 4.5.2
matplotlib 3.3.0
moviepy 1.0.3
numpy 1.19.1
pandas 1.1.0
parsel 1.6.0
Pillow 7.2.0
pip 19.0.3
pip-licenses 2.3.0
pipdeptree 1.0.0
proglog 0.1.9
Protego 0.1.16
PTable 0.9.2
pyasn1 0.4.8
pyasn1-modules 0.2.8
pycparser 2.20
PyDispatcher 2.0.5
PyHamcrest 2.0.2
pyodbc 4.0.30
pyOpenSSL 19.1.0
pyparsing 2.4.7
python-dateutil 2.8.1
pytz 2020.1
queuelib 1.5.0
requests 2.24.0
s3transfer 0.3.3
scikit-learn 0.23.1
scipy 1.5.2
Scrapy 2.2.1
service-identity 18.1.0
setuptools 40.8.0
six 1.15.0
threadpoolctl 2.1.0
tqdm 4.48.0
Twisted 20.3.0
urllib3 1.25.10
w3lib 1.22.0
zope.interface 5.1.0
以上で準備が終わったので実際にCLIで依存関係とライセンスを確認してみます。
pipdeptreeで依存関係を確認
Python仮想環境を有効化した上でpipdeptreeコマンドを実行します。
pip freezeと違い最上位のパッケージに対して依存しているパッケージがツリー形式で表示され依存関係が非常にわかりやすくなっています。
(venv) kobayashi@localhost% pipdeptree
boto3==1.14.33
- botocore [required: >=1.17.33,<1.18.0, installed: 1.17.33]
- docutils [required: >=0.10,<0.16, installed: 0.15.2]
- jmespath [required: >=0.7.1,<1.0.0, installed: 0.10.0]
- python-dateutil [required: >=2.1,<3.0.0, installed: 2.8.1]
- six [required: >=1.5, installed: 1.15.0]
- urllib3 [required: >=1.20,<1.26, installed: 1.25.10]
- jmespath [required: >=0.7.1,<1.0.0, installed: 0.10.0]
- s3transfer [required: >=0.3.0,<0.4.0, installed: 0.3.3]
- botocore [required: >=1.12.36,<2.0a.0, installed: 1.17.33]
- docutils [required: >=0.10,<0.16, installed: 0.15.2]
- jmespath [required: >=0.7.1,<1.0.0, installed: 0.10.0]
- python-dateutil [required: >=2.1,<3.0.0, installed: 2.8.1]
- six [required: >=1.5, installed: 1.15.0]
- urllib3 [required: >=1.20,<1.26, installed: 1.25.10]
bottle==0.12.18
matplotlib==3.3.0
- cycler [required: >=0.10, installed: 0.10.0]
- six [required: Any, installed: 1.15.0]
- kiwisolver [required: >=1.0.1, installed: 1.2.0]
- numpy [required: >=1.15, installed: 1.19.1]
- pillow [required: >=6.2.0, installed: 7.2.0]
- pyparsing [required: >=2.0.3,!=2.1.6,!=2.1.2,!=2.0.4, installed: 2.4.7]
- python-dateutil [required: >=2.1, installed: 2.8.1]
- six [required: >=1.5, installed: 1.15.0]
moviepy==1.0.3
- decorator [required: >=4.0.2,<5.0, installed: 4.4.2]
- imageio [required: >=2.5,<3.0, installed: 2.9.0]
- numpy [required: Any, installed: 1.19.1]
- pillow [required: Any, installed: 7.2.0]
- imageio-ffmpeg [required: >=0.2.0, installed: 0.4.2]
- numpy [required: >=1.17.3, installed: 1.19.1]
- numpy [required: Any, installed: 1.19.1]
- proglog [required: <=1.0.0, installed: 0.1.9]
- tqdm [required: Any, installed: 4.48.0]
- requests [required: >=2.8.1,<3.0, installed: 2.24.0]
- certifi [required: >=2017.4.17, installed: 2020.6.20]
- chardet [required: >=3.0.2,<4, installed: 3.0.4]
- idna [required: >=2.5,<3, installed: 2.10]
- urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.25.10]
- tqdm [required: >=4.11.2,<5.0, installed: 4.48.0]
pandas==1.1.0
- numpy [required: >=1.15.4, installed: 1.19.1]
- python-dateutil [required: >=2.7.3, installed: 2.8.1]
- six [required: >=1.5, installed: 1.15.0]
- pytz [required: >=2017.2, installed: 2020.1]
pip-licenses==2.3.0
- PTable [required: Any, installed: 0.9.2]
pipdeptree==1.0.0
- pip [required: >=6.0.0, installed: 19.0.3]
pyodbc==4.0.30
scikit-learn==0.23.1
- joblib [required: >=0.11, installed: 0.16.0]
- numpy [required: >=1.13.3, installed: 1.19.1]
- scipy [required: >=0.19.1, installed: 1.5.2]
- numpy [required: >=1.14.5, installed: 1.19.1]
- threadpoolctl [required: >=2.0.0, installed: 2.1.0]
Scrapy==2.2.1
- cryptography [required: >=2.0, installed: 3.0]
- cffi [required: >=1.8,!=1.11.3, installed: 1.14.1]
- pycparser [required: Any, installed: 2.20]
- six [required: >=1.4.1, installed: 1.15.0]
- cssselect [required: >=0.9.1, installed: 1.1.0]
- itemadapter [required: >=0.1.0, installed: 0.1.0]
- lxml [required: >=3.5.0, installed: 4.5.2]
- parsel [required: >=1.5.0, installed: 1.6.0]
- cssselect [required: >=0.9, installed: 1.1.0]
- lxml [required: Any, installed: 4.5.2]
- six [required: >=1.6.0, installed: 1.15.0]
- w3lib [required: >=1.19.0, installed: 1.22.0]
- six [required: >=1.4.1, installed: 1.15.0]
- protego [required: >=0.1.15, installed: 0.1.16]
- six [required: Any, installed: 1.15.0]
- PyDispatcher [required: >=2.0.5, installed: 2.0.5]
- pyOpenSSL [required: >=16.2.0, installed: 19.1.0]
- cryptography [required: >=2.8, installed: 3.0]
- cffi [required: >=1.8,!=1.11.3, installed: 1.14.1]
- pycparser [required: Any, installed: 2.20]
- six [required: >=1.4.1, installed: 1.15.0]
- six [required: >=1.5.2, installed: 1.15.0]
- queuelib [required: >=1.4.2, installed: 1.5.0]
- service-identity [required: >=16.0.0, installed: 18.1.0]
- attrs [required: >=16.0.0, installed: 19.3.0]
- cryptography [required: Any, installed: 3.0]
- cffi [required: >=1.8,!=1.11.3, installed: 1.14.1]
- pycparser [required: Any, installed: 2.20]
- six [required: >=1.4.1, installed: 1.15.0]
- pyasn1 [required: Any, installed: 0.4.8]
- pyasn1-modules [required: Any, installed: 0.2.8]
- pyasn1 [required: >=0.4.6,<0.5.0, installed: 0.4.8]
- Twisted [required: >=17.9.0, installed: 20.3.0]
- attrs [required: >=19.2.0, installed: 19.3.0]
- Automat [required: >=0.3.0, installed: 20.2.0]
- attrs [required: >=19.2.0, installed: 19.3.0]
- six [required: Any, installed: 1.15.0]
- constantly [required: >=15.1, installed: 15.1.0]
- hyperlink [required: >=17.1.1, installed: 19.0.0]
- idna [required: >=2.5, installed: 2.10]
- incremental [required: >=16.10.1, installed: 17.5.0]
- PyHamcrest [required: >=1.9.0,!=1.10.0, installed: 2.0.2]
- zope.interface [required: >=4.4.2, installed: 5.1.0]
- setuptools [required: Any, installed: 40.8.0]
- w3lib [required: >=1.17.0, installed: 1.22.0]
- six [required: >=1.4.1, installed: 1.15.0]
- zope.interface [required: >=4.1.3, installed: 5.1.0]
- setuptools [required: Any, installed: 40.8.0]
他にpipdeptreeコマンドの使い方として、-rオプションを使って依存されているパッケージから依存しているパッケージを表示することもできます。
(venv) kobayashi@localhost% pipdeptree -r --p botocore,six
botocore==1.17.29
- boto3==1.14.29 [requires: botocore>=1.17.29,<1.18.0]
- s3transfer==0.3.3 [requires: botocore>=1.12.36,<2.0a.0]
- boto3==1.14.29 [requires: s3transfer>=0.3.0,<0.4.0]
six==1.15.0
- Automat==20.2.0 [requires: six]
- Twisted==20.3.0 [requires: Automat>=0.3.0]
- Scrapy==2.2.1 [requires: Twisted>=17.9.0]
- cryptography==3.0 [requires: six>=1.4.1]
...
他オプションはpipdeptree -hで確認するか、公式サイト(GitHub - naiquevin/pipdeptree: A command line utility to display dependency tree of the installed Python packages)をご確認ください。
pip-licensesでライセンス情報を確認
こちらもPython仮想環境を有効化した上でpip-licensesコマンドを実行します。
(venv) kobayashi@localhost% pip-licenses Name Version License Automat 20.2.0 MIT Pillow 7.2.0 HPND Protego 0.1.16 BSD PyDispatcher 2.0.5 BSD PyHamcrest 2.0.2 New BSD Scrapy 2.2.1 BSD Twisted 20.3.0 MIT attrs 19.3.0 MIT boto3 1.14.33 Apache License 2.0 botocore 1.17.33 Apache License 2.0 bottle 0.12.18 MIT certifi 2020.6.20 MPL-2.0 cffi 1.14.1 MIT chardet 3.0.4 LGPL constantly 15.1.0 MIT cryptography 3.0 BSD or Apache License, Version 2.0 cssselect 1.1.0 BSD cycler 0.10.0 BSD decorator 4.4.2 new BSD License docutils 0.15.2 public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt) hyperlink 19.0.0 MIT idna 2.10 BSD-like imageio 2.9.0 BSD-2-Clause imageio-ffmpeg 0.4.2 BSD-2-Clause incremental 17.5.0 MIT itemadapter 0.1.0 BSD jmespath 0.10.0 MIT joblib 0.16.0 BSD kiwisolver 1.2.0 BSD lxml 4.5.2 BSD matplotlib 3.3.0 PSF moviepy 1.0.3 MIT License numpy 1.19.1 BSD pandas 1.1.0 BSD parsel 1.6.0 BSD pipdeptree 1.0.0 MIT License proglog 0.1.9 MIT - copyright Edinburgh Genome Foundry pyOpenSSL 19.1.0 Apache License, Version 2.0 pyasn1 0.4.8 BSD pyasn1-modules 0.2.8 BSD-2-Clause pycparser 2.20 BSD pyodbc 4.0.30 MIT pyparsing 2.4.7 MIT License python-dateutil 2.8.1 Dual License pytz 2020.1 MIT queuelib 1.5.0 BSD requests 2.24.0 Apache 2.0 s3transfer 0.3.3 Apache License 2.0 scikit-learn 0.23.1 new BSD scipy 1.5.2 BSD service-identity 18.1.0 MIT six 1.15.0 MIT threadpoolctl 2.1.0 UNKNOWN tqdm 4.48.0 MPLv2.0, MIT Licences urllib3 1.25.10 MIT w3lib 1.22.0 BSD zope.interface 5.1.0 ZPL 2.1
pip-licensesコマンドにもいろいろなオプションがあります。これらを使って必要な情報を必要な形式で出力できますのでいくつかオプションの使用例を記載します。
- 公式サイトと詳細説明も表示する
(venv) kobayashi@localhost% pip-licenses --with-urls --with-description Name Version License URL Description PyYAML 5.1.2 MIT https://github.com/yaml/pyyaml YAML parser and emitter for Python awscli 1.16.286 Apache License 2.0 http://aws.amazon.com/cli/ Universal Command Line Environment for AWS. boto3 1.9.235 Apache License 2.0 https://github.com/boto/boto3 The AWS SDK for Python botocore 1.13.22 Apache License 2.0 https://github.com/boto/botocore Low-level, data-driven core of boto 3. ...
-
公式サイトと詳細説明の情報を付加し、csv形式でpython-licenses.csvファイルに出力する
(venv) kobayashi@localhost% pip-licenses --with-urls --format=csv --with-description --output-file=python-licenses.csv
他オプションはpip-licenses -hで確認するか、公式サイト(GitHub - raimon49/pip-licenses: Dump the license list of packages installed with pip.)をご確認ください。
一応最後にPython仮想環境を抜ける処理を記述しておきます。
(venv) kobayashi@localhost% deactivate
まとめ
pipdeptreeとpip-licensesを使ってPythonパッケージの依存関係とライセンス情報を取得してみました。頻繁に使う場面はありませんが、プロジェクトが立ち上がった際など要所要所では必要になってくると思います。
最後まで読んで頂いてありがとうございました。






