Reputation: 2099
I'm trying to pull salesforce reports through python. I've tried this approach:
import requests
l = requests.get('sfinstanceurl/?un=user&pw=passw')
report = requests.get('sfinstanceurl/reportid?view=d&snip&export=1&enc=UTF-8&xf=csv',cookies=l.cookies)
print(report.content)
Also this one:
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
And for both, when i print the content I get this (even though the status response is always 200):
b'\r\n<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n<html>\n<head>\n <meta HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">\n\n\n\n\n\n<script>\nif (this.SfdcApp && this.SfdcApp.projectOneNavigator) { SfdcApp.projectOneNavigator.handleRedirect(\'sfinstanceurl?ec=302&startURL=%2F00O0m000000JzRc%3Fview%3Dd%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv%26snip%3D\'); } else \nif (window.location.replace){ \nwindow.location.replace(\'sfinstanceurl?ec=302&startURL=%2F00O0m000000JzRc%3Fview%3Dd%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv%26snip%3D\');\n} else {;\nwindow.location.href =\'sfinstanceurl?ec=302&startURL=%2F00O0m000000JzRc%3Fview%3Dd%26enc%3DUTF-8%26export%3D1%26xf%3Dcsv%26snip%3D\';\n} \n</script>\n\n</head>\n\n\n</html>\n\n\n\n\n\n<!-- Body events -->\n<script type="text/javascript">function bodyOnLoad(){if(window.PreferenceBits){window.PreferenceBits.prototype.csrfToken="null";};}function bodyOnBeforeUnload(){}function bodyOnFocus(){}function bodyOnUnload(){}</script>\n\t\t\t\n</body>\n</html>\n\n\n<!--\n...................................................................................................\n...................................................................................................\n...................................................................................................\n...................................................................................................\n-->\n'
My company uses SSO, so security tokens are not something i have to try a different approach. Am I missing something? Why do I not get the report in the content?
EDIT:
I also just tried this approach:
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' : sf.session_id})
response.content
It still returns the same HTML object.
Upvotes: 1
Views: 4661
Reputation: 624
Looks like you are running reports from the SF instance directly, this will always return HTML as it is not an API call.
To access Reports through an API please refer to the documentation for Salesforce Reports and Dashboards REST API:
Below is a link to the resources specifically for reports:
When using Simple Salesforce you can easily call the API, like this:
from simple_salesforce import Salesforce
import requests
import base64
import json
sf = Salesforce(username=[username],password=[password],security_token=[token])
reportId = '00OR0000000K2UeMAK'
reportRESTPath = ('analytics/reports/{id}'.format(id='00OR0000000K2UeMAK')
# Synchronous report get
reportJSON = sf.restful(reportRESTPath, {'includeDetails': 'true'})
# Asynchronous report create
asyncJobJSON = sf.restful(reportRESTPath, {'includeDetails': 'true'}, 'POST')
# Asynchronous report get
reportJSON = sf.restful(('{basePath}/instances/{instanceId}'.format(basePath=reportRESTPath,instanceId=asyncJobJSON.Id), {'includeDetails': 'true'})
Upvotes: 3