无法将附件正确上传到 Azure DevOps API(0kb 结果)
Unable to upload attachment to Azure DevOps API correctly (0kb result)
我正在尝试使用 REST API 将附件上传到 Azure DevOps 中的工作项。但是,虽然我可以获得附件 "uploaded" 并附加到工作项,但附件的大小始终为 0KB,无论是在 UI 中还是在我下载它时。
API 看起来相当简单,我用过的其他十几个 API 都没有问题。我只是不知道这是哪里出了问题。这是我为此使用的代码:
import os
import sys
import requests
_credentials = ("user@example.com", "password")
def post_file(url, file_path, file_name):
file_size = os.path.getsize(file_path)
headers = {
"Accept": "application/json",
"Content-Size": str(file_size),
"Content-Type": "application/octet-stream",
}
request = requests.Request('POST', url, headers=headers, auth=_credentials)
prepped = request.prepare()
with open(file_path, 'rb') as file_handle:
prepped.body = file_handle.read(file_size)
return requests.Session().send(prepped)
def add_attachment(path_to_attachment, ticket_identifier):
filename = os.path.basename(path_to_attachment)
response = post_file(
f"https://[instance].visualstudio.com/[project]/_apis/wit/attachments?uploadType=Simple&fileName={filename}&api-version=1.0",
path_to_attachment,
filename
)
data = response.json()
attachment_url = data["url"]
patch_result = requests.patch(
f"https://[instance].visualstudio.com/[project]/_apis/wit/workitems/{ticket_identifier}?api-version=4.1",
auth=_credentials,
headers={
"Accept": "application/json",
"Content-Type": "application/json-patch+json",
},
json=[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": attachment_url
},
}
]
)
print(patch_result)
print(patch_result.text)
add_attachment(sys.argv[1], sys.argv[2])
我已经尝试了 setting/removing/varying 我能想到的所有可能的 header 值。我试过使用 requests
中 post
方法上的 files
属性(但放弃了它,因为它设置了 Content-Disposition,但我见过的所有示例都没有使用那个),我已经尝试设置区域路径参数,我已经尝试了我能想到的一切,但没有任何区别。
我什至使用 Fiddler 观察了实际网站是如何做到的,然后将 header 复制到 Python 中的新请求并发送了它,我 仍然看到0kb的结果。
此时我几乎没有想法,所以如果有人知道我可能哪里出错了,将不胜感激!
这个问题的答案并不明显。这是第二次调用 link 存在错误的工作项的附件。如果未指定 评论,则它不会 link 正确。即此代码:
json=[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": attachment_url
},
}
]
应该是:
json=[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": attachment_url,
"attributes": {
"comment": ""
}
},
}
]
这没有记录,如果您没有在 linking 阶段指定评论,也不希望您上传 0KB 的附件。没有其他 link 类型需要评论。我将向文档维护者提出这个问题。
我也一直在研究这个问题并找到了解决方案。您必须在 json 中添加文件大小参数。您无需发表评论即可显示尺码。
请注意,DevOps 似乎四舍五入到最接近的 1,000(我的测试文件是 325,在 DevOps 中显示为 1K)
file_size = os.path.getsize(file_path)
json = [
{
"op": "add",
"path": "/relations/-",
"value": {"rel": "AttachedFile", "url": attachment.url,
"attributes": {"comment": "DevOps Test", "resourceSize": file_size},
}
}
]
希望这对某人有所帮助!
你的 post 文件函数应该变成:
def post_file(url, file_path, file_name):
file_size = os.path.getsize(file_path)
headers = {
"Accept": "application/json",
"Content-Size": str(file_size),
"Content-Type": "application/octet-stream",
}
files = {'file': open(file_path, 'rb')}
r = requests.post(url, files=files, headers=headers, auth=(username, token))
return r
我正在尝试使用 REST API 将附件上传到 Azure DevOps 中的工作项。但是,虽然我可以获得附件 "uploaded" 并附加到工作项,但附件的大小始终为 0KB,无论是在 UI 中还是在我下载它时。
API 看起来相当简单,我用过的其他十几个 API 都没有问题。我只是不知道这是哪里出了问题。这是我为此使用的代码:
import os
import sys
import requests
_credentials = ("user@example.com", "password")
def post_file(url, file_path, file_name):
file_size = os.path.getsize(file_path)
headers = {
"Accept": "application/json",
"Content-Size": str(file_size),
"Content-Type": "application/octet-stream",
}
request = requests.Request('POST', url, headers=headers, auth=_credentials)
prepped = request.prepare()
with open(file_path, 'rb') as file_handle:
prepped.body = file_handle.read(file_size)
return requests.Session().send(prepped)
def add_attachment(path_to_attachment, ticket_identifier):
filename = os.path.basename(path_to_attachment)
response = post_file(
f"https://[instance].visualstudio.com/[project]/_apis/wit/attachments?uploadType=Simple&fileName={filename}&api-version=1.0",
path_to_attachment,
filename
)
data = response.json()
attachment_url = data["url"]
patch_result = requests.patch(
f"https://[instance].visualstudio.com/[project]/_apis/wit/workitems/{ticket_identifier}?api-version=4.1",
auth=_credentials,
headers={
"Accept": "application/json",
"Content-Type": "application/json-patch+json",
},
json=[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": attachment_url
},
}
]
)
print(patch_result)
print(patch_result.text)
add_attachment(sys.argv[1], sys.argv[2])
我已经尝试了 setting/removing/varying 我能想到的所有可能的 header 值。我试过使用 requests
中 post
方法上的 files
属性(但放弃了它,因为它设置了 Content-Disposition,但我见过的所有示例都没有使用那个),我已经尝试设置区域路径参数,我已经尝试了我能想到的一切,但没有任何区别。
我什至使用 Fiddler 观察了实际网站是如何做到的,然后将 header 复制到 Python 中的新请求并发送了它,我 仍然看到0kb的结果。
此时我几乎没有想法,所以如果有人知道我可能哪里出错了,将不胜感激!
这个问题的答案并不明显。这是第二次调用 link 存在错误的工作项的附件。如果未指定 评论,则它不会 link 正确。即此代码:
json=[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": attachment_url
},
}
]
应该是:
json=[
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": attachment_url,
"attributes": {
"comment": ""
}
},
}
]
这没有记录,如果您没有在 linking 阶段指定评论,也不希望您上传 0KB 的附件。没有其他 link 类型需要评论。我将向文档维护者提出这个问题。
我也一直在研究这个问题并找到了解决方案。您必须在 json 中添加文件大小参数。您无需发表评论即可显示尺码。
请注意,DevOps 似乎四舍五入到最接近的 1,000(我的测试文件是 325,在 DevOps 中显示为 1K)
file_size = os.path.getsize(file_path)
json = [
{
"op": "add",
"path": "/relations/-",
"value": {"rel": "AttachedFile", "url": attachment.url,
"attributes": {"comment": "DevOps Test", "resourceSize": file_size},
}
}
]
希望这对某人有所帮助!
你的 post 文件函数应该变成:
def post_file(url, file_path, file_name):
file_size = os.path.getsize(file_path)
headers = {
"Accept": "application/json",
"Content-Size": str(file_size),
"Content-Type": "application/octet-stream",
}
files = {'file': open(file_path, 'rb')}
r = requests.post(url, files=files, headers=headers, auth=(username, token))
return r