代码之家  ›  专栏  ›  技术社区  ›  Arne Mertz

使用Python请求将附件上载到Confluence REST API会产生415和500个错误

  •  4
  • Arne Mertz  · 技术社区  · 10 年前

    我正在尝试使用Python Requests通过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)

    1 回复  |  直到 10 年前
        1
  •  5
  •   Arne Mertz    10 年前

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

    尽管 Python Requests documentation 显式写入 files 参数用于上载多部分编码的文件,需要将内容类型显式设置为附件的正确类型。
    虽然这并不完全正确(见下面的评论), 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()