4

I have a report that I want to download in a CSV format using a pyhton script. I searched the web for solutions, but none of them worked. This one looked very promising and simple, but unfortunately does not work either. Any ideas would be helpful.

Update: Thats what I am trying to do when using the technique in the link I provided. I get some weird output and I am not sure what it means.

My code:

import requests

l = requests.get("https://login.salesforce.com/?un=MYUSERNAME&pw=MYPASS")
d = requests.get("https://na2.salesforce.com/00O40000003jBbP?export=1&enc=UTF-8&xf=csv",cookies=l.cookies)
print d.content

Output

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">





<script>
if (this.SfdcApp && this.SfdcApp.projectOneNavigator) { SfdcApp.projectOneNavigator.handleRedirect('https://login.salesforce.com/?ec=302&startURL=%2F00O40000003jBbP%3Fexport%3D1%26xf%3Dcsv%26enc%3DUTF-8'); }  else 
if (window.location.replace){ 
window.location.replace('https://login.salesforce.com/?ec=302&startURL=%2F00O40000003jBbP%3Fexport%3D1%26xf%3Dcsv%26enc%3DUTF-8');
} else {;
window.location.href ='https://login.salesforce.com/?ec=302&startURL=%2F00O40000003jBbP%3Fexport%3D1%26xf%3Dcsv%26enc%3DUTF-8';
} 
</script>

</head>


</html>



<!--
...................................................................................................
...................................................................................................
...................................................................................................
...................................................................................................
-->
Koba
  • 291
  • 1
  • 4
  • 12
  • 1
    Have you seen - Can report data be accessed programatically? It isn't specific to Python, but the basic premise is the same. Use the dedicated Analytics API or request based on the report Id with the export=1 and xf=csv query string arguments. – Daniel Ballinger Aug 21 '14 at 00:25
  • @DanielBallinger I have seen it. In the link I provided the same approach is used I believe (to get a report use the report links). I have been looking at the different ways of downloading files in python using urllib, urllib2, httplib, and others, but did not come up with a solution yet. – Koba Aug 21 '14 at 03:11
  • As an alternative, you might consider Conga Courier appExchange which can send csv report to email recipients on a schedule – cropredy Aug 21 '14 at 05:38
  • @Koba the technique definitely works. The question is, how do you apply it in Python? I don't know Python, but it should be a fairly common thing to make HTTP requests with cookies to a URL and read back the response stream. – Daniel Ballinger Aug 21 '14 at 10:31
  • Any error messages when you try to run the solution from the linked article? – FrankZ Aug 21 '14 at 11:58
  • @FrankZ Not and error msg, but I get weird output. I updated my question. – Koba Aug 21 '14 at 12:18
  • Works for me. Are you sure that a) the login was successful and b) your application is on the na2 instance? – FrankZ Aug 21 '14 at 13:03
  • @FrankZ It does? Hmm weird. Yeah I am sure about it. I will double check. How does your output looks like? – Koba Aug 21 '14 at 13:14
  • What's the output if you add these two lines after the first request? (and add an 'import json' of course) print l.status_code print json.dumps(dict(l.headers), indent=4) – FrankZ Aug 21 '14 at 15:32
  • @FrankZ here is the output – Koba Aug 21 '14 at 19:40
  • @Koba were you able to figure it out? I know this is an old thread but i'm having literally the exact same issue, even made an SO question: https://stackoverflow.com/questions/48443107/export-salesforce-report-as-csv – rodrigocf Jan 25 '18 at 19:20

3 Answers3

1

I manged to do it with the below :

from simple_salesforce import Salesforce
import requests
import base64
import json

sf = Salesforce(username=    #login
                ,password=  # password
                ,security_token= # token )

print "get sid ", sf.session_id

response = requests.get("https://instancename/reportid?view=d&snip&export=1&enc=UTF-8&xf=csv",
                  headers = sf.headers, cookies = {'sid' : sid})

response.contents
cutty14
  • 11
  • 1
0

This answer requires:

  • pandas (because its perfect for this)
  • requests
  • csv

    def sfdc_to_pd(reportid):
    
        login_data = {'un': 'your_username', 'pw': 'your_password'}
    
        with requests.session() as s:
        s.get('https://your_instance.salesforce.com', params = login_data)
        d = requests.get("https://your_instance.salesforce.com/{}?export=1&enc=UTF-8&xf=csv".format(reportid), headers=s.headers, cookies=s.cookies)
        lines = d.content.splitlines()
        reader = csv.reader(lines)
        data = list(reader)
        data = data[:-7]
        df = pd.DataFrame(data)
        df.columns = df.iloc[0]
        df = df.drop(0)
        return df
        print df
    

I know you need this in csv format: to get that, you can just remove everything below data = data[:-7] and replace with code to write csv to disk.

Obol
  • 133
  • 2
0

So this has been driving me crazy, but I figured it out.

you need to curl this:

curl https://login.salesforce.com/services/Soap/u/33.0 -H \"Content-Type: text/xml; charset=UTF-8\" -H \"SOAPAction: login\" -d @sf_login.txt

where sf_login.txt contains:

<?xml version="1.0" encoding="utf-8" ?> <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <n1:login xmlns:n1="urn:partner.soap.sforce.com"> <n1:username>username</n1:username> <n1:password>pass+token</n1:password> </n1:login> </env:Body> </env:Envelope>

parse out the sessionId however you chose and store it as a variable in your python script.

After that post to SF like this:

r = session.post("https://login.salesforce.com/services/oauth2/token", params=payload)

Payload can be a list you set before hand containing the following:

payload = {'grant_type': 'password', 'client_id': 'xxxxxxxxx', 'client_secret': 'xxxxx', 'username': 'xxxx@xxxxx.com', 'password': 'pass+token'}

save the output and convert it to json extract the access token and save it as a variable

once you have the sessionId and access token as variables construct a cookie+header list:

headers = {'Bearer': token}
cookie = {'sid': sid}

Then construct a final request:

d = requests.get("https://na2.salesforce.com/00O40000003jBbP?export=1&enc=UTF-8&xf=csv", headers=headers, cookies=cookie)

Printing content will yield you the csv

hope this helped

Alex
  • 1