无法将附件正确上传到Azure DevOps API(结果为0kb)

时间:2018-11-29 13:11:51

标签: python python-requests azure-devops azure-devops-rest-api

我正在尝试使用REST API将附件上载到Azure DevOps中的工作项。但是,虽然我可以将附件“上载”并附加到工作项,但无论是在UI中还是在下载时,附件的大小始终为0KB。

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])

我尝试设置/删除/更改我能想到的每个可能的标头值。我尝试使用filespost方法上的requests属性(但由于设置了Content-Disposition而将其删除了,但是我看到的所有示例都没有使用该属性) ),我尝试设置区域路径参数,尝试了所有可以想到的方法,但没有任何区别。

我什至使用Fiddler来观察实际站点的工作方式,然后将标头复制到Python中的新请求并将其发送给我, still 仍然看到0kb的结果。

在这一点上,我几乎没有主意,因此,如果有人知道我可能要去哪里,那将不胜感激!

3 个答案:

答案 0 :(得分:0)

答案并不明显。这是第二次将附件链接到具有该错误的工作项的调用。如果未指定注释,则无法正确链接。即此代码:

json=[
    {
        "op": "add",
        "path": "/relations/-",
        "value": {
            "rel": "AttachedFile",
            "url": attachment_url
        },
    }
]

应该是:

json=[
    {
        "op": "add",
        "path": "/relations/-",
        "value": {
            "rel": "AttachedFile",
            "url": attachment_url,
            "attributes": {
                "comment": ""
            }
        },
    }
]

这没有记录,如果您在链接阶段未指定评论,也不会上传0KB附件。没有其他链接类型需要注释。我将向文档维护者提出这个问题。

答案 1 :(得分:0)

我也一直在努力,找到了解决方案。您必须在json中添加filesize参数。您无需添加评论即可显示尺寸。

请注意,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},
             }
        }
    ]

希望这对某人有帮助!

答案 2 :(得分:0)

你的帖子文件功能应该变成:

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