Using the RPC API

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.

How to do it…

The following code is not meant to run within Odoo, but as simple scripts:

  1. First, we query the list of installed modules via XMLRPC:
    #!/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']
  2. Then we do the same with 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.

How it works…

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.

XMLRPC

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.

JSONRPC

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.

There's more…

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.

See also

The most interesting business methods to call on models are explained in Chapter 5, Basic Server Side Business Logic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.161.161