Skip to Content

Odoo 20 : migrer de XML-RPC vers l’API JSON-2 en Python

XML-RPC et JSON-RPC sont dépréciés depuis Odoo 19, et Odoo 20 pousse l'API JSON-2 comme interface externe officielle. Ce tutoriel montre, avec du code Python, comment convertir vos appels existants en quatre étapes, et quoi vérifier avant de basculer.
Développement OdooNiveau intermédiaireOdoo 20Python

En bref

  • Nouveau modèle : un POST vers /json/2/<modèle>/<méthode>, une clé API, un corps JSON.
  • À faire : convertir vos scripts un par un, sur une copie de la base.
  • À vérifier : les changements incompatibles d'Odoo 20 et l'accès à l'API selon votre forfait.

Pourquoi migrer vos intégrations XML-RPC maintenant ?

Si un script, un connecteur ou un outil maison lit ou écrit dans Odoo par XML-RPC, il repose sur un mécanisme que l'éditeur retire par étapes. Voici le calendrier, tel que nous le comprenons à partir de la documentation officielle.

PointStatutDétail
XML-RPC et JSON-RPCConfirméDépréciés depuis Odoo 19.
Service dbConfirméRetiré dans Odoo 20.
Points d'entrée common et objectConfirméRetrait prévu pour Odoo 22.
API JSON-2 (/json/2/)ConfirméRemplaçante officielle, appels HTTP POST avec clé API.
Liste complète des changements incompatibles entre Odoo 19 et 20À vérifierNon confirmée de notre côté. Lisez les notes de version officielles avant de migrer.
Accès à l'API externe selon le forfait Odoo OnlineÀ vérifierLa documentation d'Odoo 19 réserve l'API aux forfaits Custom. Confirmez pour Odoo 20.

Avant de commencer

Travaillez toujours sur une copie de la base de données, jamais sur la production. Les exemples ci-dessous créent et suppriment des enregistrements.

Quels sont les prérequis ?

  • Une instance Odoo 20 (ou une copie de test de votre base)
  • Un utilisateur dédié à l'intégration, avec seulement les droits nécessaires
  • Une clé API générée pour cet utilisateur
  • Python 3 et la bibliothèque requests (pip install requests)

Pour la clé API, ouvrez les préférences de l'utilisateur d'intégration et cherchez la section de sécurité du compte. Les libellés exacts peuvent varier d'une version à l'autre : vérifiez-les dans votre instance. Copiez la clé tout de suite, elle ne sera plus affichée.

Bonne pratique

Créez un utilisateur technique par intégration plutôt que d'utiliser un compte de personne. Si un accès doit être révoqué, vous ne touchez qu'à une seule clé.

Étape 1 : comment faire un premier appel JSON-2 ?

Un appel JSON-2 suit toujours le même modèle : une requête POST vers /json/2/<modèle>/<méthode>, la clé API dans Authorization, et les arguments de la méthode dans le corps JSON. Testons-le d'abord avec curl.

terminalbash
curl -X POST "https://mon-odoo.example.com/json/2/res.partner/search_read" \
  -H "Authorization: bearer VOTRE_CLE_API" \
  -H "X-Odoo-Database: ma_base" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"domain": [["is_company", "=", true]], "fields": ["name", "email"], "limit": 5}' 

Si tout est bien configuré, la réponse est une liste JSON de cinq contacts au plus. Passons maintenant à Python, avec une petite fonction réutilisable.

odoo_json2.pypython
import requests

BASE_URL = "https://mon-odoo.example.com"
API_KEY = "VOTRE_CLE_API"
DB = "ma_base"

session = requests.Session()
session.headers.update({
    "Authorization": f"bearer {API_KEY}",
    "X-Odoo-Database": DB,
    "Content-Type": "application/json; charset=utf-8",
})

def call(model, method, **payload):
    """Appelle une méthode d'un modèle via l'API JSON-2."""
    r = session.post(f"{BASE_URL}/json/2/{model}/{method}", json=payload, timeout=30)
    r.raise_for_status()
    return r.json()

contacts = call(
    "res.partner", "search_read",
    domain=[["is_company", "=", True]],
    fields=["name", "email"],
    limit=5,
)
print(contacts)

À retenir

Il n'y a plus d'étape d'authentification qui renvoie un identifiant d'utilisateur. La clé API dans l'en-tête suffit à chaque appel.

Étape 2 : comment créer, modifier et supprimer des enregistrements ?

Les méthodes classiques de l'ORM s'appellent de la même façon. Les arguments portent leur nom dans le corps JSON : vals_list pour créer, ids et vals pour modifier, ids pour supprimer.

odoo_json2.py (suite)python
# Créer un contact (vals_list est une liste de dictionnaires)
nouveaux = call("res.partner", "create", vals_list=[{"name": "Client test API"}])
partner_id = nouveaux[0]
print("Créé :", partner_id)

# Modifier ce contact
call("res.partner", "write", ids=[partner_id], vals={"phone": "514 555 0100"})

# Relire le résultat
print(call("res.partner", "search_read",
           domain=[["id", "=", partner_id]],
           fields=["name", "phone"]))

# Supprimer le contact de test
call("res.partner", "unlink", ids=[partner_id])

Vérifiez dans votre version

La forme exacte des réponses peut varier selon la méthode appelée. Affichez toujours la réponse brute lors de vos premiers tests plutôt que de supposer sa structure.

Étape 3 : comment convertir un appel XML-RPC existant ?

Voici un appel typique en XML-RPC. Il demande deux requêtes distinctes (authentification, puis appel) et passe les arguments par position.

avant : xmlrpc_legacy.pypython
import xmlrpc.client

url, db, user, password = "https://mon-odoo.example.com", "ma_base", "api@exemple.com", "motdepasse"

common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
uid = common.authenticate(db, user, password, {})

models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
partners = models.execute_kw(
    db, uid, password,
    "res.partner", "search_read",
    [[["is_company", "=", True]]],
    {"fields": ["name", "email"], "limit": 5},
)

Le même appel en JSON-2 devient une seule requête, avec des arguments nommés.

après : odoo_json2.pypython
partners = call(
    "res.partner", "search_read",
    domain=[["is_company", "=", True]],
    fields=["name", "email"],
    limit=5,
)
XML-RPCJSON-2
/xmlrpc/2/common puis /xmlrpc/2/objectUne seule route : /json/2/<modèle>/<méthode>
Authentification avec identifiant et mot de passe, puis uidClé API dans l'en-tête Authorization
Arguments par position dans args et kwargsArguments nommés dans le corps JSON
Base choisie dans chaque appelEn-tête X-Odoo-Database

Étape 4 : comment gérer les erreurs et plusieurs bases ?

Dans la fonction call, raise_for_status() transforme un statut HTTP d'erreur en exception Python. Le corps de la réponse contient le détail de l'erreur, utile à journaliser. Ajoutons-le proprement.

odoo_json2.py (version robuste)python
import requests

class OdooApiError(Exception):
    pass

def call(model, method, **payload):
    r = session.post(f"{BASE_URL}/json/2/{model}/{method}", json=payload, timeout=30)
    if not r.ok:
        raise OdooApiError(f"{r.status_code} sur {model}.{method} : {r.text[:500]}")
    return r.json()

Pour un serveur qui héberge plusieurs bases, gardez une session par base, chacune avec son en-tête X-Odoo-Database. Ne mettez jamais la clé API dans le code source : lisez-la depuis une variable d'environnement.

Sécurité

Une clé API donne les mêmes droits que l'utilisateur qui la porte. Limitez ses droits, changez-la périodiquement, et ne la versionnez jamais dans Git.

Comment planifier la bascule sans interrompre vos opérations ?

  • Lister tous les scripts, connecteurs et outils tiers qui appellent Odoo
  • Vérifier si chaque outil tiers offre déjà une version compatible JSON-2
  • Convertir vos propres scripts un par un et les tester sur une copie de la base
  • Comparer les résultats ancien et nouveau appel sur les mêmes données
  • Basculer en production en dehors des heures de pointe, avec un plan de retour

Les intégrations avec une boutique en ligne, un outil de paie ou un système d'expédition touchent souvent plusieurs modules à la fois. Si vous hésitez sur la portée du chantier, un partenaire Odoo peut en faire l'inventaire avec vous.

Une clé API, une route, des arguments nommés : JSON-2 simplifie l'intégration, à condition de convertir avant l'échéance.

Foire aux questions sur l'API JSON-2 d'Odoo 20

Qu'est-ce que l'API JSON-2 d'Odoo 20 ?

C'est l'API externe moderne d'Odoo. Chaque appel est une requête HTTP POST vers /json/2/<modèle>/<méthode>, avec une clé API en en-tête et les paramètres dans un corps JSON. Elle remplace progressivement XML-RPC et JSON-RPC.

XML-RPC fonctionne-t-il encore dans Odoo 20 ?

Les points d'entrée XML-RPC et JSON-RPC sont dépréciés depuis Odoo 19. Dans Odoo 20, le service db a été retiré, et le retrait de common et object est prévu pour Odoo 22. Vos intégrations existantes ne tombent donc pas toutes en même temps, mais il vaut mieux migrer avant l'échéance.

Faut-il un mot de passe pour utiliser l'API JSON-2 ?

Non. L'authentification se fait avec une clé API envoyée dans l'en-tête Authorization, sous la forme bearer suivi de la clé. Il n'y a plus d'appel d'authentification préalable pour obtenir un identifiant d'utilisateur.

Comment choisir la base de données avec JSON-2 ?

En ajoutant l'en-tête X-Odoo-Database avec le nom de la base, utile surtout quand le serveur héberge plusieurs bases.

L'API JSON-2 est-elle offerte sur Odoo Online ?

Selon la documentation d'Odoo 19, l'API externe est réservée aux forfaits Custom d'Odoo Online. Confirmez la situation de votre forfait pour Odoo 20 auprès d'Odoo ou de votre partenaire avant de bâtir une intégration.

Par où commencer pour migrer une intégration existante ?

Dressez la liste de vos appels XML-RPC, convertissez-les un à un en suivant le modèle search_read, create, write et unlink de ce tutoriel, puis testez sur une copie de la base avant de basculer la production.

Vos intégrations Odoo sont-elles prêtes pour Odoo 20 ?

On en fait l'inventaire avec vous et on convertit ce qui doit l'être, sans toucher à la production.

Parler à un expert Kuantiik

Sources

  1. Odoo, documentation de l'API externe (version 19), odoo.com
  2. Notes de version et calendrier de dépréciation d'Odoo 20 : à valider sur la documentation officielle avant toute migration
Vos intégrations Odoo reposent encore sur XML-RPC ? Parler à un expert
Une question sur la migration vers JSON-2 ?

On répond sous 24h ouvrées aux questions des entreprises québécoises.

Écrire à Kuantiik

Avant de partir

Demandez une évaluation de vos intégrations Odoo avant l'échéance XML-RPC.

Demander mon évaluation


Odoo 20 : payer ses factures fournisseurs depuis Odoo et prédiction des lignes de facture