使用multipartform将文件上载到Salesforce

2024-09-24 02:25:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图上传一个文本文件(也尝试PDF等)到Salesforce。 文本文件包含“hello world”。你知道吗

这是我正在使用的代码

def putFile(sf, libname, filen):
    file_name=os.path.basename(filen)
    libId=libraryExists(sf, libname)
    contentDocumentId = getContentDocumentId(sf, libname, file_name)
    if not libId:
        print(f"Provided library '{libname}' does not exists")
        return

    with open(filen, "rb") as f:
        bodyEncoded = base64.b64encode(f.read())

    boundary = '----------------------------741e90d31eff'
    headers = {
        'Content-Type' : 'multipart/form-data; boundary=' + boundary
    }

    nonBinaryPart = '--'+boundary+'\nContent-Disposition: form-data; name="entity_content";\n'
    nonBinaryPart += 'Content-Type: application/json;\r\n\r\n'
    nonBinaryPart += json.dumps({
        "ContentDocumentId" : contentDocumentId,
        "ReasonForChange" : "Large file upload", 
        "PathOnClient" : file_name
    })
    nonBinaryPart += '\r\n\r\n'

    header = '--'+boundary+'\nContent-Disposition: form-data; name="VersionData"; filename="'+file_name+'";\nContent-Type: application/octet-stream\r\n\r\n'
    footer = '--'+boundary+'--'
    headerEncoded = header
    last4Bytes = bodyEncoded[len(bodyEncoded)-4:len(bodyEncoded)]
    print(type(last4Bytes))
    print(last4Bytes)
    if last4Bytes.endswith(b'=='):
        last4Bytes = last4Bytes[0:2] + b'0K'
        bodyEncoded = bodyEncoded[0:len(bodyEncoded)-4] + last4Bytes
        footerEncoded = footer
        reqBody = headerEncoded+str(bodyEncoded)+footerEncoded
    elif last4Bytes.endswith(b'='):
        print('Ends with =')
        last4Bytes = last4Bytes[0:3] + b'N'
        bodyEncoded = bodyEncoded[0:len(bodyEncoded)-4] + last4Bytes
        footer = '\n' + footer;
        footerEncoded = footer
        reqBody = headerEncoded+str(bodyEncoded)+footerEncoded
    else:
        footer = '\r\n' + footer
        footerEncoded = footer
        reqBody = headerEncoded+str(bodyEncoded)+footerEncoded

    reqBody = nonBinaryPart + reqBody

    print('==================================================')
    print(reqBody)
    print('==================================================')

    res = sf.contentVersion.create(reqBody, headers)

    print(res)

    print('Now downloading it...')
    os.system('rm -f ' + filen + '_downloaded')
    getFile(sf, contentDocumentId, filen + '_downloaded', './' )
    print('Downloaded.')


    os.system('md5sum ' + filen)
    os.system('md5sum ' + filen + '_downloaded')

根据Salesforce指南,这将产生以下请求主体: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_insert_update_blob.htm

标题:

内容类型:多部分/表单数据;边界=“----------------------------------------741e90d31eff” 接受:application/json

请求正文:

------------------------------741e90d31eff 内容处理:表单数据;name=“entity\u Content”; 内容类型:application/json

{“ContentDocumentId”:“0699e00000lkblqau”,“ReasonForChange”:“大文件上传”,“PathOnClient”:“你好_世界.txt“}

------------------------------741e90d31eff 内容处理:表单数据;name=“VersionData”;filename=“hello_世界.txt"; 内容类型:应用程序/八位字节流

“aGVsbG8gd29ybGQK” ------------------------------741e90d31eff--


Tags: name内容ossffilefooterprintboundary
2条回答

终于有了。因此,要将多部分表单数据上载到Salesforce: 1没有base64编码!!!! 它需要保持二进制 2我的错误是我试图将字符串连接到字节。 因此,构建多部分消息的非二进制部分并将其编码为二进制:

nonbinaryPart.encode()
  1. 比附加字节到字节,文件的二进制内容。你知道吗
  2. 调用api时,以字节形式发布数据。注意API的用法,比如simple salsforce在默认情况下可能希望将其编码为json。不需要后续编码。以二进制形式发布。你知道吗

就像您的代码所显示的bodyEncoded = base64.b64encode(f.read()),文件以base64编码的形式发送。您需要在下载文件后对其进行解码,以恢复其原始的“可读”值。你知道吗

注意:如您的注释所述,文件的内容是b'aGVsbG8gd29ybGQK',其中b表示base64编码的字符串,另一部分是编码值,您也可以使用base64decode这样的在线工具对其进行编码,该工具将显示字符串正是hello world

相关问题 更多 >