前言:
? ? ? ? windows下和linux下都可以搭建本地pip镜像源。操作流程上一样,但是细节上存在一些差异。建议在linux上搭建本地镜像,流程简单很多。在windows系统上,会在多个地方存在问题(比如不识别.symlink文件,一些python包的命名不识别),报错并需要修改。个人因为在两个系统上都搭建过了,所以记录一下。
? ? ? ? 这里仅仅对下载得到pypi的package之后的mirror发布进行细节介绍,如何下载pypi的镜像文件,我在文末进行了介绍。
我把所有需要用到的文件都已经打包,大家可以自行下载。
链接:https://pan.baidu.com/s/1xXAonud7NnkpLWM7ExI-bg?
提取码:8yvn
创建一个新的文件夹:build_pypi_mirror,后续所有的操作都在这个文件夹下进行。
????????为每一个工程创建一个独立的虚拟环境是一个好习惯,可以保证项目环境的纯洁性,避免出现package版本冲突。
? ? ? ? 创建虚拟环境
python -m venv ./virtual_env
????????激活虚拟环境:
./virtual_env/Scripts/activate
????????安装pip2pi包
pip install pip2pi-*.whl
? ? ? ? 我已经把一些示例包都准备好了,大家直接使用即可。把下载文件中的pypi-packages文件夹放置到build_pypi_mirror目录下。
????????以管理员身份打开cmd命令行终端,进入build_pypi_mirror文件夹,执行以下命令,
dir2pi ./pypi-packages
?该命令会在pypi-packages文件夹下生成一个simple文件夹。?
???????说明:
- dir2pi函数是pip2pi包中自带的,不需要额外安装。
- 在windows下运行,建议“以管理员身份”命令行,否则会报错。原因:dir2pi 过程中会产生“.symlink”文件,而windows不识别“.symlink”文件,当产生“.symlink”文件时,命令行终端会报警,除非以管理员身份运行。(其实,不用管理员身份运行也可以,因为产生的“.symlink”文件用不着,仅仅是cmd界面的观感不太好。)
? ? ? ? dir2pi命令的返回结果是为linux系统准备的,比如上面的".symlink"文件,在linux系统中可以识别,但是在windows系统下不能识别也不能使用。这导致,在windows系统下生成的simple文件夹中的index文件需要进行修改。
????????修改的目的是:在通过index文件寻找pypi数据包时,不通过".symlink"文件作为中转站,而是直接寻找pypi数据包原件。
? ? ? ? 修改的内容是:在每一个index.html文件内的pypi数据包路径前面,加上“../../”,如下:
????????修改前:
????????修改后:
? ? ? ? 通过代码批量化修改:?
我已经把批量修改的代码放在了第一步的打包文件中,其内容如下:
reformat_index.py
import os
import glob
class Class_Util_Text():
def __init__(self):
pass
def read_text(self,text_path):
"""
读取本地text文件到列表,并返回该列表
"""
assert os.path.exists(text_path)
with open(text_path,"r") as f:
lines=f.readlines() #读行
return lines
def write_text(self,text_path,text_content):
"""
把文字写入文本文件中,会清空文本文件的原有内容
"""
with open(text_path,"w") as f:
f.writelines(text_content)
f.writelines("\n")
def append_text(self,text_path,text_content):
"""
把文字添加到文本文件的末尾,保留原文本文件内容
"""
with open(text_path,"a") as f:
f.writelines(text_content)
f.writelines("\n")
def replace_text(self,text_path,replace_old,replace_new):
"""
替换文本文件中的部分文字,先读文件,替换文字后,再重新写入文件
"""
#read
with open(text_path,"r") as f:
lines=f.readlines()
data=[]
for i in lines:
#根据条件修改
if(replace_old in i):
i=i.replace(replace_old,replace_new) #修改 replace_old 为 replace_new
data.append(i) #记录每一行
#write
with open(text_path,"w") as f:
for i in data:
f.writelines(i)
if __name__ =="__main__":
txt_obj = Class_Util_Text()
dir_path = "D:\pypi-packages\simple" ## 只需要修改这里即可
html_files = glob.glob(dir_path+"/*/index.html")
for html_path in html_files:
txt_obj.replace_text(html_path,replace_old="<a href='",replace_new="<a href='../../" )
# txt_obj.replace_text(html_path,replace_old="<a href='../../",replace_new="<a href='" )
lines = txt_obj.read_text(html_path)
print(html_path)
print(lines)
????????为了让浏览器或pip程序可以访问这个镜像库,需要把第二步中产生的simple文件夹发布到互联网/局域网中。这里主要介绍两种方式:
python -m http.server 8080 --bind 168.163.1.1 --directory D:/your_path_to_simple_dir
? ? ? ? 参数说明:
- ? ? ? ? 8080是自己设置的网络端口,可以自行修改
- ? ? ? ? --bind:绑定你的机器的ip地址,后面的地址是你的电脑IP。这个命令可以省略。
- ? ? ? ? --directory: 指定要暴露哪个文件夹
? ? ? ? 在浏览器中输入: Your_IP:Your_Port (比如:168.163.10.0:8080) 即可访问你自己创建的镜像源了,点击之后可以下载相关python包。
? ? ? ? 要pip命令访问自己创建的pypi镜像库,需要修改pip命令的默认搜索路径。
????????打开命令行终端,对pip命令进行以下设置:
# 设置默认搜索路径
pip config set global.index-url http://168.163.1.1:8080
# 设置对IP的信任--不设置会报错
pip config set install.trusted-host 168.163.1.1
????????该方式很简单,但是需要一个额外的cmd窗口来维持对镜像源的发布,不能关闭。虽然实现简单,但是维护有些麻烦,因此推荐方法2.
下载安装nginx,修改nginx.conf(总共修改三个位置,如下):
server{
? ? listen?? ??? ?8080; ?# 1.修改位置1:设置端口
? ? server_name ?? ?168.163.1.1; ?# 2.修改位置2:输入你的电脑IP。
? ? access_log ?? ?logs/pip.log;
? ? location / {
? ? ? ? ? ? root D:/build_pypi_mirror/pypi_packages/simple; # 3.修改位置3--设置html文件的搜索路径
? ? ? ? ? ? autoindex on;
? ? ? ? ? ? autoindex_exact_size off;
? ? ? ? ? ? autoindex_localtime on;
? ? }
}
修改完成后,双击执行nginx.exe启动nginx。
? ? ? ? 完成以上操作,就可以用浏览器打开168.163.1.1:8080访问simple文件夹,并可以通过鼠标点击,下载python包了。
? ? ? ? 这里对pip的设置与方式1中的设置方式完全相同。只是重复一遍:
????????打开命令行终端,对pip命令进行以下设置:
# 设置默认搜索路径
pip config set global.index-url http://168.163.1.1:8080?
# 设置对IP的信任--不设置会报错
pip config set install.trusted-host 168.163.1.1
????????nginx方式需要再安装一个nginx软件。这个过程可能稍显麻烦。但是他的好处是,双击运行nginx后就不用再管了,其在后台运行,不存在一个命令行窗口提示自己不能关掉。?
? ? ? ? 通过第三步的设置,自己的镜像源已经发布在了互联网/局域网中,任何与该电脑相连接的互联网/局域网设备,都可以上面的ip地址和端口号访问这个镜像了。
? ? ? ? 每个机器只需要修改pip的配置即可。这里把配置信息再赘述一遍:
????????打开命令行终端,对pip命令进行以下设置:
# 设置默认搜索路径
pip config set global.index-url http://168.163.1.1:8080?
# 设置对IP的信任--不设置会报错
pip config set install.trusted-host 168.163.1.1
? ? ? ? 以上过程仅仅完成了原理验证,现在只需要下载整个pypi镜像源,然后重新执行以上步骤就可以了。
? ? ?prepare_pypi_requirements.py
import requests
import re
report = requests.request('get','https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/')
# print(report.text)
text_str = str(report.text).split('\n')
with open('requirement.txt','w+') as f:
for i in text_str:
temp = re.findall('<a href="(.*?)/">',i)
# print(i,temp)
if temp != []:
f.write(str(temp[0])+'\n')
? ? ? ? download_pypi.py
#!/bin/bash
import os
file="C:\\software\\package\\requirement.txt"
with open(file,'r+') as f:
text = f.readlines()
for i in text:
os.mkdir('C:\\software\\package\\'+i[:-1])
os.system('pip download '+i[:-1]+' -i https://pypi.tuna.tsinghua.edu.cn/simple -d '+'C:\\software\\package\\'+i[:-1])
? ? ? ? ?当对整个清华pypi镜像源进行 dir2pi 操作时,会出现多次报错。主要原因是,有的python包的命名格式不符合windows的要求。此时,需要把这些命名不符合windows规范的包删除掉,才能正常完成dir2pi操作。这些包有很多,虽然有一些规律,但是仍旧是一个很繁琐的工作。因此,极力不推荐在windows系统上布置pypi镜像。