python环境部署(一) —— pip依赖迁移

2023-05-16

前言

工程实际应用时,我们需要考虑如何在各种情况下顺利地将工程的运行环境部署起来。
就Python工程来说,最主要的就是将程序运行所需的各种依赖模块安装起来。目前Python最常用包管理工具是conda和pip,其中conda还具有虚拟环境管理功能,而且conda环境下可能还有很多包是通过pip安装的。
避免混乱,我将分两篇文章分别介绍纯粹使用pip以及使用conda虚拟环境时的部署方法。这篇文章,从简单的pip开始。

教条的方法

pip提供了导出依赖的方法,在测试机器上执行以下命令导出依赖文件requirements.txt:

pip freeze >  requirements.txt

文件格式如下:

<package>==<version>

随后,在待部署机器上,使用以下命令安装就可以恢复依赖环境:

pip install -r requirements.txt

网上能搜到的大部分教程,大都是这么写的。所以我称之为教条的方法。如果真的有这么畅通无阻,那就真的太好了,毕竟谁都不愿意折腾。但是事实上,在实际部署中,存在这样那样的各种问题,想不折腾的话,请大家看下去。

找不到匹配的包

一个最常遇到的问题是:找不到匹配的包(No matching distribution found)。在这个提示信息之前,还会有Could not find a version that satisfies the requirement … 。很多情况下确实只是找不到适配的版本,而有的时候是真的找不到包。

pip的镜像源处于不断更新的状态,而且更新异常活跃,甚至有人发布了包又将其撤回、或者删去之前的版本,都可能造成找不到对应版本的包的情况。

例如:
在这里插入图片描述
而如果一些包来源于外部链接,在pip仓库中并没有的话,得到的提示仍然是No matching distribution found,这时pip是真找不到这个包了。例如:

在这里插入图片描述

属于第一种情况的,有以下几个可能的解决方法:

(1)调整requirements.txt,把“==”变成“>=”。这样即使源更新了,还是能找到绝大多数包的。但是,这方法其实只是取巧。调整后的整体依赖环境是否能够正常、稳定地工作,并没有得到验证。

(2)更新测试机器上的包,在测试机器上验证是否能够正常、稳定地工作后,再导出requirements.txt。

批量更新pip的包可以使用:

pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U
(如果不支持的话可能是pip版本太旧,先升级下pip)

这个方法也存在一些问题。
首先,升级新版本是冒险的,由其对于开发周期较长的程序来说,开发过程中,可能所依赖的包的版本已经有了较大的更新,程序中用到的一些方法可能在新版本中都被取消了,所以如果要升级,升级后一定要确保程序可以正常且稳定地运行。这个可能就比较耗时了。
其次,如果测试机器上升级完并导出后,并不具备快速进行部署的条件,升级也是枉然的,间隔几天后进行部署,依然面临一些包不匹配的问题。这个问题的根源就是pip源的不断更新,那么,要彻底解决这个问题,就得建立自己的源或者在安装时指定本地文件了。这一点,后面在离线部署时一并介绍。

属于第二种情况的,可以用以下方法解决:

(1)在requirements.txt中,相应的包之前添加–find-links,例如:

--find-links https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.1.0/en_core_web_sm-2.1.0.tar.gz
en_core_web_sm==2.1.0

离线部署

源的不断更新可以令用户更快用上来自上游的更新,但是对部署来说却未必是一件好事。
为了实现离线部署,可以将安装所需的文件从源上下载下来,然后从本地安装。
首先,还是需要导出requirements.txt文件,然后在测试机器上使用以下命令下载所有的安装包:

pip download -d ~/my_env_pkgs/ -r requirements.txt

在下载文件的过程中,我们依然会遇到找不到适配的包的问题。这时要做的是,仔细对照这些包,如果并不是十分重要的包,可以在本地更新修改requirements.txt文件,下载更新的版本;如果非常关键的包(比如做的深度学习的项目,用到的深度学习框架),应该去网上搜索,找到旧版本的包,放到~/my_env_pkgs/ 目录下,requirements.txt中可以暂时删除这一项;通过外部链接安装的包,就将包先下载到~/my_env_pkgs/ 目录下,同样地,requirements.txt中可以暂时删除这一项。

如此一来,requirements.txt文件(记得补上刚刚暂时删去的项)中的依赖与所提供的文件及版本就是完全一致的了,在部署时就不会遇到上述的问题。

复制到待部署机器上后,可以使用以下命令安装:

pip install -r requirements.txt --no-index --find-links=file:///home/user_name/my_env_pkgs

其中 --no-index代表不去搜索源,file://是必须的,此后再接上绝对路径(一定要使用绝对路径,所以有三个/)。

当然,你也可以构建一个本地的pypi源:

# 安装pip2pi模块
pip install pip2pi
# 建立索引(my_env_pkgs目录下会多出一个simple文件夹)
dir2pi ~/my_env_pkgs/
# 进入目标文件夹(就是对外发布的文件夹,因为开启HTTP Server是将当前文件夹发布)
cd ~/my_env_pkgs/simple/
# 开启HTTP Server - Python3
python -m http.server
# 开启HTTP Server - Python2
python -m SimpleHTTPServer

然后使用以下命令安装:

pip install -i http://127.0.0.1:8000/ -r requirements.txt

二者无甚区别。

跨平台部署

当需要跨平台部署环境时,最妥当的方法应该是在不同的平台上做好测试,然后再按以上方法分别部署。我并不建议大家用我下面说的方法直接部署,而是希望大家将其当做减少在新测试机器上部署测试环境的工作量的方法。
一般来说,在发布一个模块时,开发者会同时发布支持多个平台的独立的binary distribution(扩展名为whl)和一个source distribution(简称sdist,扩展名为tar.gz),但这并不是强制要求,所以存在例外。
在前面的方法中,我们稍作修改:

pip download --no-binary=:all: -d ~/my_env_pkgs/ -r requirements.txt

这是要求pip只下载sdist,而不下载binary distribution。
在新测试机器上,仍然使用以下命令安装,不需更改:

pip install -r requirements.txt --no-index --find-links=file:///home/user_name/my_env_pkgs

此时,在新测试机器上,pip的setuptools将会根据平台环境和源码去构建合适的whl包,继而安装。
对于那些不提供sdist的包,则需要在新测试机器上独立安装了。

其他的小问题

(1)依赖安装顺序问题
pip导出的requirements.txt文件中各项是按字母表顺序排序的,因此其中存在一些属于前面需要安装的包的依赖包的包被放到了后面。正常情况下,安装这些包时,也会进行依赖的检查,并不会出什么问题,但是,由于pip的处理逻辑是whl下载下来后不会先安装,但是sdist下载下来后会先编译成whl,这时,就可能用到这些依赖,这应该是个小bug吧。如果遇到这个问题,就先安装下这个依赖吧。
在这里插入图片描述
(2)python版本与pip版本
最起码应保证测试机器与待部署机器上的python版本与pip版本的一致,避免语法上的错误或者其他不可预见的错误。

关于其他工具的说明

(1)pip-bundle
pip-bundle可以在导出的requirements.txt的基础上一键创建一个bundle文件,实际上就是把所有的需要的安装的包融合到一起。具体如下:

# 安装(测试机器和待部署机器上都需要)
pip install pip-bundle
# 测试机器上下载包
pip-bundle create my_env.pip-bundle
# 待部署机器上安装这些包
pip-bundle install my_env.pip-bundle

需要注意的是,pip-bundle这个工具也依赖于requirements.txt,所以还是存在“找不到匹配的包”的问题,所以,该更新还是得更新,该修改requirements.txt文件,还是得修改,参照上面的方法。对于那类从外部源安装的包,则需要用–find-links在requirements.txt中做好标注了。

遗憾的是,这个工具还在打包时编译成whl,也就使其失去了跨平台使用的特性。

(2)pipreqs
pipreqs可以通过对项目目录下文件的扫描,确定文件运行需要哪些依赖,在pip环境不纯净时可以用于替代pip freeze。
具体用法如下:

# 安装
pip install pipreqs
# 进入项目目录
cd ~/my_project/
# 导出requirements.txt
pipreqs ./ --encoding=utf8

(3)pyinstaller
如有打包成exe文件的需求,可以看看pyinstaller这个模块。

(4)查找资料时发现一个将文件打包成zip的方法,具体是否还奏效我没有去测试,感兴趣的自己看看吧,链接如下:
https://www.zhihu.com/question/21639330
https://blogs.gnome.org/jamesh/2012/05/21/python-zip-files/

参考文献

https://pip.readthedocs.io/en/1.1/requirements.html
https://pip.pypa.io/en/stable/reference/pip_wheel/
https://blog.csdn.net/iodjSVf8U1J7KYc/article/details/90585771
https://stackoverflow.com/questions/18883430/trouble-installing-private-github-repository-using-pip
https://pypi.org/project/pip-bundle/
https://www.zhihu.com/question/21639330
https://blogs.gnome.org/jamesh/2012/05/21/python-zip-files/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python环境部署(一) —— pip依赖迁移 的相关文章

  • 网络安全组(NSG)简介

    韩源 xff0c 资深工程师 xff0c 存储和灾备专家 Azure 网络安全解析 作为公有云最重要环节之一 xff0c 网络安全一直是 Azure 的重中之重 在 Azure 中 xff0c 多种安全技术共同构成了立体的网络保护 xff1
  • gnome manjaro设置无法打开

    本文转载自 xff1a https joshtronic com 2018 04 02 unable to open gnome settings on arch linux after gnome upgrade 我经常会写关于主题的博客
  • 手动将经典 VM 从 VHD 迁移到新的 ARM 托管磁盘 VM

    本部分有助于将现有 Azure VM 从经典部署模型迁移到资源管理器部署模型中的托管磁盘 计划迁移到托管磁盘 本部分可帮助你针对 VM 和磁盘类型做出最佳决策 位置 选取 Azure 托管磁盘可用位置 如果要迁移到高级托管磁盘 xff0c
  • 适用于 Azure 虚拟网络的常见 PowerShell 命令

    如果想要创建虚拟机 xff0c 需要创建虚拟网络或了解可在其中添加 VM 的现有虚拟网络 通常情况下 xff0c 创建 VM 时 xff0c 还需考虑创建本文所述资源 有关安装最新版 Azure PowerShell 选择订阅和登录到帐户的
  • 创建包含多个子网的虚拟网络

    本教程介绍如何创建包含独立公共子网和专用子网的基本 Azure 虚拟网络 虚拟网络中的资源可以彼此通信 xff0c 并可以与连接到虚拟网络的其他网络中的资源通信 可在虚拟网络中相同或不同的子网中创建 Azure 资源 xff0c 如虚拟机
  • matplotlib笔记

    文章目录 matplotlib笔记cmap选择cmap创建cmap 子图断点轴 Broken axis 子图大小 坐标轴scale matplotlib笔记 有一个在线使用matplotlib的网址 cmap 选择cmap choose c
  • Fortran pgplot安装

    pgplot 首先确保已经安装了gfortran 以下为linux下安装流程 从这里下载安装包解压tar zxvf pgplot5 2 tar gz到某个目录比如 src pgplot创建一个文件夹xxx pgplot用于安装 xff0c
  • CUDA和Compute Capability

    CUDA Enabled GPUs Cuda支持的GPU 在这个参考包含了GPU的Compute Capacity列表 比如我的笔记本搭载了一块Geforce830m xff0c 查询列表就可以发现如下图 那么这块830M GPU的Comp
  • Javascript笔记

    数据类型 基本类型 primitive value 简单的数据段 xff0c 包括 Undefined Null Boolean Number String初始化只使用2原始字面量形式 xff0c 如果使用new则会创建Object无法加入
  • 前端面试题笔记

    前端面试八股 发现了一个地方包含了很多前端面试八股 1 用户喜好 为了不断优化推荐效果 xff0c 今日头条每天要存储和处理海量数据 假设有这样一种场景 xff1a 我们对用户按照它们的注册时间先后来标号 xff0c 对于一类文章 xff0
  • Matlab:数据写入Excel

    使用xlswrite 可以help xlswrite查看用法 xlswrite filename A xlswrite filename A sheet xlswrite filename A xlRange xlswrite filena
  • python处理FITS 1:astropy介绍与安装

    1 1介绍 astropy是一个开源的python库 xff0c 专门用于处理天文方面的数据 astropy包是Astropy 项目的内核 xff0c 这个项目致力于发展一个鲁棒性较好的伴随子包 xff08 能兼容优秀的astropy这个库
  • 使用sublime编译运行C程序

    1 打开sublime xff0c 找到顶部工具 xff08 Tool xff09 菜单 gt 编译系统 xff08 Build System xff09 gt 新编译系统 xff08 New Build System xff09 xff1
  • python处理FITS文件 2:astropy.io.fits介绍及打开FITS文件

    astropy这个库有很多功能 xff0c 因为本文主要涉及FITS文件 xff0c 因此仅仅使用astropy io fits 1介绍 astropy io fits包提供FITS文件操作的函数接口 xff0c 使得用户可以忽略FITS文
  • python处理FITS 3:处理头文件和数据单元

    1头文件处理 在获得hdul后 xff0c 可以使用两个属性 header data分别获得头文件和数据单元 gt gt gt hdul 61 fits span class hljs built in open span fits ima
  • Django使用pip安装

    1 pip安装 pip是python的包管理器 xff0c 使用这个工具可以很轻松安装各种python库 直接运行 pip install django 然后就可以安装了 1 1安装问题 输入 pip install django 报错 x
  • 内网穿透方式

    ssh 内网中的机器A 需要访问内网中的c 64 C 公网中的机器B xff0c 用户名b 内网中的机器A ssh CNR 7280 C 22 b 64 B 公网中的机器B ssh fCNL 7279 localhost 7280 loca
  • vue笔记

    rollup 专注于JavaScript打包不包含无关代码 对比webpack tree shaking 最开始由rollup实现 xff0c 之后被webpack借鉴配置output format xff0c 选择输出资源的模块形式 xf
  • geant4学习

    文章目录 配置vscode configuration materialgeant4的类及成员函数physicsList选择构建Physics List 粒子粒子类型能量损失重子和离子 杂项getEnergyoptical photon的速
  • C++枚举与字符串转换工具类

    C 43 43 枚举与字符串转换工具类 最近需要一个能够在字符串和枚举值之间互相转换的功能 xff0c 因为C 43 43 没有对枚举值进行遍历 反射之类的操作 xff0c 不像Java那样可以轻松搞定 网上找到一些代码感觉用起来有点不爽

随机推荐