关于python:是否可以使用pip从私有github存储库安装包?

Is it possible to use pip to install a package from a private github repository?

正如标题所示,我正试图从一个私有的github repo安装一个python包。对于公共存储库,我可以发出以下命令,这些命令可以正常工作:

1
pip install git+git://github.com/django/django.git

但是,如果我在私有存储库中尝试此操作:

1
pip install git+git://github.com/echweb/echweb-utils.git

我得到以下输出:

1
2
3
4
5
6
7
8
9
Downloading/unpacking git+git://github.com/echweb/echweb-utils.git
Cloning Git repository git://github.com/echweb/echweb-utils.git to /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-VRsIoo-build
Complete output from command /usr/local/bin/git clone git://github.com/echweb/echweb-utils.git /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-VRsIoo-build:
fatal: The remote end hung up unexpectedly

Cloning into /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-VRsIoo-build...

----------------------------------------
Command /usr/local/bin/git clone git://github.com/echweb/echweb-utils.git /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-VRsIoo-build failed with error code 128

我想这是因为我试图在不提供任何身份验证的情况下访问私有存储库。因此,我尝试使用git+ssh,希望pip使用我的ssh公钥进行身份验证:

1
pip install git+ssh://github.com/echweb/echweb-utils.git

这将提供以下输出:

1
2
3
4
5
6
7
8
9
10
11
Downloading/unpacking git+ssh://github.com/echweb/echweb-utils.git
Cloning Git repository ssh://github.com/echweb/echweb-utils.git to /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-DQB8s4-build
Complete output from command /usr/local/bin/git clone ssh://github.com/echweb/echweb-utils.git /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-DQB8s4-build:
Cloning into /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-DQB8s4-build...

Permission denied (publickey).

fatal: The remote end hung up unexpectedly

----------------------------------------
Command /usr/local/bin/git clone ssh://github.com/echweb/echweb-utils.git /var/folders/cB/cB85g9P7HM4jcPn7nrvWRU+++TI/-Tmp-/pip-DQB8s4-build failed with error code 128

有人知道我试图达到的目标是否可能实现吗?如果有的话,你能告诉我怎么做吗?


您可以使用git+sshuri方案,但必须设置用户名:

1
pip install git+ssh://git@github.com/echweb/echweb-utils.git

看到git@部分进入uri了吗?

另请阅读部署密钥。

pps:在我的安装中,"git+ssh"uri方案只适用于"可编辑"的要求:

1
pip install -e URI#egg=EggName

记住:在使用pip命令中的远程地址之前,将git remote -v打印的:字符更改为/字符:

1
2
3
$ git remote -v
origin  git@github.com:echweb/echweb-utils.git (fetch)
                      ^ change this to a '/' character

如果您忘记了,您将得到这个错误:

1
2
ssh: Could not resolve hostname github.com:echweb:
         nodename nor servname provided, or not known


作为一种附加技术,如果您在本地克隆了私有存储库,则可以执行以下操作:

1
pip install git+file://c:/repo/directory

编辑:更现代的做法是,你可以这样做(-e意味着你不必在改变被反映出来之前提交它们):

1
2
pip install -e C:
epo\directory


您可以直接使用https URL执行此操作,如下所示:

1
pip install git+https://github.com/username/repo.git

例如,在Django项目的requirements.txt中添加这一行也是可行的。


也适用于BitBucket:

1
pip install git+ssh://git@bitbucket.org/username/projectname.git

在这种情况下,pip将使用ssh密钥。


这里给出了需求文件的语法:

https://pip.pypa.io/en/latest/reference/pip_install.html需求文件格式

例如:

1
-e git+http://github.com/rwillmer/django-behave#egg=django-behave

如果您希望源在安装后仍然存在

或者只是

1
git+http://github.com/rwillmer/django-behave#egg=django-behave

如果你只是想安装它。


我找到了一种自动"pip安装"Gitlab私有存储库的方法,它不需要密码提示。这种方法使用gitlab"deploy keys"和ssh配置文件,这样您就可以使用个人ssh密钥以外的密钥进行部署(在我的例子中,供"bot"使用)。也许某个善良的灵魂可以使用Github进行验证。

创建新的ssh密钥:

ssh-keygen -t rsa -C"GitLab_Robot_Deploy_Key"

文件应显示为~/.ssh/GitLab_Robot_Deploy_Key~/.ssh/GitLab_Robot_Deploy_Key.pub

复制并粘贴~/.ssh/GitLab_Robot_Deploy_Key.pub文件的内容到gitlab的"部署密钥"对话框中。

测试新的部署密钥

下面的命令告诉ssh使用新的deploy密钥来设置连接。成功后,您将收到消息:"欢迎使用gitlab,用户名!"

ssh -T -i ~/.ssh/GitLab_Robot_Deploy_Key [email protected]

创建ssh配置文件

接下来,使用编辑器创建一个~/.ssh/config文件。添加以下内容。"主机"值可以是任何您想要的值(记住它,因为您稍后将使用它)。主机名是指向Gitlab实例的URL。IdentifyFile是在第一步中创建的ssh密钥文件的路径。

1
2
3
Host GitLab
  HostName gitlab.mycorp.com
  IdentityFile ~/.ssh/GitLab_Robot_Deploy_Key

将ssh指向配置文件

@Oxyum给了我们使用pip和ssh的方法:

pip install git+ssh://[email protected]/my_name/my_repo.git

我们只需要稍微修改一下,让ssh使用我们的新部署密钥。我们通过将ssh指向ssh配置文件中的主机条目来实现这一点。只需将命令中的"gitlab.mycorp.com"替换为ssh配置文件中使用的主机名:

pip install git+ssh://git@GitLab/my_name/my_repo.git

现在安装该包时不需要密码提示。

参考A参考文献B


我发现使用令牌比使用ssh密钥容易得多。我找不到太多关于这方面的好文档,因此主要通过试用和错误发现了这个解决方案。此外,从PIP&SETUPTOOLS进行安装有一些细微的区别,但这种方式对两者都适用。

Github不(目前,截至2016年8月)提供一种简单的方式来获得私人回购的Zip/Tarball。因此,您需要指向SETUPTOOLS,告诉SETUPTOOLS您指向的是Git回购:

1
2
3
4
5
6
7
8
9
10
11
12
from setuptools import setup
import os
# get deploy key from https://help.github.com/articles/git-automation-with-oauth-tokens/
github_token = os.environ['GITHUB_TOKEN']

setup(
    # ...
    install_requires='package',
    dependency_links = [
    'git+https://{github_token}@github.com/user/{package}.git/@{version}#egg={package}-0'
        .format(github_token=github_token, package=package, version=master)
        ]

这里有几条注释:

  • 对于private repos,您需要使用github进行身份验证;我找到的最简单方法是创建一个OAuth令牌,将其放到您的环境中,然后将其包含在URL中。
  • 您需要在链接的末尾包含一些版本号(这里是0),即使pypi上没有包。这必须是一个实际数字,而不是一个字。
  • 你需要在git+的前面告诉安装工具它是克隆repo,而不是指向zip/tarball
  • version可以是分支、标记或提交哈希
  • 如果从PIP安装,需要提供--process-dependency-links


当我从Github安装时,我可以使用:

1
pip install git+ssh://git@github.com/<username>/<projectname>.git#egg=<eggname>

但是,由于我必须以sudo的身份运行pip,因此ssh密钥不再与github一起工作,"git clone"在"permission denied(publickey)"上失败。使用git+https允许我以sudo的形式运行命令,并让github询问我的用户/密码。

1
sudo pip install git+https://github.com/<username>/<projectname>.git#egg=<eggname>


您还可以通过git+https://github.com/安装私有回购依赖项。URL,通过为curl提供登录凭证(登录和密码,或部署令牌)和.netrc文件:

1
2
echo"machine github.com login ei-grad password mypasswordshouldbehere"> ~/.netrc
pip install"git+https://github.com/ei-grad/my_private_repo.git#egg=my_private_repo"

如果要在CI服务器或类似服务器中安装需求文件中的依赖项,可以执行以下操作:

1
2
3
4
5
6
7
git config --global credential.helper 'cache'
echo"protocol=https
host=example.com
username=${GIT_USER}
password=${GIT_PASS}
"
| git credential approve
pip install -r requirements.txt

在我的例子中,我使用了GIT_USER=gitlab-ci-tokenGIT_PASS=${CI_JOB_TOKEN}

这个方法有一个明显的优势,您有一个包含所有依赖项的需求文件。


如果不想使用ssh,可以在https URL中添加用户名和密码。下面的代码假定您在工作目录中有一个名为"pass"的文件,其中包含您的密码。

1
2
export PASS=$(cat pass)    
pip install git+https://<username>:$PASS@github.com/echweb/echweb-utils.git


如果您在Github/Gitlab等上有自己的库/包,则必须添加标记以提交具体版本的库(如v2.0),然后才能安装包。

1
pip install git+ssh://link/name/repo.git@v2.0

这对我有用。其他的解决方案对我没有效果。


你可以试试

pip install [email protected]/my_name/my_repo.git

没有ssh:…这是我的工作。


对于这个答案,Oxyum的解决方案是可以的,我只是想指出,如果安装时使用sudo,您需要小心,因为密钥也必须存储在根目录中(例如/root/.ssh)。

然后你可以打字

sudo pip install git+ssh://[email protected]/echweb/echweb-utils.git