url = "https://demo.taskflow.co.za"
db = "demo.taskflow.co.za"
username = "demo"
password = "demo"

Logging in

Authentication is required before data manipulation is allowed on most data.

The xmlrpc/2/common endpoint provides meta-calls which don't require authentication, such as the authentication itself or fetching version information. To verify if the connection information is correct before trying to authenticate, the simplest call is to ask for the server's version. The authentication itself is done through the authenticate function and returns a user identifier (uid) used in authenticated calls instead of the login.

common = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(url))

The version() call will output the data below.

	"server_version": "9.0",
	"server_version_info": [9, 0, 0, "final", 0],
	"server_serie": "9.0",
	"protocol_version": 1,

Use the authenticate() method to retrieve the uid which you will use in later calls.

uid = common.authenticate(db, username, password, {})

Manipulating Data

Create Record

Records of a model are created using create(). The method will create a single record and return its database identifier.

create() takes a mapping of fields to values, used to initialize the record. For any field which has a default value and is not set through the mapping argument, the default value will be used.

models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))
id = models.execute_kw(db, uid, password, 'crm.lead', 'create', [{ 'name': "New Lead", }])

The create() method will return the database ID of the newly created record.



While most value types are what would be expected (integer for Integer, string for Char or Text),

  • Date, Datetime and Binary fields use string values
  • One2many and Many2many use a special command protocol

Edit Record

Records can be updated using write(), it takes a list of records to update and a mapping of updated fields to values similar to create().

Multiple records can be updated simultaneously, but they will all get the same values for the fields being set. 

models.execute_kw(db, uid, password, 'crm.lead', 'write', [[id], { 'name': "Lead Edited" }])
# get record name after having changed it
models.execute_kw(db, uid, password, 'crm.lead', 'name_get', [[id]])
[[78, "Lead Edited"]]

Upload Large Batches

When uploading large amounts of data on a regular basis, it is preferred to use the "load" method.

Adding an ID column to your import will be treated as an "External ID", and therefore a link between outside data and records within TaskFlow.

This provides two possible uses:

  • Creating new records, if id does not exist
  • Updating records, if the id exists

It is recommended to always generate an id for each record to enable future manipulation of data

models.execute_kw(db, uid, password, 'crm.lead', 'load', [
    # Header
    ['id', 'name', 'contact_name', 'contact_surname', 'phone', 'mobile', 'fax'],
    # Data  
        ['my_lead.external_id1', 'Lead 1', 'John', 'Snow', '27830001234', '27821114321', ''],
        ['my_lead.external_id2', 'Lead 2', 'Luke', 'Skywalker', '27849991234', '277771234', '27123456789'],