目录


文章目录


创建本地 PyPI 仓库

安装 pypiserver

$ mkdir pypiserver
$ cd pypiserver

$ mkdir ./packages
$ mkdir ./auth

$ pip install passlib
$ cd auth
# 生成 htpass 文件
# 会 prompt 密码输入,重复两遍一样的
$ htpasswd -sc .htaccess username

$ cd pypiserver
$ cat ./docker-compose.yml
...
version: "3.3"
services:
pypiserver:
image: pypiserver/pypiserver:latest
volumes:
- type: bind
source: ./packages
target: /data/packages
- type: bind
source: ./auth
target: /data/auth
command: -P /data/auth/.htaccess -a update,download,list /data/packages
ports:
- "8081:8080"

$ docker-compose -f docker-compose.yml up -d

上传 Python 安装包

  1. 可以使用 twine CLI 工具上传,也可以手动地把安装包 copy 到 pypiserver/packages 目录下。
  2. 可以上传 XXX.tar.gz 源码包,也可以上传 XXX.whl 分发包,都可以用于 pip 安装。

安装 twine CLI 工具:

$ pip install twine

$ ~/.pypirc
...
[distutils]
index-servers =
# 不使用 pypi 公共仓库。
# pypi
internal

#[pypi]
#username:<your_pypi_username>
#password:<your_pypi_passwd>

[internal]
repository: http://your_pipserver:8081
username: <some_username>
password: <some_passwd>

twine upload -r internal {packet_path}

(可选的)从现有的环境中获取 pip 安装包清单:

pip freeze bypy > requirement.txt
pip download -d ./python_packages -r requirement.txt
cp ./python_packages/* pypiserver/packages

(可选的)从源码编译得到可用于分发的 tar 包和 whl 包:

pip install wheel
pip install -U setuptools
python setup.py sdist bdist_wheel
twine upload -r internal ./dist/yourpackage-0.0.1.tar.gz

使用私有 PyPI 仓库

隐式使用:

$ ~/.pip/pip.conf

[global]
index-url = http://youruser:yourpass@yourserver:8081/simple
[install]
trusted-host=yourserver

显式使用:

$ pip install --trusted-host yourserver \
--extra-index-url http://youruser:yourpass@yourserver:8081/simple \
yourpackage

Python 程序的离线部署

PyPI 上 Python Packages 有好几种格式,并且 PyPI 也没有强制要求哪一种格式是必须要提供的,也不会维护 Packages 所有的版本,这都会导致 pip download 失败(No matching distribution found),简直是一场灾难。开发者们也一直在吐槽 Python Packages 分发难的问题。

  • 源码文件:XXX.tar.gz 或 XXX.zip,源码文件,用 pip 安装,与机器架构无关,但某些 Packages 可能会涉及到 C/C++ 的编译,要求安装机器具有编译环境。
  • wheel 文件(pip install 优先选择):XXX.whl,二进制文件,用 pip 安装,无需编译,但与硬件平台架构相关。
  • egg 文件:XXX.egg,二进制文件,用 easy_install 安装,无需编译,但与硬件平台架构相关。

pip download 获取必须的 Python Packages

pip download with the --platform, --python-version, --implementation, and --abi options provides the ability to fetch dependencies for an interpreter and system other than the ones that pip is running on. --only-binary=:all: or --no-deps is required when using any of these options. It is important to note that these options all default to the current system/interpreter, and not to the most restrictive constraints (e.g. platform any, abi none, etc). To avoid fetching dependencies that happen to match the constraint of the current interpreter (but not your target one), it is recommended to specify all of these options if you are specifying one of them. Generic dependencies (e.g. universal wheels, or dependencies with no platform, abi, or implementation constraints) will still match an over- constrained download requirement.

pip download 默认会把指定的 Packages 及其依赖的 Packages 都一并下载,具体参数请浏览《PEP 425 – Compatibility Tags for Built Distributions》。

有以下关键选项:

  • ​--only-binary=:all:​​:只下载二进制 Packages(wheel 或 egg)。
  • ​--no-binary=:all:​​:只下载源码 Packages。
  • ​--no-deps​​:不下载依赖。
  • ​--platform​​:指定操作系统和硬件平台。
  • ​--python-version​​:指定 Python 版本。
  • ​--implementation​​:指定编译器,通常是 cpython。
  • ​--abi​

EXAMPLE:

pip download \
--only-binary=:all: \
--platform linux_x86_64 \
--python-version 27 \
--implementation cp \
--abi cp27mu
tensorflow

在已经部署好的环境中制作离线部署包

  1. 首先确定离线包制作环境。因为如果存在二进制包的话,那么就会跟硬件平台绑定。
  • x86
  • Linux
  • python2.7
  • pip2
  1. 获取环境所有使用 pip 安装的包。
pip freeze > all_reqs.txt

  1. 优先下载源码包,可以跨平台,但可能依赖编译环境。
pip download --no-binary=:all: -r all_reqs.txt

  1. 过程中可能会出现 No matching distribution found,此时将失败的包摘录出来。
  2. 对没有源码的包,退而下载二进制包(平台绑定)
pip download --only-binary=:all: -r bin_reqs.txt

  1. 如果源码包也没有,二进制包也没有,那么就是 PyPI 已经不维护指定的版本了,此时只能手动下载(可能是不同的版本)。
  2. 还有最坏的情况就是,PyPI 根本就没有这个包,那么就需要自己下载源码,自己编译并上传到私有仓库了。