Partie II.c : Utiliser des Scripts FR

Nous avons vu les fondements de la manipulation des données de Sciforma à l’aide de Postman. Ce n’est pas tout à fait fini ; nous continuerons cette découverte plus tard. Ce chapitre-ci sera axé sur la modification d’un volume de données beaucoup plus important à l’aide de scripts.

L’introduction a expliqué pourquoi nous allons utiliser Python comme langage de script. Cependant, mon exemple pourrait facilement être traduit dans n’importe quel autre langage de programmation moderne.

Je ne donnerai pas de conseils sur la façon d’utiliser les outils de script ou même la programmation en Python. Néanmoins, je vais partager avec vous des exemples fonctionnels. Ils ne sont pas exactement construits de cette manière dans mes implémentations professionnelles, mais ils fonctionnent et c’est ce qu’on leur demande.

Le scénario.

Dans ce premier exemple, nous allons nous en tenir au traitement des données de ressources. Le cas d’utilisation est le suivant.

Dans la vraie vie, vous utilisez probablement plusieurs instances de votre base de données Sciforma. Une version est destinée à la production, l’autre à la qualification ou aux essais et l’autre au développement.

Vous remarquerez sûrement qu’il n’y a pas de moyen intégré pour distinguer visuellement ces instances (je parle à la fois du Designer et du client HTML). Vous ne pouvez pas changer le schéma de couleurs ; vous ne pouvez pas mettre un grand panneau d’en-tête rouge pour vous faire savoir sur quelle version vous travaillez, et vous avez à coup sûr expérimenté que, en travaillant avec plusieurs fenêtres de Designer ou HTML simultanément, l’erreur de manipulation n’est jamais très loin. Ma meilleure idée pour différentier les environnements a été d’avoir différentes icônes d’avatar dans chaque version, visuellement différentes. Cela, par ailleurs, ne fonctionne qu’avec le client HTML.

La deuxième idée était d’utiliser le Middle Name. En France ; ce Middle Name est systématiquement laissé vide. Si je mets « DEV » ou « TEST » comme deuxième nom pour toutes les ressources (vous voyez le cas d’utilisation à venir, n’est-ce pas ?), cela donnera des indices sur presque toutes les pages, sur la version sur laquelle je me trouve et diminuera en fait le risque d’erreur.

Changer le deuxième nom de toutes les ressources avec copier-coller est assez lourd, nous allons donc utiliser un script de base.

Écrivons doc un script qui se connectera à, disons, l’instance TEST et définira 'TEST' comme deuxième nom pour toutes les ressources.

La structure du Script

Nous savons comment mettre à jour les données de la ressource. Pour cela, nous avons besoin de son ID. La structure de notre script sera

get the required data for authentification

for each resource in the resource list:
	if the resource is active:
		update its middle name to 'TEST'

Les données requises pour l’authentification

Dans Postman, nous avons mis en place le mécanisme pour obtenir le token d’autorisation du serveur 0auth et le transmettre à toutes les requêtes que nous avons écrites. Ici, nous devons le faire nous-mêmes.

J’ai aussi mentionné dans le chapitre précédent que nous devions spécifier le Content-Type pour certaines requêtes. Cela sera nécessaire non seulement pour les demandes PATCH que vous connaissez, mais aussi pour PUT, DELETE et POST, que nous verrons plus tard.

Nous devons gérer un en-tête pour GET et un pour PATCH dans notre cas d’utilisation. En effet, nous allons lire les ressources (GET) puis apporter des modifications (PATCH). Comme nous l’avons fait avec Postman, nous allons également définir toutes les variables dont nous avons besoin.

import json, requests

token_url = 'https://YOUR_DOMAIN_HERE.sciforma.net/oauth2/token'
rest_url = 'https://YOUR_DOMAIN_HERE.sciforma.net/sciforma/rest/'

header_token = {
	 'Content-type': 'application/x-www-form-urlencoded',
}

# get the token
body = {
	'client_id': YOUR_CLIENT_ID,
	'client_secret': YOUR_CLIENT_SECRET,
  'grant_type': 'client_credentials',
  'scope': 'resources:read resources:write',
  }
response = requests.post(url=token_url,
                         headers=header_token,
                         verify=False,
                         data=body)
token = response.json()['access_token']

# define the GET header
header_get = {
        'Content-type': 'application/json',
        'Authorization': f'Bearer {token}',
        'Cache-Control': 'no-cache'
    }

# define the PATCH header
header_patch = {
        'Content-type': 'application/vnd.sciforma.v1+merge-patch+json',
        'Authorization': f'Bearer {token}',
        'Cache-Control': 'no-cache'
    }

Passons en revue quelques commentaires :

Récupérons la liste des ressources.

Nous ne pouvons pas accéder à la liste complète des ressources en même temps, nous devons donc la paginer. Nous utiliserons des pages avec 100 éléments.

Voici la deuxième partie du code :

LIMIT = 100
offset = 0

# prepare the data to write to the resources
data = {
	'Middle Name': 'TEST',
}

while True:
	# reads the 'page' of resources
	response = requests.get(url=f'{rest_url}resources?offset={offset}&limit=100',
                          headers=header_get,
                          verify=False)
  # convert the response into a JSON structure
  json_data = response.json()
  # test if the end of the list is reached
  if not json_data:
      # exit the loop
      break
  # fetch all the items of the reply
  for resource in json_data:
	  # get the ID of the resource
	  sci_id = resource['id']
	  status = resource['status']
	  if status == 'ACTIVE':
		  # patch the resource
		  # todo
	  
	# next page of 100 resources
	offset += LIMIT
	  
	  
print('end of process. bye.')
	  
	

Il y a plusieurs choses essentielles à comprendre

Il est temps de mettre à jour les ressources.

La dernière chose à faire est d’écrire la partie patch qui sera insérée où nous avons écrit 'todo. ' L’ID de la ressource à patcher a été stocké dans une variable appelée sci_id, les instructions ont été définies dans la variable appelée data.

# patches the resource
response = requests.patch(
            url=f'{rest_url}resources/{sci_id}',
            headers = header_patch,
            json = data,
            verify = False)
        if response.status_code != 204:
		        # inform in case of errors
            print(f'{json.loads(response.text)["message"]}')
        else:
            # sucess confirmation 
            print(f'{resource["last_name"]} updated')

Encore une fois, voici quelques explications.

Conclusion et résumé

Voici le script complet de bout en bout proposé. C’est assez simple, mais c’est votre première étape dans l’utilisation de l’API Rest de Sciforma.

Nous avons encore beaucoup de choses à découvrir ! J’ai déjà mentionné les autres types de requêtes : UPDATE, POST et DELETE. Saviez-vous que le traitement des données du projet nécessite l’obtention d’un ID caché qui ne peut pas être affiché avec l’interface utilisateur HTML ? Nous verrons comment obtenir et utiliser cet ID.

Et nous allons travailler avec des cas d’utilisation encore plus utiles : nous allons parler de

Alors restez à l’écoute!

import  json, requests

token_url = 'https://YOUR_DOMAIN.sciforma.net/oauth2/token'
rest_url = 'https://YOUR_DOMAIN.sciforma.net/sciforma/rest/'

header_token = {
	 'Content-type': 'application/x-www-form-urlencoded',
}

# get the token
body = {
	'client_id': YOUR_CLIENT_ID,
	'client_secret': YOUR_CLIENT_SECRET,
    'grant_type': 'client_credentials',
    'scope': 'resources:read resources:write',
     }
response = requests.post(url=token_url,
                         headers=header_token,
                         verify=False,
                         data=body)
token = response.json()['access_token']

# define the GET header
header_get = {
        'Content-type': 'application/json',
        'Authorization': f'Bearer {token}',
        'Cache-Control': 'no-cache'
    }

# define the PATCH header
header_patch = {
        'Content-type': 'application/vnd.sciforma.v1+merge-patch+json',
        'Authorization': f'Bearer {token}',
        'Cache-Control': 'no-cache'
    }

LIMIT = 100
offset = 0

# prepare the data to write to the resources
data = {
    'Middle Name': 'TEST',
}

i= 0
while True:
    # reads the 'page' of resources
    response = requests.get(url=f'{rest_url}resources?offset={offset}&limit=100',
                            headers=header_get,
                            verify=False)
    # convert the response into a JSON structure
    json_data = response.json()
    # test if the end of the list is reached
    if not json_data:
        # exit the loop
        break
    # fetch all the items of the reply
    for resource in json_data:
        # get the ID of the resource
        sci_id = resource['id']
        status = resource['status']
        if status == 'ACTIVE':
            # patches the resource
            response = requests.patch(
                url=f'{rest_url}resources/{sci_id}',
                headers=header_patch,
                json=data,
                verify=False)
            if response.status_code != 204:
                # inform in case of errors
                print(f'{json.loads(response.text)["message"]}')
            else:
                # success confirmation
                print(f'{resource["last_name"]} updated')

    # next page of 100 resources
    offset += LIMIT

print('end of process. bye.')