通过 GitLab API 下载已手动上传的文件
Download files through GitLab API that has been manually uploaded
我们有一个自托管的 GitLab 服务器,并且正在致力于自动化我们的构建和发布。我们有许多在使用 GitLab CI 之前构建的旧版本。其中一些应该包含在某个软件的发布包中。这些版本并不位于任何易于访问的服务器上,因此如果可以从我们的 GitLab 服务器访问它们将非常容易。
可以从 API 访问标签并从构建作业中获取工件。似乎无法手动添加构建工件,因此无法将其用于旧版本。
可以将文件上传到标签的发行说明。这些通过网页下载非常简单,但我找不到任何通过API下载这些的方法。有这个 API 端点:
https://docs.gitlab.com/ee/api/projects.html#upload-a-file
但是没有"download-a-file".
有没有一种简单的方法可以将文件上传到我们自托管的 GitLab,然后通过 API 下载它们?
我们所有的存储库都将可见性设置为私有。如果您尝试在未登录的情况下访问像这样的 link:
http://www.example.com/group/my-project/uploads/443568a8641b1b48fc983daea27d36c0/myfile.zip
然后您将被重定向到登录页面。
无法从 GitLab API 下载文件。这是 GitLab 跟踪此功能的问题:
https://gitlab.com/gitlab-org/gitlab/issues/25838
------
作为目前的解决方法,我使用 python 脚本来简单地登录页面并获取文件。这需要用户的用户名和密码。我设置了一个新用户,它只能在需要的地方访问特定的项目,所以在这个项目的构建脚本中使用它应该足够安全。
import argparse
import sys
import mechanize
def login_and_download(url, user, password):
br = mechanize.Browser()
br.set_handle_robots(False)
br.open(url)
br.select_form(id = 'new_user')
br['user[login]'] = user
br['user[password]'] = password
response = br.submit()
filename = url.split('/')[-1] #Last part of url
with open(filename, 'wb') as f:
f.write(response.get_data())
def main():
parser = argparse.ArgumentParser(description = 'Downloads files from a private git repo')
parser.add_argument('url', help = 'The URL to download')
parser.add_argument('user', help = 'The username to use')
parser.add_argument('password', help = 'The password to use')
args = parser.parse_args()
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
login_and_download(args.url, args.user, args.password)
if __name__ == '__main__':
main()
这是 python 脚本的另一个示例,仍然来自 issue 25838。
它翻译 curl
调用:
curl --request GET 'http://127.0.0.1:3000/root/my-project/uploads/d3d527ac296ae1b636434f44c7f57272/IMG_3935.jpg' \
--header 'Authorization: Bearer YOUR_API_TOKEN'
import requests
from bs4 import BeautifulSoup
with requests.Session() as http_session:
# my login page url
login_url = [LOGIN_URL]
login_page = http_session.get(login_url)
login_inputs = BeautifulSoup(login_page.content, features='html.parser').find_all('input')
# get the authenticity token from the login page
for login_input in login_inputs:
if 'token' in login_input['name']:
auth_token = login_input['value']
break
# send some user-agent header just in case
headers = {"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
# see your login page source for the required data ...
data = {
"username": [MYUSERNAME],
"password": [MYPASSWORD],
"authenticity_token": auth_token,
"remember_me": "1",
"commit": "Sign in"
}
# ... as well as the login endpoint
login_endpoint = [LOGIN_ENDPOINT_URL]
# authenticate
http_session.post(login_endpoint, data=data, headers=headers)
# myfile_url is the url for my wanted file
myfiledata = http_session.get(myfile_url).content
我们有一个自托管的 GitLab 服务器,并且正在致力于自动化我们的构建和发布。我们有许多在使用 GitLab CI 之前构建的旧版本。其中一些应该包含在某个软件的发布包中。这些版本并不位于任何易于访问的服务器上,因此如果可以从我们的 GitLab 服务器访问它们将非常容易。
可以从 API 访问标签并从构建作业中获取工件。似乎无法手动添加构建工件,因此无法将其用于旧版本。
可以将文件上传到标签的发行说明。这些通过网页下载非常简单,但我找不到任何通过API下载这些的方法。有这个 API 端点:
https://docs.gitlab.com/ee/api/projects.html#upload-a-file
但是没有"download-a-file".
有没有一种简单的方法可以将文件上传到我们自托管的 GitLab,然后通过 API 下载它们?
我们所有的存储库都将可见性设置为私有。如果您尝试在未登录的情况下访问像这样的 link:
http://www.example.com/group/my-project/uploads/443568a8641b1b48fc983daea27d36c0/myfile.zip
然后您将被重定向到登录页面。
无法从 GitLab API 下载文件。这是 GitLab 跟踪此功能的问题:
https://gitlab.com/gitlab-org/gitlab/issues/25838
------
作为目前的解决方法,我使用 python 脚本来简单地登录页面并获取文件。这需要用户的用户名和密码。我设置了一个新用户,它只能在需要的地方访问特定的项目,所以在这个项目的构建脚本中使用它应该足够安全。
import argparse
import sys
import mechanize
def login_and_download(url, user, password):
br = mechanize.Browser()
br.set_handle_robots(False)
br.open(url)
br.select_form(id = 'new_user')
br['user[login]'] = user
br['user[password]'] = password
response = br.submit()
filename = url.split('/')[-1] #Last part of url
with open(filename, 'wb') as f:
f.write(response.get_data())
def main():
parser = argparse.ArgumentParser(description = 'Downloads files from a private git repo')
parser.add_argument('url', help = 'The URL to download')
parser.add_argument('user', help = 'The username to use')
parser.add_argument('password', help = 'The password to use')
args = parser.parse_args()
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
login_and_download(args.url, args.user, args.password)
if __name__ == '__main__':
main()
这是 python 脚本的另一个示例,仍然来自 issue 25838。
它翻译 curl
调用:
curl --request GET 'http://127.0.0.1:3000/root/my-project/uploads/d3d527ac296ae1b636434f44c7f57272/IMG_3935.jpg' \
--header 'Authorization: Bearer YOUR_API_TOKEN'
import requests
from bs4 import BeautifulSoup
with requests.Session() as http_session:
# my login page url
login_url = [LOGIN_URL]
login_page = http_session.get(login_url)
login_inputs = BeautifulSoup(login_page.content, features='html.parser').find_all('input')
# get the authenticity token from the login page
for login_input in login_inputs:
if 'token' in login_input['name']:
auth_token = login_input['value']
break
# send some user-agent header just in case
headers = {"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
# see your login page source for the required data ...
data = {
"username": [MYUSERNAME],
"password": [MYPASSWORD],
"authenticity_token": auth_token,
"remember_me": "1",
"commit": "Sign in"
}
# ... as well as the login endpoint
login_endpoint = [LOGIN_ENDPOINT_URL]
# authenticate
http_session.post(login_endpoint, data=data, headers=headers)
# myfile_url is the url for my wanted file
myfiledata = http_session.get(myfile_url).content