Development Book V17:Remote Procedure Calls (RPC)

JSON-RPC

JSON, short for JavaScript Object Notation, is a widely used data format in apps and APIs. Its key advantage lies in its ease of writing, parsing, reading, and interpretation.

For Python method calls from a distance, RPC (Remote Procedure Call) is an option. JSON-RPC, a lightweight protocol, facilitates these remote procedure calls without maintaining a state. This specification outlines data structures and their processing rules. It's versatile, working across processes, sockets, HTTP, and various message passing systems.

The json-rpc API method in Odoo enables remote connections to the Odoo server. This RPC utilizes JSON encoding and is similar to XML-RPC but significantly lighter. Unlike XML-RPC, it doesn't require a response to transmit data to the server.

Connection to Odoo

Let's analyze how to connect to Odoo using the json-rpc method.

import json
import json
import random
import urllib.request
host = 'localhost'
port = 8017
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",
   })
   reply = json.loads(urllib.request.urlopen(req).read().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 = "http://%s:%s/jsonrpc" % (host, port)
uid = call(url, "common", "login", database, user, password)
print(uid)
(Py3.6_venv) cybrosys@cybrosys:~/json-rpc$ python3 json-test.py

This will give output as the ID of the user.

url: Specifying the URL of JSON-RPC with host and port number

service: Set the service as common

method: Set the method as login

args: Pass the argument as given below:

database: name of database

user: login user id

password: password of user

Search/ Read Records

We can use JSON RPC to get and handle data in a database. This method makes it easy to fetch, search, and read data from the database smoothly.

import json
import random
import urllib.request
host = 'localhost'
port = 8017
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",
   })
   reply = json.loads(urllib.request.urlopen(req).read().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 = "http://%s:%s/jsonrpc" % (host, port)
uid = call(url, "common", "login", database, user, password)
task_ids = call(url, "object", "execute", database, uid, password, "project.task", "read", [1])
print("Tasks: ", task_ids)

Specify the JSON-RPC URL by providing the host and port number.

Define the service as an object.

Set the method to "execute."

Pass the following arguments:

  • "database": the name of the database
  • "uid": the user ID
  • "password": the user's password
  • "model_name": the name of the model
  • "method": set it to "read" to invoke the read method
  • "ids": a list of IDs for which data should be read

The output will be:

python3 json-test.py
Tasks:  [{'id': 1, 'rating_ids': [], 'rating_last_value': 0.0, 'rating_last_feedback': False, 'rating_last_image': False, 'rating_count': 0, 
'rating_avg': 0.0, 'rating_avg_text': 'none', 'rating_percentage_satisfaction': -1.0, 'rating_last_text': False, 'activity_ids': [], 
'activity_state': False, 'activity_user_id': False, 'activity_type_id': False, 'activity_type_icon': False, 'activity_date_deadline': False, 'my_activity_date_deadline': False, 
'activity_summary': False, 'activity_exception_decoration': False, 'activity_exception_icon': False, 'message_is_follower': True, 'message_follower_ids': [29, 30, 31], 'message_partner_ids': [3, 7], 'message_ids': [45], 'has_message': True, 'message_needaction': False, 'message_needaction_counter': 0, 'message_has_error': False, 'message_has_error_counter': 0, 
'message_attachment_count': 0, 'message_main_attachment_id': False, 'website_message_ids': [], 'message_has_sms_error': False, 'email_cc': False, 'access_url': '/my/tasks/1', 'access_token': '4c36bc36-f60a-4da8-9aa3-c81e05a7079a', 'access_warning': '', 'active': True, 'name': 'Office planning', 'description': False, 'priority': '0', 'sequence': 20, 'stage_id': [3, 'Done'], 'tag_ids': [], 'kanban_state': 'normal', 
'kanban_state_label': 'In Progress', 'create_date': '2022-06-05 07:29:59', 'write_date': '2022-11-05 07:29:55', 'date_end': '2022-11-05 07:29:59', 'date_assign': False, 'date_deadline': False, 
'date_last_stage_update': '2022-11-05 07:29:59', 'project_id': [1, 'Office Design'], 'task_properties': [], 'display_project_id': [1, 'Office Design'], 'planned_hours': 20.0, 'subtask_planned_hours': 0.0, 'user_ids': [], 'portal_user_names': '', 'personal_stage_type_ids': [], 'personal_stage_id': False, 'personal_stage_type_id': False, 
'partner_id': [8, 'YourCompany, Joel Willis'], 'partner_is_company': False, 
'commercial_partner_id': [8, 'YourCompany, Joel Willis'], 'partner_email': 'joel.willis63@example.com',
 'partner_phone': '(683)-556-5104', 'partner_city': 'Bayonne', 'manager_id': [6, 'Marc Demo'], 'company_id': [1, 'YourCompany'], 'color': 7, 
 'project_color': 3, 'rating_active': False, 'attachment_ids': [], 'displayed_image_id': False, 'legend_blocked': 'Blocked', 'legend_done': 'Ready', 'legend_normal': 'In Progress', 'is_closed': True, 'parent_id': False, 'ancestor_id': False, 'child_ids': [], 'child_text': False, 'allow_subtasks': False, 'subtask_count': 0, 
 'email_from': 'joel.willis63@example.com', 'project_privacy_visibility': 'portal', 'working_hours_open': 0.0, 
'working_hours_close': 880.0, 'working_days_open': 0.0, 'working_days_close': 110.0, 'is_private': False,
 'allow_milestones': True, 'milestone_id': [1, 'First Phase'], 'has_late_and_unreached_milestone': False, 
 'allow_task_dependencies': False, 'depend_on_ids': [], 'dependent_ids': [], 'dependent_tasks_count': 0, 'is_blocked': False, 'display_parent_task_button': False, 
 'allow_recurring_tasks': False, 'recurring_task': False, 'recurring_count': 0, 'recurrence_id': False, 'recurrence_update': 'this', 'recurrence_message': False, 'repeat_interval': 0, 'repeat_unit': False, 'repeat_type': False, 
 'repeat_until': False, 'repeat_number': 0, 'repeat_on_month': False, 'repeat_on_year': False, 'mon': False, 'tue': False, 'wed': False, 'thu': False, 'fri': False, 'sat': False, 'sun': False, 'repeat_day': False, 
 'repeat_week': False, 'repeat_weekday': False, 'repeat_month': False, 'repeat_show_dow': False, 'repeat_show_day': False, 'repeat_show_week': False, 'repeat_show_month': False, 'analytic_account_id': [19, 
'Office Design'], 'is_analytic_account_id_changed': False, 
'project_analytic_account_id': [19, 'Office Design'], '__last_update': '2022-11-05 07:29:55', 'display_name': 'Office planning', 
'create_uid': [1, 'OdooBot'], 'write_uid': [1, 'OdooBot']}]

To utilize the search read method, it is necessary to substitute the task IDs with the provided values.

task_ids = call(url, "object", "execute", database, uid, password, "project.task", "read", [1])

Create Records

Creating records in the database is achievable through JSON-RPC.

Here's the process for creating a record:

URL: Indicate the JSON-RPC URL by including the host and port number.

service: Define the service as an object.

method: Set the method to "execute."

args: Provide the necessary arguments for creating records.

project_args = {
    'name': 'JSON_RPC Project 3'
}
project_id = call(url, "object", "execute", database, uid, password, "project.project", "create", project_args)
#Create task only if project is created
if project_id:
  task_args = {
      'name': 'JSON_RPC Task 1',
      'project_id': project_id
  }
  task_id = call(url, "object", "execute", database, uid, password, "project.task", "create", task_args)

The screenshot below shows the project and task created.

odoo-development

Update Records

project_args = {
  'name': 'JSON_RPC Project 3'
}
project_args_update = {
       'name': 'JSON_RPC Project updated'
   }
project_id = call(url, "object", "execute", database, uid, password, "project.project", "create", project_args)
#Create task only if project is created
if project_id:
  project_update = call(url, "object", "execute", database, uid, password, "project.project", "write",project_id ,project_args_update)

It is used to update the records.

odoo-development

Delete Record

project_args = {
  'name': 'JSON_RPC Project 3'
}
project_id = call(url, "object", "execute", database, uid, password, "project.project", "create", project_args)
#Create task only if project is created
if project_id:
  project_update = call(url, "object", "execute", database, uid, password, "project.project", "unlink", [project_id] )

The record created through JSON-RPC can be deleted by employing the "unlink" method.

Calling Method

import json
import json
import random
import urllib.request
host = 'localhost'
port = 8017
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",
   })
   reply = json.loads(urllib.request.urlopen(req).read().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 = "http://%s:%s/jsonrpc" % (host, port)
uid = call(url, "common", "login", database, user, password)
print(uid)

Specify the URL by including the host and port. Provide details such as the database name, user login, and password. Utilize the "service" and "common" with the "method" set to "login" to establish a connection with the Odoo database.

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