■はじめに
「GitHubのPrivate Repositoryで管理されているライブラリをPipenvから使いたい」場合に苦戦したのでまとめておきます。
○(2019/08時点) Pipenvで環境変数からクレデンシャルを差し込む方法について
公式ドキュメントが非常にわかりづらいのですが、環境変数でPipfileにクレデンシャルを差し込む機能が有効になるのはPipfile中の[[source]]
内だけのようです。
bundlerの類似機能とは挙動が違うっぽいのでご注意ください。
で、上記のやりとりを見たところ「そういう場合は.netrcを使え」とのこと。
■Private Libraryを準備
既にPrivate Libraryがあればそれを使っていただければと思いますが、今回はcookiecutterを使い、サンプルライブラリを準備するところからやってみます。
$ pip install -U cookiecutter
$ cookiecutter https://github.com/audreyr/cookiecutter-pypackage
cookiecutter https://github.com/audreyr/cookiecutter-pypackage
full_name [Audrey Roy Greenfeld]:
email [audreyr@example.com]:
github_username [audreyr]: terukizm
project_name [Python Boilerplate]: MyPrivateLibSamplePy
project_slug [myprivatelibsamplepy]: MyPrivateLibSamplePy
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]:
pypi_username [terukizm]:
version [0.1.0]:
use_pytest [n]:
use_pypi_deployment_with_travis [y]:
add_pyup_badge [n]:
Select command_line_interface:
1 - Click
2 - No command-line interface
Choose from 1, 2 (1, 2) [1]:
create_author_file [y]:
Select open_source_license:
1 - MIT license
2 - BSD license
3 - ISC license
4 - Apache Software License 2.0
5 - GNU General Public License v3
6 - Not open source
Choose from 1, 2, 3, 4, 5, 6 (1, 2, 3, 4, 5, 6) [1]:
$ ls MyPrivateLibSamplePy/
MyPrivateLibSamplePy.py
__init__.py
cli.py
生成されたテンプレートを微調整して、ライブラリとして動作確認しやすくしておきます。(MyPrivateLibSamplePy.message()
)
--- a/MyPrivateLibSamplePy/MyPrivateLibSamplePy.py
+++ b/MyPrivateLibSamplePy/MyPrivateLibSamplePy.py
@@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
"""Main module."""
+def message():
+ return "This is My Private Lib."
--- a/MyPrivateLibSamplePy/cli.py
+++ b/MyPrivateLibSamplePy/cli.py
@@ -3,14 +3,14 @@
"""Console script for MyPrivateLibSamplePy."""
import sys
import click
+import MyPrivateLibSamplePy
@click.command()
def main(args=None):
"""Console script for MyPrivateLibSamplePy."""
- click.echo("Replace this message by putting your code into "
- "MyPrivateLibSamplePy.cli.main")
- click.echo("See click documentation at http://click.pocoo.org/")
+ text = MyPrivateLibSamplePy.message()
+ click.echo(text)
return 0
動作確認ができたら、GitHubのPrivate Repositoryにgit pushしておきましょう。
$ python MyPrivateLibSamplePy/cli.py
This is My Private Lib.
$ git init
(略)
$ git push -u origin master
上記のサンプルライブラリは以下に置いてありますので、forkしたあとにリポジトリをprivateにしていただくのでもよいかも。
https://github.com/terukizm/MyPrivateLibSamplePy
■Pipenvから利用
用意したライブラリは当然認証を通さないとpip install(git clone)
できません。ローカルから使う場合ならSSH認証(git+ssh
)で問題ないのですが、今回はDocker Imageで利用する場合を想定し、.netrc
とGitHub Personal Access Tokenを利用します。1
取得したPersonal Access Tokenを.netrc
に設定します。tokenはlogin
に設定してください。
machine github.com
login xxxxxxxxxxxxxxxxxxxxx
password x-oauth-basic
この状態でgit+https
を指定してpipenv install
します。Pipfile
にライブラリが追加されていること、pip freeze
でライブラリが利用できる状態になっていることを確認してください。
$ mkdir ~/netrc-pipenv-sample
$ pipenv install git+https://github.com/terukizm/MyPrivateLibSamplePy.git#egg=MyPrivateLibSamplePy
(略)
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 1/1 — 00:00:04
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
$ ls
Pipfile Pipfile.lock
$ cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
myprivatelibsamplepy = {git = "https://github.com/terukizm/MyPrivateLibSamplePy.git"}
[requires]
python_version = "3.7"
$ pipenv run pip freeze | grep MyPrivateLib
MyPrivateLibSamplePy==0.1.0
実際にプログラムから使えることも確認しておくと良いでしょう。
from MyPrivateLibSamplePy import MyPrivateLibSamplePy
message = MyPrivateLibSamplePy.message()
print(f"message: {message}")
$ pipenv run python main.py
message: This is My Private Lib.
■Docker Imageから利用
ここまで確認できたら、あとはDockerfile内で上記の手順を再現するだけです。
機密情報であるPersonal Access TokenについてはCircleCIなどで自動ビルドすることを想定し、--build-arg
でビルド時に指定、pipenv install後には.netrc
を削除することでイメージ内に含めないようにしています。
FROM python:3.7.4
RUN pip install -U pip && pip install pipenv
WORKDIR /opt/pip
ADD Pipfile Pipfile.lock ./
# setup .netrc
ARG GITHUB_TOKEN
RUN echo "machine github.com" > /root/.netrc && \
echo "login $GITHUB_TOKEN" >> /root/.netrc && \
echo "passowrd x-oauth-basic" >> /root/.netrc && \
chmod 600 /root/.netrc
RUN pipenv install --system
RUN rm Pipfile Pipfile.lock
RUN rm /root/.netrc
ADD main.py /src/main.py
CMD ["python", "/src/main.py"]
$ NAME=netrc-pipenv-sample
$ GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxx
$ docker build --build-arg GITHUB_TOKEN=${GITHUB_TOKEN} -t ${NAME}:latest .
...
$ docker run -i -t ${NAME}:latest
message: This is My Private Lib.
こちらにサンプルを置いておきます。参考になれば幸いです。
https://github.com/terukizm/netrc-pipenv-sample
-
docker build(git clone)用にSSHの秘密鍵を払い出してもいいのですが、あんまりそれやりたくないなあという人向けです ↩