Remote Procedure Calls (RPC) in Odoo 18: Using JSON-RPC

Remote Procedure Calls (RPC) are a powerful way to interact with Odoo from external systems. In Odoo 18, just like earlier versions, JSON-RPC remains one of the most efficient and lightweight ways to remotely call Odoo methods using Python or any other language that can send HTTP requests and handle JSON.

What is JSON-RPC?

JSON-RPC is a stateless, lightweight remote procedure call protocol encoded in JSON. It allows you to send commands or queries to a remote server and get results, without needing to keep an open connection or session. Since JSON is easily readable and widely used in web and app development, JSON-RPC is a practical choice for communicating with the Odoo backend.

Compared to XML-RPC, JSON-RPC is more concise and faster, especially over HTTP.

Connecting to Odoo with JSON-RPC

To connect to Odoo 18 using JSON-RPC, you need to define a method that sends a properly formatted JSON payload to the /jsonrpc endpoint.

Here’s a simple Python example:

import json
import random
import urllib.request

host = 'localhost'
port = 8018  # update this if your Odoo port is different
database = 'Demo'
user = 'admin'
password = 'admin'

def json_rpc(url, method, params):
    data = {
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": random.randint(0, 1000000000),
    }
    req = urllib.request.Request(
        url=url,
        data=json.dumps(data).encode(),
        headers={"Content-Type": "application/json"},
    )
    response = urllib.request.urlopen(req).read()
    reply = json.loads(response.decode("UTF-8"))
    if reply.get("error"):
        raise Exception(reply["error"])
    return reply["result"]

def call(url, service, method, *args):
    return json_rpc(url, "call", {
        "service": service,
        "method": method,
        "args": args
    })

url = f"http://{host}:{port}/jsonrpc"
uid = call(url, "common", "login", database, user, password)
print(f"User ID: {uid}")

Reading Records via JSON-RPC

Once authenticated, you can fetch records from any model. Here's how you can read a record from the project.task model:

task_data = call(
    url, "object", "execute", database, uid, password,
    "project.task", "read", [1]
)
print("Task Data:", task_data)

Parameters:

  • database: Your database name
  • uid: The logged-in user's ID
  • password: The user's password
  • model: The model to operate on (e.g., "project.task")
  • method: The method to execute (e.g., "read")
  • ids: List of record IDs to read

Searching and Reading (search_read)

To find and fetch records in one go, use search_read:

task_data = call(
    url, "object", "execute", database, uid, password,
    "project.task", "search_read",
    [[['name', 'ilike', 'Office']]],
    ["id", "name", "stage_id"]
)
print(task_data)

This returns all tasks with names containing "Office".

Creating Records

To create a new project and a corresponding task:

project_data = {'name': 'New Project via JSON-RPC'}
project_id = call(url, "object", "execute", database, uid, password, "project.project", "create", project_data)

if project_id:
    task_data = {
        'name': 'Initial Task',
        'project_id': project_id
    }
    task_id = call(url, "object", "execute", database, uid, password, "project.task", "create", task_data)

Updating Records

Use the write method to update an existing record:

update_data = {'name': 'Updated Project Name'}
call(url, "object", "execute", database, uid, password, "project.project", "write", [project_id], update_data)

Note: The record must exist and be accessible to the user.

Deleting Records

You can delete a record using the unlink method:

call(url, "object", "execute", database, uid, password, "project.project", "unlink", [project_id])

Make sure you pass a list of IDs, even if you're deleting just one record.

Calling Custom Methods

In Odoo, you can also call your custom methods defined in a model, as long as they are exposed through the API:

result = call(
    url, "object", "execute", database, uid, password,
    "your.model.name", "your_method_name", [arg1, arg2]
)

Tip: Methods must not be private (no underscore prefix) and must not raise access errors.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message