How to Access Data from Odoo Website Through Odoo XML-RPC API and Python

Odoo API

Odoo is typically extended internally through modules, but many of its features and data are also accessible from the outside for external analysis or integration with various tools. A portion of the Models API is easily accessible via XML-RPC and can be accessed from a variety of languages.

Signing in

Odoo requires API users to be authenticated before they can query most data. The xmlrpc/2/common endpoint provides meta-calls that do not require authentication, such as authentication or retrieving version information. The simplest call to make to check if the connection information is correct before attempting to authenticate is to request the server’s version. The authenticate function performs the authentication and returns a user identifier (uid) that is used in authenticated calls instead of the login.

url = "url-of-your-website"
db ="your-database-name"
username = 'your-database-username'
password = 'your-database-password'

common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url)) 
common.version() 
uid = common.authenticate(db, username, password, {})

Calling Method

The second endpoint, xmlrpc/2/object, is used to call odoo model methods via the execute kw RPC function. Each call to execute kw requires the following parameters:

  • a string representing the database to be used
  • the user id (as obtained via authenticate), an integer
  • a string representing the user’s password
  • a string containing the model’s name
  • a string containing the method name
  • a set of parameters passed by position
  • a set of parameters to be passed by keyword (optional)
url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})

models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
models.execute_kw(db, uid, password,
    'res.partner', 'check_access_rights',
    ['read'], {'raise_exception': False})

List All Records

search() can be used to list and filter records. It accepts a mandatory domain filter (which can be empty) and returns the database identifiers of all records that match the filter. For example, here is a list of customer companies:

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models.execute_kw(db, uid, password,
    'res.partner', 'search',
    [[['is_company', '=', True]]])

Count records

Rather than retrieving and counting a potentially massive list of records, search count() can be used to retrieve only the number of records that match the query. It accepts the same domain filter as search() and no additional parameters.

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models.execute_kw(db, uid, password,
    'res.partner', 'search_count',
    [[['is_company', '=', True]]])

Read records

The read() method retrieves record data by passing a list of ids (as returned by search()) and optionally a list of fields to fetch. By default, it will retrieve all of the fields that the current user can read, which is usually a large number.

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
ids = models.execute_kw(db, uid, password,
    'res.partner', 'search',
    [[['is_company', '=', True]]],
    {'limit': 1})
[record] = models.execute_kw(db, uid, password,
    'res.partner', 'read', [ids])
# count the number of fields fetched by default
len(record)

Read Record Fields

Because it returns a large amount of meta-information (it is also used by client programs), it should be filtered before printing; the most interesting items for a human user are string (the field’s label), help (a help text if available), and type (to know which values to expect, or to send when updating a record):

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models.execute_kw(
    db, uid, password, 'res.partner', 'fields_get',
    [], {'attributes': ['string', 'help', 'type']})

Search and Read Records

Because this is a common task, Odoo provides a search read() shortcut, which is equivalent to a search() followed by a read() but avoids having to perform two requests and keep ids around. Its arguments are similar to search( )’s, but it can also take a list of fields (like read(), if that list is not provided it will fetch all fields of matched records):

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models.execute_kw(db, uid, password,
    'res.partner', 'search_read',
    [[['is_company', '=', True]]],
    {'fields': ['name', 'country_id', 'comment'], 'limit': 5})

Create a record

Create is used to create model records (). The method will generate a single record and return its database identifier. create() accepts a mapping of fields to values, which will be used to initialize the record. The default value will be used for any field that has a default value and is not set via the mapping argument.

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{
    'name': "New Partner",
}])

Update a Record.

write() takes a list of records to update and a mapping of updated fields to values, similar to create(). Multiple records can be updated at the same time, but they will all have the same values for the fields being set. At the moment, “computed” updates are not possible (where the value being set depends on an existing value of a record).

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models.execute_kw(db, uid, password, 'res.partner', 'write', [[id], {
    'name': "Newer partner"
}])
# get record name after having changed it
models.execute_kw(db, uid, password, 'res.partner', 'name_get', [[id]])

Delete a record.

By providing their ids to unlink() method, records can be deleted in bulk.

url = "https://odoo.nucleiotechnologies.com"
db ="nucleio"
username = '[email protected]'
password = 'NucleioTechno@2019'

import xmlrpc.client 
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models.execute_kw(db, uid, password, 'res.partner', 'unlink', [[id]])
# check if the deleted record is still in the database
models.execute_kw(db, uid, password,
    'res.partner', 'search', [[['id', '=', id]]])

References:

https://www.odoo.com/documentation/15.0/developer/misc/api/odoo.html

https://1.bp.blogspot.com/-OsCdt6CSyh4/XZQz65jGeGI/AAAAAAAABK4/ck343G40pXo-K0wDx_IUjUl3Lp5UEUHsACNcBGAsYHQ/w1200-h630-p-k-no-nu/xml-rpc.jpg

Leave a Comment

Your email address will not be published. Required fields are marked *