Upload multiple files using simple-salesforce python
Asked Answered
R

2

7

I started learning SalesForce and developing apps using django.

I need assistance with uploading a file to salesforce, For that I read simple-salesforce and this that help to upload file using rest and SOAP api.

My question is how do I upload one or more files using simple-salesforce?

Retene answered 16/9, 2016 at 10:18 Comment(0)
P
3

Here is the code block I use for uploading files.

def load_attachments(sf, new_attachments):
    '''
        Method to attach the Template from the Parent Case to each of the     children.
        @param: new_attachments the dictionary of child cases to the file name of the template
    '''
    url = "https://" + sf.get_forced_url() + ".my.salesforce.com/services/data/v29.0/sobjects/Attachment/"
    bearer = "Bearer " + sf.get_session_id()
    header = {'Content-Type': 'application/json', 'Authorization': bearer}

    for each in new_attachments:
        body = ""
        long_name = str(new_attachments[each]).split(sep="\\")
        short_name = long_name[len(long_name) - 1]
        with open(new_attachments[each], "rb") as upload:
            body = base64.b64encode(upload.read())
        data = json.dumps({
                           'ParentId': each,
                           'Name': short_name,
                           'body': body
                          })
        response = requests.post(url, headers=header, data=data)
        print(response.text)

Basically, to send the file, you need to use the requests module and submit the file via a post transaction. The post transaction requires the URL to which the request is sent, the header information, and the data.

Here, sf is the instance of returned by the simple-salesforce initialization. Since my instance uses custom domains, I had to create my own function in simple-salesforce to handle that; I call it get_forced_url(). Note: The URL is may be different for you depending on which version you are using [the v29.0 portion may change].

Then I set up my bearer and header.

The next thing is a loop that submits a new attachment for each attachment in a map from Parent ID to the File I wish to upload. This is important to note, attachments must have a Parent Object so you need to know the ParentId. For each attachment, I blank out the body, create a long and short name for the attachment. Then the important part. On attachments, the actual data of the file is stored as a base-64 binary array. So the file must be opened as binary, hence the "rb" and then encoded to base-64.

Once the file has been parsed to base-64 binary, I build my json string where ParentId is the object ID of the parent object, the Name is the short name, and the body is the base-64 encoded string of data.

Then the file is submitted to the URL with the headers and data. Then I print the response so I could watch it happening.

Pentarchy answered 19/9, 2016 at 17:42 Comment(0)
R
4

To upload files, you only need simple-salesforce

Complete example, including creating Account, Contact and Case. Then attaching the file to Case.

#Create Account, Contact and Case
AccountID = sf.Account.create({'Name':'Test12','Phone':'987654321'})["id"]
ContactID = sf.Contact.create({'LastName':'Smith2','Email':'[email protected]'})["id"]
CaseID = sf.Case.create({'AccountId':AccountID,'ContactId':ContactID,'Description':'Test4321','Subject':'Test4321'})

#Convert image to Base64
import json, base64
with open('test1.png', mode='rb') as file:
    img = file.read()
image = base64.encodebytes(img).decode('utf-8')

#The simple example
sf.Attachment.create({'ParentId': CaseID["id"],'Name':'TestFile1','body': image,'ContentType':'image/png'})

And how to change the 'one-file' example to multiple files

sf.bulk.Attachment.insert([
    {'ParentId': CaseID["id"],'Name':'TestFile2','body': image,'ContentType':'image/png'},
    {'ParentId': CaseID["id"],'Name':'TestFile3','body': image,'ContentType':'image/png'},
    {'ParentId': CaseID["id"],'Name':'TestFile4','body': image,'ContentType':'image/png'},
    {'ParentId': CaseID["id"],'Name':'TestFile5','body': image,'ContentType':'image/png'},
    {'ParentId': CaseID["id"],'Name':'TestFile6','body': image,'ContentType':'image/png'},
    {'ParentId': CaseID["id"],'Name':'TestFile7','body': image,'ContentType':'image/png'},
    {'ParentId': CaseID["id"],'Name':'TestFile8','body': image,'ContentType':'image/png'},
    {'ParentId': CaseID["id"],'Name':'TestFile9','body': image,'ContentType':'image/png'}],batch_size=1000,use_serial=True)

(you know how to fix the rest)

Refuel answered 11/11, 2021 at 10:41 Comment(3)
This is so the right answer and insanely easy. @RefuelCanoness
I like the answer, do you know how to upload to ContentVersion?Bagwell
this approach is limited to 50 MB max file size. A multi-part request is required if you need to exceed this limit developer.salesforce.com/docs/atlas.en-us.api_rest.meta/….Bystander
P
3

Here is the code block I use for uploading files.

def load_attachments(sf, new_attachments):
    '''
        Method to attach the Template from the Parent Case to each of the     children.
        @param: new_attachments the dictionary of child cases to the file name of the template
    '''
    url = "https://" + sf.get_forced_url() + ".my.salesforce.com/services/data/v29.0/sobjects/Attachment/"
    bearer = "Bearer " + sf.get_session_id()
    header = {'Content-Type': 'application/json', 'Authorization': bearer}

    for each in new_attachments:
        body = ""
        long_name = str(new_attachments[each]).split(sep="\\")
        short_name = long_name[len(long_name) - 1]
        with open(new_attachments[each], "rb") as upload:
            body = base64.b64encode(upload.read())
        data = json.dumps({
                           'ParentId': each,
                           'Name': short_name,
                           'body': body
                          })
        response = requests.post(url, headers=header, data=data)
        print(response.text)

Basically, to send the file, you need to use the requests module and submit the file via a post transaction. The post transaction requires the URL to which the request is sent, the header information, and the data.

Here, sf is the instance of returned by the simple-salesforce initialization. Since my instance uses custom domains, I had to create my own function in simple-salesforce to handle that; I call it get_forced_url(). Note: The URL is may be different for you depending on which version you are using [the v29.0 portion may change].

Then I set up my bearer and header.

The next thing is a loop that submits a new attachment for each attachment in a map from Parent ID to the File I wish to upload. This is important to note, attachments must have a Parent Object so you need to know the ParentId. For each attachment, I blank out the body, create a long and short name for the attachment. Then the important part. On attachments, the actual data of the file is stored as a base-64 binary array. So the file must be opened as binary, hence the "rb" and then encoded to base-64.

Once the file has been parsed to base-64 binary, I build my json string where ParentId is the object ID of the parent object, the Name is the short name, and the body is the base-64 encoded string of data.

Then the file is submitted to the URL with the headers and data. Then I print the response so I could watch it happening.

Pentarchy answered 19/9, 2016 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.