One of Odoo's strengths is its interoperability, which is helped by the fact that basically any functionality is available via JSON-RPC 2.0 and XMLRPC. In this recipe, we'll explore how to use both of them from client code. This interface also enables you to integrate Odoo with any other application. Making functionality available via any of the two protocols on the server side is explained in the There's more section of this recipe.
We'll query a list of installed modules from the Odoo instance, so that we could show a list like the one displayed in the previous recipe in our own application or website.
The following code is not meant to run within Odoo, but as simple scripts:
#!/usr/bin/env python2 import xmlrpclib db = 'odoo9' user = 'admin' password = 'admin' uid = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/2/common') .authenticate(db, user, password, {}) odoo = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/2/object') installed_modules = odoo.execute_kw( db, uid, password, 'ir.module.module', 'search_read', [[('state', '=', 'installed')], ['name']], {'context': {'lang': 'fr_FR'}}) for module in installed_modules: print module['name']
JSONRPC
:import json import urllib2 db = 'odoo9' user = 'admin' password = 'admin' request = urllib2.Request( 'http://localhost:8069/web/session/authenticate', json.dumps({ 'jsonrpc': '2.0', 'params': { 'db': db, 'login': user, 'password': password, }, }), {'Content-type': 'application/json'}) result = urllib2.urlopen(request).read() result = json.loads(result) session_id = result['result']['session_id'] request = urllib2.Request( 'http://localhost:8069/web/dataset/call_kw', json.dumps({ 'jsonrpc': '2.0', 'params': { 'model': 'ir.module.module', 'method': 'search_read', 'args': [ [('state', '=', 'installed')], ['name'], ], 'kwargs': {'context': {'lang': 'fr_FR'}}, }, }), { 'X-Openerp-Session-Id': session_id, 'Content-type': 'application/json', }) result = urllib2.urlopen(request).read() result = json.loads(result) for module in result['result']: print module['name']
Both code snippets will print a list of installed modules, and because they pass a context that sets the language to French, the list will be in French if there are translations available.
Both snippets call the function search_read
, which is very convenient because you can specify a search domain on the model you call, pass a list of fields you want to be returned, and receive the result in one request. In older versions of Odoo, you had to call search
first to receive a list of IDs and then call read
to actually read the data.
search_read
returns a list of dictionaries, with the keys being the names of the fields requested and the values the record's data. The ID field will always be transmitted, no matter if you requested it or not.
Now we need to look at the specifics of the two protocols.
The XMLRPC API expects a user ID and a password for every call, which is why we need to fetch this ID via the method authenticate
on the path /xmlrpc/2/common
. If you already know the user's ID, you can skip this step.
As soon as you know the user's ID, you can call any model's method by calling execute_kw
on the path /xmlrpc/2/object
. This method expects the database you want to execute the function on, the user's ID and password for authentication, then the model you want to call your function on, and then the function's name. The next two mandatory parameters are a list of positional arguments to your function, and a dictionary of keyword arguments.
Don't be distracted by the size of the code example; that's because Python doesn't have built in support for JSONRPC. As soon as you've wrapped the urllib
calls in some helper functions, the example will be as concise as the XMLRPC one.
As JSONRPC is stateful, the first thing we have to do is to request a session at /web/session/authenticate
. This function takes the database, the user's name, and their password.
The crucial part here is that we record the session ID Odoo created, which we pass in the header X-Openerp-Session-Id
to /web/dataset/call_kw
. Then the function behaves the same as execute_kw
from; we need to pass a model name and a function to call on it, then positional and keyword arguments.
Both protocols allow you to call basically any function of your models. In case you don't want a function to be available via either interface, prepend its name with an underscore – Odoo won't expose those functions as RPC calls.
Furthermore, you need to take care that your parameters, as well as the return values, are serializable for the protocol. To be sure, restrict yourself to scalar values, dictionaries, and lists.
As you can do roughly the same with both protocols, it's up to you which one to use. This decision should be mainly driven by what your platform supports best. In a web context, you're generally better off with JSON, because Odoo allows JSON handlers to pass a CORS header conveniently (see the Make a path accessible from the network recipe of this chapter for details). This is rather difficult with XMLRPC.
The most interesting business methods to call on models are explained in Chapter 5, Basic Server Side Business Logic.
3.12.161.161