Using a get request through a browser I can download a report from Salesforce as a .csv.
However, when I try to replicate this action using Python and the requests module I can not generate the report either as a .csv or a Data Frame.
The request follows this pattern:
url = '{0}/{1}?export=1&enc=ISO-8859-1&xf=csv&isdtp=nv'.format(base_url, report_id)
I have authenticated as follows:
import requests
import logging
# Function to establish a connection to Salesforce: sforce_connect => function()
def sforce_connect(c_id, cs_id, sforce_uname, sforce_pwd):
"""Function to create a connection with Salesforce.
Dependent on the requests module.
Args:
c_id (str): A string scalar denoting the Consumer (Client) ID.
cs_id (str): A string scalar denoting the Consumer (Client) Secret ID
sforce_uname (str): A string scalar denoting the user's salesforce username.
sforce_pwd (str): A string scalar denoting the user's salesforce password.
Returns:
(list): A list comprised of the instance_url (str) scalar, and the oauth details (dict).
"""
# Store the auth url as a string scalar: auth_url => string scalar
# Visit https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_oauth_endpoints.htm
auth_url = 'https://login.salesforce.com/services/oauth2/token'
# Callback URL: redirect_url => string scalar
# redirect_uri = 'http://localhost/'
# Defensively attempt to:
try:
# Issue a POST request in order to retrieve access token: response => response object
response = requests.post(auth_url, data = {
'client_id': c_id,
'client_secret': cs_id,
'grant_type': 'password',
'username': sforce_uname,
'password': sforce_pwd})
# If an error occurs:
except Exception as error:
# Log the error: str => stdout(logfile)
logging.critical("Failed to retrieve Bearer token from Salesforce API, rest of run will be problematic, the "
+ " error caught: " + repr(error))
# Extract the json from the response: json_res => json object
json_res = response.json()
# Extract the access token from the json response object: access_token => string scalar
access_token = json_res['access_token']
# Extract the token type from the json response object: token_type => string scalar
token_type = json_res['token_type']
# Extract the session id: session_id => string scalar
session_id = json_res['id']
# A dictionary denoting the Authorisation string required, token type concatenated with the token: auth => dictionary
oauth = {'Authorization': ' '.join([token_type, access_token])}
# Extract the instance url from the response.json(): instance_url => string scalar
instance_url = json_res['instance_url']
# Explicitly define the return object: list => GlobalEnv()
return([instance_url, oauth, session_id])
# Apply the function to establish a connection with salesforce:
# instance_url => string scalar, auth => dictionary, session_id => string scalar
instance_url, auth, session_id = sforce_connect(
client_id, client_secret, sfdc_user, sfdc_pass
)
And I have attempted to retrieve the .csv as follows but it is not generating:
req = requests.get(url, headers = auth)
df = pd.read_csv(req.content)
Due to security concerns I can not use the simple-salesforce package or Selenium (and am limited to requests, urllib3). Any help would be greatly appreciated.
Also, this is the returned object:
<!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>
function redirectOnLoad() {
var escapedHash = '';
var url = '/saml/authn-request.jsp?saml_request_id=PERSONAL INFO;
if (window.location.hash) {
escapedHash = '%23' + window.location.hash.slice(1);
}
if (window.location.replace){
window.location.replace(url + escapedHash);
} else {
window.location.href = url + escapedHash;
}
}
redirectOnLoad();
</script>
</head>
</html>
<!-- Body events -->
<script type="text/javascript">function bodyOnLoad(){if(window.PreferenceBits){window.PreferenceBits.prototype.csrfToken="null";};}function bodyOnBeforeUnload(){}function bodyOnFocus(){}function bodyOnUnload(){}</script>
</body>
</html>
<!--
...................................................................................................
...................................................................................................
...................................................................................................
...................................................................................................
-->