pypicloudで遊ぶ
主な目的
- 自分が使ってるpypicloud環境のおさらい
- 途中段階の記事化
スクラップ内の前提
- Arch Linux
- Python 3.9
- Poetry
ローカル向けにPyPIを用意する
インストール
素のパッケージではHTTPサーバー系ライブラリがないので、extraとしてserver
を追加。[1]
$ poetry init
(面倒なので、全部Enter)
$ poetry add 'pypicloud[server]'
環境の準備
とりあえずのローカル用なので、シンプルな設定にする。
$ poetry run pypicloud-make-config config.ini
[1] dev
[2] test
[3] prod
What is this config file for? 1
[1] s3
[2] gcs
[3] filesystem
[4] azure-blob
Where do you want to store your packages? 3
Admin username? admin
Password:
Password:
Config file written to 'config.ini'
起動
Pyramid製なので、pserve
でそのまま起動可能
$ poetry run pserve config.ini
INFO 2021-02-23 14:54:36,375 [pypicloud.cache.base] Cache is empty. Rebuilding from storage backend...
INFO 2021-02-23 14:54:36,375 [pypicloud.cache.base] Cache repopulated
Starting server in PID 2739933.
Serving on http://0.0.0.0:6543
-
waitress
がインストール対象になる ↩︎
簡単に動作確認する
使う
ブラウザでアクセスしてみる
当然だけど、初期状態では空っぽ
pip 経由でアクセスしてみる
python -m venv .venv
で別環境を用意して、インデックスに起動したサーバーを指定しつつpypicloud
をインストールしてみる。
$ pip install -i http://localhost:6543/simple/ 'pypicloud[server]'
(中略)
pypicloud
Running setup.py install for beaker ... done
Running setup.py install for pyramid-beaker ... done
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 PasteDeploy-2.1.1 SQLAlchemy-1.3.23 beaker-1.11.0 boto3-1.17.13 botocore-1.20.13 certifi-2020.12.5 cffi-1.14.5 chardet-4.0.0 cryptography-3.4.6 distlib-0.3.1 hupper-1.10.2 idna-2.10 jmespath-0.10.0 passlib-1.7.4 paste-3.5.0 plaster-1.0 plaster-pastedeploy-0.7 pycparser-2.20 pypicloud-1.1.7 pyramid-1.10.7 pyramid-beaker-0.8 pyramid-duh-0.1.2 pyramid-jinja2-2.8 pyramid-rpc-0.8 pyramid-tm-2.4 python-dateutil-2.8.1 requests-2.25.1 s3transfer-0.3.4 six-1.15.0 transaction-3.0.1 translationstring-1.4 urllib3-1.26.3 venusian-3.0.0 waitress-1.4.4 webob-1.8.7 zope.deprecation-4.4.0 zope.interface-5.2.0 zope.sqlalchemy-1.3
特に問題なくインストールできる。
サーバーの配下フォルダの様子を見る
$ ls -l
-rw-r--r-- 1 attakei attakei 1389 Feb 23 14:42 config.ini
-rw-r--r-- 1 attakei attakei 24576 Feb 23 14:54 db.sqlite
drwxr-xr-x 2 attakei attakei 6 Feb 23 14:54 packages
-rw-r--r-- 1 attakei attakei 48737 Feb 23 14:26 poetry.lock
-rw-r--r-- 1 attakei attakei 339 Feb 23 14:26 pyproject.toml
db.sqlite
と packages
が増えている。が、出番はちょっと先
ローカルでキャッシュする
Before
$ time .venv/bin/pip install -i http://localhost:6543/simple/ 'pypicloud[server]'
(中略)
Looking in indexes: http://localhost:6543/simple/
(中略)
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 PasteDeploy-2.1.1 SQLAlchemy-1.3.23 beaker-1.11.0 boto3-1.17.13 botocore-1.20.13 certifi-2020.12.5 cffi-1.14.5 chardet-4.0.0 cryptography-3.4.6 distlib-0.3.1 hupper-1.10.2 idna-2.10 jmespath-0.10.0 passlib-1.7.4 paste-3.5.0 plaster-1.0 plaster-pastedeploy-0.7 pycparser-2.20 pypicloud-1.1.7 pyramid-1.10.7 pyramid-beaker-0.8 pyramid-duh-0.1.2 pyramid-jinja2-2.8 pyramid-rpc-0.8 pyramid-tm-2.4 python-dateutil-2.8.1 requests-2.25.1 s3transfer-0.3.4 six-1.15.0 transaction-3.0.1 translationstring-1.4 urllib3-1.26.3 venusian-3.0.0 waitress-1.4.4 webob-1.8.7 zope.deprecation-4.4.0 zope.interface-5.2.0 zope.sqlalchemy-1.3
.venv/bin/pip install -i http://localhost:6543/simple/ 'pypicloud[server]' 6.79s user 0.58s system 57% cpu 12.913 total
設定を変更する
+pypi.fallback = cache
+
pypi.default_read =
everyone
pypi.default_write =
authenticated
+pypi.cache_update =
everyone
pypi.storage = file
storage.dir = %(here)s/packages
After
pip
を実行すると、pypicloudのサーバーからwheelをダウンロードしている。
Beforeと比較すると速くなってはいない。[1]
$ time .venv/bin/pip install -i http://localhost:6543/simple/ 'pypicloud[server]'
Looking in indexes: http://localhost:6543/simple/
Collecting pypicloud[server]
Downloading http://localhost:6543/api/package/pypicloud/pypicloud-1.1.7-py2.py3-none-any.whl (537 kB)
|████████████████████████████████| 537 kB 57.5 MB/s
(中略)
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 PasteDeploy-2.1.1 SQLAlchemy-1.3.23 beaker-1.11.0 boto3-1.17.13 botocore-1.20.13 certifi-2020.12.5 cffi-1.14.5 chardet-4.0.0 cryptography-3.4.6 distlib-0.3.1 hupper-1.10.2 idna-2.10 jmespath-0.10.0 passlib-1.7.4 paste-3.5.0 plaster-1.0 plaster-pastedeploy-0.7 pycparser-2.20 pypicloud-1.1.7 pyramid-1.10.7 pyramid-beaker-0.8 pyramid-duh-0.1.2 pyramid-jinja2-2.8 pyramid-rpc-0.8 pyramid-tm-2.4 python-dateutil-2.8.1 requests-2.25.1 s3transfer-0.3.4 six-1.15.0 transaction-3.0.1 translationstring-1.4 urllib3-1.26.3 venusian-3.0.0 waitress-1.4.4 webob-1.8.7 zope.deprecation-4.4.0 zope.interface-5.2.0 zope.sqlalchemy-1.3
.venv/bin/pip install -i http://localhost:6543/simple/ 'pypicloud[server]' 7.41s user 0.43s system 30% cpu 25.938 total
サーバーの出力のほう。キャッシュするために、pypicloudがWheelをダウンロードしていっている。
中間キャッシュとして一度ダウンロードしている以上、初回は遅いのは普通の挙動。
INFO 2021-02-23 17:32:07,394 [pypicloud.views.api] Caching python_dateutil-2.8.1-py2.py3-none-any.whl from https://pypi.org/simple
INFO 2021-02-23 17:32:07,783 [pypicloud.views.api] Caching pycparser-2.20-py2.py3-none-any.whl from https://pypi.org/simple
INFO 2021-02-23 17:32:08,339 [pypicloud.views.api] Caching PasteDeploy-2.1.1-py2.py3-none-any.whl from https://pypi.org/simple
After-2
.venv
をまっさらにしてもう一回。
$ time .venv/bin/pip install -i http://localhost:6543/simple/ 'pypicloud[server]'
Looking in indexes: http://localhost:6543/simple/
Collecting pypicloud[server]
Downloading http://localhost:6543/api/package/pypicloud/pypicloud-1.1.7-py2.py3-none-any.whl (537 kB)
|████████████████████████████████| 537 kB 95.7 MB/s
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 PasteDeploy-2.1.1 SQLAlchemy-1.3.23 beaker-1.11.0 boto3-1.17.13 botocore-1.20.13 certifi-2020.12.5 cffi-1.14.5 chardet-4.0.0 cryptography-3.4.6 distlib-0.3.1 hupper-1.10.2 idna-2.10 jmespath-0.10.0 passlib-1.7.4 paste-3.5.0 plaster-1.0 plaster-pastedeploy-0.7 pycparser-2.20 pypicloud-1.1.7 pyramid-1.10.7 pyramid-beaker-0.8 pyramid-duh-0.1.2 pyramid-jinja2-2.8 pyramid-rpc-0.8 pyramid-tm-2.4 python-dateutil-2.8.1 requests-2.25.1 s3transfer-0.3.4 six-1.15.0 transaction-3.0.1 translationstring-1.4 urllib3-1.26.3 venusian-3.0.0 waitress-1.4.4 webob-1.8.7 zope.deprecation-4.4.0 zope.interface-5.2.0 zope.sqlalchemy-1.3
.venv/bin/pip install -i http://localhost:6543/simple/ 'pypicloud[server]' 4.22s user 0.50s system 85% cpu 5.517 total
pypicloud側でのダウンロードがない分、だいぶ高速になった。
Webインターフェースの様子
中間キャッシュとしてダウンロードしたパッケージが登録されている
-
初回は当然ではある ↩︎
自作したパッケージを登録する
主にこのようなケース用。
- 共通化された業務ロジックをプライベートに公開したい
- ちょっとしたライブラリを作ったけどPyPIへの登録はちょっと
適当なパッケージを用意
$ poetry init 1 ↵
This command will guide you through creating your pyproject.toml config.
Package name [local-pypi-demo]: demo
Version [0.1.0]:
Description []:
Author [Kazuya Takei <myself@attakei.net>, n to skip]:
License []:
Compatible Python versions [^3.9]:
Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Generated file
Do you confirm generation? (yes/no) [yes] yes
def hello():
return "world"
この2個があれば、poetry build
でパッケージを用意できる。[1]
アップロード先を追加登録して、プッシュする
$ poetry config --local repositories.local "http://0.0.0.0:6543/simple/"
$ poetry config --local http-basic.local username password
No suitable keyring backends were found
Using a plaintext file to store and retrieve credentials
$ poetry config list
.
repositories.local.url = "http://0.0.0.0:6543/simple/"
.
$ poetry publish -r local
No suitable keyring backends were found
Using a plaintext file to store and retrieve credentials
Publishing demo (0.1.0) to local
- Uploading demo-0.1.0-py3-none-any.whl 100%
- Uploading demo-0.1.0.tar.gz 100%
poetry config
でpoetry環境に各種設定を追加できる。--local
をつけたのは、このプロジェクトに限定するため。
poetry config repositories.XXX
だと、 XXX
という名前をつけてパッケージリポジトリを新規追加できる。
poetry config http-basic.XXX
で、対応するリポジトリにアクセスする際のBasic認証情報を保持できる。
一通り設定が終わればpoetry publish -r XXX
で用意したXXX
というパッケージリポジトリにパッケージをプッシュする。
確認
他のワークスペースでインストール確認
$ venv/bin/pip install -i http://localhost:6543/simple/ demo
Looking in indexes: http://localhost:6543/simple/
Collecting demo
Downloading http://localhost:6543/api/package/demo/demo-0.1.0-py3-none-any.whl (966 bytes)
Installing collected packages: demo
Successfully installed demo-0.1.0
WARNING: You are using pip version 20.2.3; however, version 21.0.1 is available.
You should consider upgrading via the '/home/attakei/works/demo/local-pypi-workspace/.venv/bin/python -m pip install --upgrade pip' command.
demo/local-pypi-workspace
Python 3.9.1 (default, Feb 6 2021, 06:49:13)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import demo
>>>
>>> demo.hello()
'world'
-
tar.gzとwheelの2種類 ↩︎
pypicloudを認証制にする
「このパッケージは全体公開はしたくないなぁ」というケース用。
最低限必要な設定
pypi.default_read =
- everyone
+ authenticated
pypicloudのconfig.iniで、pypi.default_read
をeveryone
からauthenticated
に変えるだけ。
実際の挙動-ブラウザ
ブラウザからでは、UI自体は表示されるがパッケージが出なくなる。
設定済みの認証情報でログインすると、表示されるようになる。
実際の挙動-pip
$ .venv/bin/pip install -i http://localhost:6543/simple/ demo
Looking in indexes: http://localhost:6543/simple/
User for localhost:6543: admin
Password:
Collecting demo
Downloading http://localhost:6543/api/package/demo/demo-0.1.0-py3-none-any.whl (966 bytes)
Installing collected packages: demo
Successfully installed demo-0.1.0
WARNING: You are using pip version 20.2.3; however, version 21.0.1 is available.
You should consider upgrading via the '/home/attakei/works/demo/local-pypi-workspace/.venv/bin/python -m pip install --upgrade pip' command.
User for localhost:6543:
Password:
という2個の認証プロンプトが出るようになった。設定済みの認証情報を与えることでインストールが出来る。
実際の挙動-poetry
poetryの環境下に依存関係として要認証のpypicloud上のパッケージを引っ張りたい場合。
事前にpypicloud側の設定を少しいじる
-pypi.fallback = cache
+pypi.fallback = redirect
pypi.fallback
は、pypicloud上に管理されていないパッケージについてのリクエストが来た場合の振る舞いを指定するのだが、redirect
にしておくことで「ここでそれは管理してないからそっち行って」と返せるようになる。cache
だと「取ってくるからちょっと待ってて」となる。
pyproject.toml
にパッケージのソース入手先として、新しくリポジトリを追加してやる必要がある。
[[tool.poetry.source]]
name = "local"
url = "http://0.0.0.0:6543/simple/"
この設定を行うと、poetry add
を行う際にまずlocalを見に行き、なければPyPIを見に行くようになる
認証情報も忘れない。
$ poetry config --local http-basic.local username password