pip.conf中用于私有PyPI的凭证

70

我有一个私有的PyPI仓库,有没有办法在pip.conf中存储凭据,类似于.pypirc?

我的意思是,当前在.pypirc中可以配置如下:

[distutils]
index-servers = custom

[custom]
repository: https://pypi.example.com
username: johndoe
password: changeme

根据我的研究,您可以在pip.conf中加入以下内容:

[global]
index = https://username:password@pypi.example.com/pypi
index-url = https://username:password@pypi.example.com/simple
cert = /etc/ssl/certs/ca-certificates.crt

但我看到了两个问题:

  1. 每次访问URL时,您都需要指定相同的用户名和密码。
  2. 因为它们是URL的一部分,所以用户名和密码会在日志中显示出来。

有没有办法将用户名和密码存储在URL之外?


我想知道 pip 是否可以使用 SSH 连接,并使用 SSH 密钥进行身份验证。SSL 证书也可以用于用户身份验证,但是为此,您需要更改 HTTP 服务器处理请求的方式。 - scrutari
1
对于第二点,您可以抑制标准输出日志记录 pip install -q package-name,如果您仍然希望在某个地方获得完整的详细日志,则可以添加 --log 选项并指向一个文件。 - MarkAWard
5个回答

68

您可以像这样在~/.netrc中存储Pip使用的凭据:

Translated text:

您可以像这样在~/.netrc中存储Pip使用的凭据:

machine pypi.example.com
    login johndoe
    password changeme

Pip将使用这些凭据来访问https://pypi.example.com,但不会记录它们。您必须单独指定索引服务器(例如在问题中的pip.conf中)。

请注意,~/.netrc文件必须归属于pip执行的用户。它不能被任何其他用户读取。无效的文件会被静默忽略。您可以通过以下方式确保权限正确:

chown $USER ~/.netrc
chmod 0600 ~/.netrc

在Python 3.4之前,此权限检查不适用,但无论如何都是一个好主意。

Pip在进行HTTP请求时使用requests。requests使用标准库netrc模块来读取文件,因此字符集仅限于ASCII子集。


谢谢!那个有效。奇怪的是,如果pip依赖于requests,它本身没有这样的功能。 - stolho
4
太好了!在使用.netrcpip.conf时的一个重要区别是,在.netrc中,具有特殊字符的密码不得进行URL编码,而在pip.conf中则需要进行编码。 - therightstuff
1
作为一个额外的注释,对于那些想知道的人,这个解决方案适用于Linux和Windows。 - ebigeon
嗨@twm,我尝试了你的解决方案,但pip仍然忽略了配置的密码。我在这里提出了一个新问题链接 - phi
1
不幸的是,如果您的Pypi存储库不托管在自己的域上,则这并不理想。例如,Gitlab的Pypi存储库使用域“gitlab.com”,因此您可以在同一域上具有具有不同凭据的不同存储库。 - bfontaine
这会导致与AzureDevops git lfs身份验证发生冲突。 - undefined

17

将用户名/密码存储为环境变量,如何?

export username=username
export password=password

然后在pip.conf文件中像这样引用它们:

[global]
index = https://$username:$password@pypi.example.com/pypi
index-url = https://$username:$password@pypi.example.com/simple
cert = /etc/ssl/certs/ca-certificates.crt

我使用Gitlab CI的秘密变量来存储凭据。检查一下你的CI工具是否有相应的功能。


1
对于第二部分,@MarkAWard的建议似乎可以解决问题。 - Ketan Vatsalya
谢谢您的回复!实际上,我最初就是按照您建议的方式进行操作的。我还使用GitLab CI,并将用户名和密码存储为环境变量。问题是,pip install在输出日志中显示用户名和密码。但是@MarkAWard的建议帮了我很大忙。目前只剩下一个问题,您知道是否有一种方法可以禁止在GitLab CI中输出echo $usernameecho $password吗? - stolho
4
@rahul 你使用的是哪个版本的pip?我无法在pip.conf中使用花括号或不使用花括号的选项解析环境变量。请帮忙看一下。 - Imran
2
这个问题解决了吗?我也无法在pip.conf中解析变量。我正在使用8.0.2版本。 - abhishek phukan
3
我也无法让它工作起来。如果能有这个功能就太好了。 - Austen Novis
显示剩余3条评论

7

鉴于问题4789仍未解决,您可以在 requirements.txt 中使用以下方法:

--extra-index-url=https://${PYPI_USERNAME}:${PYPI_PASSWORD}@my.privatepypi.com
private-package==1.2.3
...

如果你尝试在设置了这些环境变量的情况下运行pip install -r requirements.txt命令,你会发现pip仍会要求输入凭据。这是因为pip不会像预期那样解释表达式${PYPI_USERNAME},而是进行url编码。例如,你的用户名和密码表达式为:https://%24%7BPYPI_USERNAME%7D:%24%7BPYPI_PASSWORD%7D@my.privatepypi.com 解决方法如下,虽然我承认还应该有更好的方法:我们可以将pip作为一个脚本来运行。
python3 -m pip install -r requirements.txt

来自man:

 -m module-name
    Searches sys.path for the named module and runs the corresponding .py file as a script.

3
我有几个不理解的问题 - 1)你的两个命令在是否使用“-r”标志方面有所不同,第一个是遗漏了吗?还是很重要?2)假设调用了正确的Python,“python3 -m pip”应该完全等同于“pip”。我不确定为什么它会产生你描述的效果,你明白发生了什么吗? - Ken Williams

3

我使用 tox,因为 tox.ini 不支持多行安装命令,所以使用 keyring 太麻烦了。PIP_EXTRA_INDEX_URL 是正确的选择。 - I'll Eat My Hat

1

嘿,你可以简单地运行pip install并将私有仓库的URL作为参数传递,就像这样(我正在使用Artifactory,但并不重要):

Artifactory示例:

pip install {lib_name} -U -i https://{user_name}:{token_to_prvate_repo}@artifactory.{company_name}.com/api/pypi/pypi/simple

Github 示例:

pip install git+https://${GITHUB_USER}:${GITHUB_TOKEN}@github.com/user/project.git@{version}

Bitbucket示例:

pip install  git+https://${BITBUCKET_USER}:${BITBUCKET_APP_PASSWORD}@bitbucket.org/user/project.git@{version}'

变量可以从管道/密钥保险库或其他安全解决方案中读取。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接