【问题标题】:Uploading attachments to Confluence REST API with Python Requests gives 415 and 500 Errors使用 Python 请求将附件上传到 Confluence REST API 会出现 415 和 500 错误
【发布时间】:2016-05-19 02:16:06
【问题描述】:

我正在尝试使用 Python 请求通过 REST API 将附件上传到 Confluence。我总是收到“415 不支持的媒体类型”错误或“500 内部服务器错误”,具体取决于我发送请求的方式。

有一些关于如何使用其他语言执行此操作的信息,或者通过现已弃用的 XMLRPC API 使用 Python,或者对于行为似乎略有不同的 JIRA REST API。

根据所有这些信息,代码应该是这样的:

def upload_image():
    url = 'https://example.com/confluence/rest/api/content/' + \
          str(PAGE_ID) + '/child/attachment/'
    headers = {'X-Atlassian-Token': 'no-check'}
    files = {'file': open('image.jpg', 'rb')}
    auth = ('USR', 'PWD')
    r = requests.post(url, headers=headers, files=files, auth=auth)
    r.raise_for_status()

缺少的是正确的内容类型标头。那里有不同的信息:

  • 为文件使用正确的内容类型,在本例中为image/jpeg
  • 使用application/octet-stream
  • 使用application/json
  • 使用multipart/form-data

(我使用的 Confluence 版本是 5.8.10)

【问题讨论】:

    标签: python rest python-requests confluence-rest-api


    【解决方案1】:

    使用正确的内容类型并不是这里唯一的问题。在正确的地方使用它同样重要。对于文件上传,内容类型必须随文件一起提供,而不是作为请求本身的标头。

    即使Python Requests documentation 明确指出files 参数用于上传多部分编码的文件,内容类型也需要明确设置为附件的正确类型。
    虽然它并不完全正确(参见下面的 cmets),但 multipart/form-data 也可以正常工作,因此如果我们确实无法确定正确的内容类型,我们可以将其用作后备:

    def upload_image():
        url = 'https://example.com/confluence/rest/api/content/' + \
              str(PAGE_ID) + '/child/attachment/'
        headers = {'X-Atlassian-Token': 'no-check'} #no content-type here!
        file = 'image.jpg'
    
        # determine content-type
        content_type, encoding = mimetypes.guess_type(file)
        if content_type is None:
            content_type = 'multipart/form-data'
    
        # provide content-type explicitly
        files = {'file': (file, open(file, 'rb'), content_type)}
    
        auth = ('USR', 'PWD')
        r = requests.post(url, headers=headers, files=files, auth=auth)
        r.raise_for_status()
    

    【讨论】:

    • 不,这似乎不对。您需要为附件指定媒体/mime 类型。在您的示例中,这应该是 image/jpeg,而不是 multipart/form-data,后者将用作 HTTP 请求的 Content-Type 标头(requests 正确执行此操作)。关于您问题中的代码,可能 Confluence 服务器注意到该文件没有指定 no 内容类型,并拒绝接受它。你应该像这样设置files:files = {'file': ('image.jpg', open('image.jpg', 'rb'), 'image/jpeg')}
    • @mhawke 我试过了,它也给出了 415 错误。您链接的文档没有提到内容类型,除了The name of the multipart/form-data parameter that contains attachments must be "file"。
    • 你是对的,它没有明确地提到,但这就是它应该在HTTP中的样子。您可以通过尝试文档中的 curl 示例来检查。 curl 生成的 HTTP 请求为附件设置以下标头:Content-Disposition: form-data; name="file"; filename="myfile.txt" 和 Content-Type: text/plain。如果您更改示例以使用 JPG 图像文件 curl 设置 Content-Type: image/jpeg 如您所料。你能在你的 Confluence 实例中使用curl 试试这个例子,看看它是否有效?首先尝试一个文本文件,如果可行,再尝试一个图像文件。
    • @mhawke 我尝试 curl 并再次检查,为文件提供正确的 content_type。它现在有效,不知道为什么我第一次尝试时它不起作用。我相应地改变了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    相关资源
    最近更新 更多