API REST de Salesforce: authentification en Python

python, api
Publié le 11/05/2017 | Jérémy Grèze

L'API REST de Salesforce.com permet d’interagir avec l'ensemble des données du CRM (accounts, contacts, opportunities...). Pour cela, il est nécessaire de s’authentifier au préalable, c'est-à-dire d'obtenir un access token.

La documentation indique 3 protocoles OAuth différents pour s'authentifier: Web Server OAuth, User-Agent OAuth et Username-Password OAuth.

Le premier et le deuxième dans une certaine mesure offrent l'avantage de retourner également un refresh token qui permet d'obtenir un nouveau access token. J'utiliserai dans cet exemple le troisième protocole qui est le plus simple à utiliser dans un scénario d'analyse de données.

Créer une application

Dans tous les cas, il faut créer une "Connected App" sur l'instance Salesforce (prod ou sandbox).

Dans la configuration ("Setup"), rechercher et ouvrir la partie "App Manager". Créer une nouvelle app ("New Connected App"). Choisir un nom et entrer les divers champs obligatoires. Il faut cocher l'option "Enable OAuth Settings". Rendre tous les scopes disponibles dans "Selected OAuth Scopes". Remplir "http://localhost/" pour le "Callback URL". Sauvegarder.

Au final, il faut obtenir le "Consumer Key" et le "Consumer Secret". Bien noter ces deux valeurs pour la suite.

S'authentifier avec le Username-Password OAuth Flow de Salesforce

Avec le login, mot de passe et security token d'un utilisateur, utiliser ce script Python pour obtenir l'access token.

import requests
params = {
    "grant_type": "password",
    "client_id": "XXX.YYY", # Consumer Key
    "client_secret": "0000000000000000", # Consumer Secret
    "username": "my@email.com", # The email you use to login
    "password": "MyPasswordMySecurityToken" # Concat your password and your security token
}
r = requests.post("https://login.salesforce.com/services/oauth2/token", params=params)
access_token = r.json().get("access_token")
instance_url = r.json().get("instance_url")
print("Access Token:", access_token)
print("Instance URL", instance_url)

Requêter l'API REST Salesforce

Une fois l'authentification validée, on peut requêter l'API REST Salesforce pour faire des extractions de données (leads, opportunités, etc.) ou même mettre à jour ou créer des données.

import requests

def sf_api_call(action, parameters = {}, method = 'get', data = {}):
    """
    Helper function to make calls to Salesforce REST API.
    Parameters: action (the URL), URL params, method (get, post or patch), data for POST/PATCH.
    """
    headers = {
        'Content-type': 'application/json',
        'Accept-Encoding': 'gzip',
        'Authorization': 'Bearer %s' % access_token
    }
    if method == 'get':
        r = requests.request(method, instance_url+action, headers=headers, params=parameters, timeout=30)
    elif method in ['post', 'patch']:
        r = requests.request(method, instance_url+action, headers=headers, json=data, params=parameters, timeout=10)
    else:
        # other methods not implemented in this example
        raise ValueError('Method should be get or post or patch.')
    print('Debug: API %s call: %s' % (method, r.url) )
    if r.status_code < 300:
        if method=='patch':
            return None
        else:
            return r.json()
    else:
        raise Exception('API error when calling %s : %s' % (r.url, r.content))

Un exemple tout simple: récupérons les prochaines opportunités qui vont "closer" avec une requête SOQL (Salesforce Object Query Language).

print(json.dumps(sf_api_call('/services/data/v39.0/query/', {
    'q': 'SELECT Account.Name, Name, CloseDate from Opportunity where IsClosed = False order by CloseDate ASC LIMIT 10'
}), indent=2))

Le résultat est un JSON facilement exploitable.

Voila!