Python脚本设置pip索引源

Python脚本设置pip索引源

背景

Python 包索引(Python Package Index,PyPI)是由全球 Python 开发人员社区提供的大量开源 Python 包的存储库。官方索引在 https://pypi.org,网站本身由 Python 软件基金会(Python Software Foundation,PSF)维护。
你也可以在上面发布自己的项目,可参考 A Beginner’s Guide to Publishing Packages on the Python Package Index (PyPi)How to Publish an Open-Source Python Package to PyPI

Python 使用 pip 安装第三方包时,默认使用的官方索引源 pypi 的地址 https://pypi.python.org/pypi 在中国大陆因为墙的原因,下载缓慢。
ubuntuaptarchlinuxPacman 有各自国内镜像源一样,pip 也有国内索引源可用,下面罗列了一部分,进一步的,为了便于设置国内源,并受到 nodejsnrm 的启发,我编写了一个脚本

key index-url trusted-url 提供者
douban http://pypi.douban.com/simple/ pypi.douban.com 豆瓣
aliyun http://mirrors.aliyun.com/pypi/simple/ mirrors.aliyun.com 阿里云
tsinghua https://pypi.tuna.tsinghua.edu.cn/simple/ pypi.tuna.tsinghua.edu.cn 清华大学
ustc https://pypi.mirrors.ustc.edu.cn/simple/ pypi.mirrors.ustc.edu.cn 中国科学技术大学
hustunique http://pypi.hustunique.com/simple/ pypi.hustunique.com 华中理工大学
sdutlinux http://pypi.sdutlinux.org/simple/ pypi.sdutlinux.org 山东理工大学
tencent http://mirrors.cloud.tencent.com/pypi/simple/ mirrors.cloud.tencent.com 腾讯云

以豆瓣源为例,假设要安装 pandas 可执行如下命令

1
pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com/simple pandas

如果写到配置文件,便可不用每次指定 -i 参数

1
2
pip config set global.index-url http://pypi.douban.com/simple/
pip config set global.trusted-host pypi.douban.com

所有的 pip 配置文件路径,可以用如下命令获取

1
python -c "from pip._internal.configuration import get_configuration_files;print(get_configuration_files())"

代码实现

TIPS 代码的最新版本在 GitHub Gist 中维护
https://gist.github.com/ChenyangGao/61d5e6eeb149a38291128fcd35befffc

文件名称是 pip_index.pyPython 实现代码如下:

pip_index.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python3
# coding: utf-8

"""\
Tool for setting the index-url of pip

Reference:
- https://pip.pypa.io/en/latest/
- https://docs.python.org/3/installing/index.html
- https://docs.python.org/3/library/ensurepip.html
"""

assert __name__ == "__main__", "Can only be used as __main__ module"

__author__ = "ChenyangGao <https://chenyanggao.github.io/>"
__version__ = (0, 1)

from argparse import ArgumentParser, RawTextHelpFormatter


parser = ArgumentParser(
description="Python pip 源配置工具",
formatter_class=RawTextHelpFormatter,
)
subparsers = parser.add_subparsers(dest="command", help="Available commands")

parser_list = subparsers.add_parser(
"list", formatter_class=RawTextHelpFormatter,
help="罗列所有可用的源", description="""罗列所有可用的源,格式形如
{key}:
index-url: {index_url!r}
trusted-host: {trusted_host!r}
comment: {comment!r}""")

parser_use = subparsers.add_parser(
"use", formatter_class=RawTextHelpFormatter,
help="使用 key 指定要设置的源", description="使用 key 指定要设置的源")
parser_use.add_argument(
"key", default="pypi", nargs="?", help="key,对应某个源,默认值 pypi")
parser_use.add_argument(
"-k", "--kind", default="user", choices=("global", "user", "site"),
help="""类型,默认值 user
- global Use the system-wide configuration file only
- user Use the user configuration file only
- site Use the current environment configuration file only""",
)
parser_use.add_argument(
"-i", "--isolated", action="store_true",
help="Run pip in an isolated mode, ignoring environment "
"variables and user configuration.")
parser_use.add_argument(
"-c", "--cmd-only", dest="cmd_only", action="store_true",
help="并不设置配置文件,只是打印一个 pip install 命令"
)

args = parser.parse_args()


from pip._internal.configuration import Configuration
from urllib.parse import urlsplit


# TIPS: 20 == logging.INFO
__import__("logging").basicConfig(level=20, format="%(message)s")

INDEXES = {
"pypi": {
"index-url": "https://pypi.python.org/pypi",
"trusted-host": "pypi.python.org",
"comment": "官方源"
},
"douban": {
"index-url": "http://pypi.douban.com/simple/",
"trusted-host": "pypi.douban.com",
"comment": "豆瓣"
},
"aliyun": {
"index-url": "http://mirrors.aliyun.com/pypi/simple/",
"trusted-host": "mirrors.aliyun.com",
"comment": "阿里云"
},
"tsinghua": {
"index-url": "https://pypi.tuna.tsinghua.edu.cn/simple/",
"trusted-host": "pypi.tuna.tsinghua.edu.cn",
"comment": "清华大学"
},
"ustc": {
"index-url": "https://pypi.mirrors.ustc.edu.cn/simple/",
"trusted-host": "pypi.mirrors.ustc.edu.cn",
"comment": "中国科学技术大学"
},
"hustunique": {
"index-url": "http://pypi.hustunique.com/simple/",
"trusted-host": "pypi.hustunique.com",
"comment": "华中理工大学"
},
"sdutlinux": {
"index-url": "http://pypi.sdutlinux.org/simple/",
"trusted-host": "pypi.sdutlinux.org",
"comment": "山东理工大学"
},
"tencent": {
"index-url": "http://mirrors.cloud.tencent.com/pypi/simple/",
"trusted-host": "mirrors.cloud.tencent.com",
"comment": "腾讯云"
},
}


def pipi_list():
"罗列所有可用的源"
for key, index in INDEXES.items():
print("%s: %s" % (key,
"".join("\n %s: %r" % e for e in index.items())))


def pipi_use(key="pypi", kind="user", isolated=False):
"""使用 key 指定要设置的源

:param key: key,对应某个源,默认值 pypi
:param kind: 类型,默认值 user
- global Use the system-wide configuration file only
- user Use the user configuration file only
- site Use the current environment configuration file only
:param isolated: Run pip in an isolated mode, ignoring environment
variables and user configuration.
"""
# assert kind in ("global", "user", "site")
index = INDEXES[key]
index_url = index["index-url"]
trusted_host = index.get("trusted-host") or urlsplit(index_url).netloc
conf = Configuration(isolated, kind)
conf.load()
conf.set_value("global.index-url", index_url)
conf.set_value("global.trusted-host", trusted_host)
conf.save()


command = args.command
if command == "list":
pipi_list()
elif command == "use":
if args.cmd_only:
from sys import executable

index = INDEXES[args.key]
index_url = index["index-url"]
trusted_host = index.get("trusted-host") or urlsplit(index_url).netloc
print(f"'{executable}' -m pip install --index-url "
f"{index_url} --trusted-host {trusted_host} ")
else:
pipi_use(args.key, args.kind, args.isolated)
else:
raise NotImplementedError(f"Command {command!r} is not implemented!")

使用说明

命令帮助信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
$ python pip_index.py -h
usage: pip_index.py [-h] {list,use} ...

Python pip 源配置工具

positional arguments:
{list,use} Available commands
list 罗列所有可用的源
use 使用 key 指定要设置的源

optional arguments:
-h, --help show this help message and exit

不同的系统和用户,命令输出的结果会有不同,我的环境如下:

1
2
3
4
5
6
$ # 我当前用的 Linux 发行版
$ uname -a
Linux kali 5.16.0-kali3-amd64 #1 SMP PREEMPT Debian 5.16.11-1kali1 (2022-03-03) x86_64 GNU/Linux
$ # 当前的用户
$ whoami
kali

1. list 命令

命令帮助信息如下:

1
2
3
4
5
6
7
8
9
10
11
$ python pip_index.py list -h
usage: pip_index.py list [-h]

罗列所有可用的源,格式形如
{key}:
index-url: {index_url!r}
trusted-host: {trusted_host!r}
comment: {comment!r}

optional arguments:
-h, --help show this help message and exit

执行如下命令示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
python pip_index.py list         
pypi:
index-url: 'https://pypi.python.org/pypi'
trusted-host: 'pypi.python.org'
comment: '官方源'
douban:
index-url: 'http://pypi.douban.com/simple/'
trusted-host: 'pypi.douban.com'
comment: '豆瓣'
aliyun:
index-url: 'http://mirrors.aliyun.com/pypi/simple/'
trusted-host: 'mirrors.aliyun.com'
comment: '阿里云'
tsinghua:
index-url: 'https://pypi.tuna.tsinghua.edu.cn/simple/'
trusted-host: 'pypi.tuna.tsinghua.edu.cn'
comment: '清华大学'
ustc:
index-url: 'https://pypi.mirrors.ustc.edu.cn/simple/'
trusted-host: 'pypi.mirrors.ustc.edu.cn'
comment: '中国科学技术大学'
hustunique:
index-url: 'http://pypi.hustunique.com/simple/'
trusted-host: 'pypi.hustunique.com'
comment: '华中理工大学'
sdutlinux:
index-url: 'http://pypi.sdutlinux.org/simple/'
trusted-host: 'pypi.sdutlinux.org'
comment: '山东理工大学'
tencent:
index-url: 'http://mirrors.cloud.tencent.com/pypi/simple/'
trusted-host: 'mirrors.cloud.tencent.com'
comment: '腾讯云'

2. use 命令

命令帮助信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ python pip_index.py use -h 
usage: pip_index.py use [-h] [-k {global,user,site}] [-i] [-c] [key]

使用 key 指定要设置的源

positional arguments:
key key,对应某个源,默认值 pypi

optional arguments:
-h, --help show this help message and exit
-k {global,user,site}, --kind {global,user,site}
类型,默认值 user
- global Use the system-wide configuration file only
- user Use the user configuration file only
- site Use the current environment configuration file only
-i, --isolated Run pip in an isolated mode, ignoring environment variables and user configuration.
-c, --cmd-only 并不设置配置文件,只是打印一个 pip install 命令

执行如下命令示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ python pip_index.py use douban
Writing to /home/kali/.config/pip/pip.conf
$ cat /home/kali/.config/pip/pip.conf
[global]
index-url = http://pypi.douban.com/simple/
trusted-host = pypi.douban.com

$ pip config list
global.index-url='http://pypi.douban.com/simple/'
global.trusted-host='pypi.douban.com'
$ # 如果仅仅只是想要使用源,而不想修改配置文件,
$ # 可以用下面的命令打印一个 pip install 命令,
$ # 复制后在命令行粘贴,然后在后面添加要安装的模块
$ python pip_index.py use douban -c
'/home/kali/anaconda3/bin/python' -m pip install --index-url http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

评论

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×