【odoo14】第二十章、odoo的远程过程调用

odoo支持远程过程调用(RPC),你能够经过其余的应用链接odoo的实例。好比,咱们能够经过使用java编写的android应用链接odoo实例展现过时的订单信息。经过odoo的RPC API,咱们能够操做数据库的CURD。odoo的RPC不只仅局限于数据库的CURD,还支持对象的方法调用。odoo的RPC依然适用于odoo内部的权限管理机制。odoo的RPC适用于任意平台、任意语言调用。
odoo提供了两种类型RPC,XML-RPC和JSON-RPC。本章,咱们将学习如何使用RPC。最后,咱们将使用OCA的odoorpc包实现odoo的RPC调用。
本章内容以下:php

  1. 经过XML-RPC实现登陆odoo
    2. 经过XML-RPC获取和读取数据(未完成)
    3. 经过XML-RPC建立、更新、删除数据(未完成)
    4. 经过XML-RPC调用函数(未完成)
  2. 经过JSON-RPC登陆odoo
    6. 经过JSON-RPC过滤及搜索数据
    7. 经过JSON-RPC建立、更新、删除数据
    8. 经过JSON-RPC调用函数
  3. OCA的odoorpc库(超好用)
  4. 生成API key

技术需求

本章,咱们将使用第十九章的my_library模块。可见GitHub repository: https://github.com/ PacktPublishing/Odoo-12-Development-Cookbook-Third-Edition/tree/master/Chapter19/r0_initial_module.java

假设你已经有一个在运行的odoo实例,http://localhost:8069,使用名为book-db-14的数据库,安装了名为my_library的模块。python

经过XML-RPC实现登陆odoo

本节,咱们经过RPC实现用户验证并检查用户凭证是否有效。android

准备

步骤

  1. 添加odoo_authenticate.py文件,放在哪里随意。
  2. 添加代码
from xmlrpc import client

server_url = "http://localhost:8069"
db_name = "book-db-14"
username = "admin"
password = "admin"
common = client.ServerProxy("%s/xmlrpc/2/common" % server_url)
user_id = common.authenticate(db_name, username, password, {})
if user_id:
    print("Success: User id is", user_id)
else:
    print("Failed: wrong credentials")
  1. 运行文件
python3 odoo_authenticate.py

原理

本节,咱们经过python的xmlrpc包实现访问odoo实例。这是python自带的标准包,不用额外安装。git

odoo提供/xmlrpc/2/common节点用于XML-RPC调用。此端点用于不须要身份验证的元方法。authentication()方法自己是一个公共方法,所以能够公开调用它。authentication()方法接受四个参数——数据库名称、用户名、密码和用户代理环境。用户代理环境是一个强制参数,可是若是您不想传递用户代理参数,至少要传递空字典。github

当您使用全部有效参数执行authenticate()方法时,它将调用Odoo服务器并执行身份验证。而后,若是给定的登陆ID和密码是正确的,它将返回用户ID。若是用户不存在或者密码不正确,则返回False。sql

在经过RPC访问任何数据以前,您须要使用authenticate()方法。这是由于使用错误的凭据访问数据将产生错误。数据库

小贴士
Odoo的在线实例(*.odoo.com)使用OAuth认证,
所以,本地密码没有在实例上设置。要在这些实例上使用XML-RPC,您须要从实例的Settings | Users | Users菜单手动设置用户的密码。json

此外,用于访问数据的方法须要用户ID,而不是用户名,所以须要使用authenticate()方法来获取用户ID。api

更多

/xmlrpc/2/common端点提供了另外一个方法:version()。您能够在没有凭据的状况下调用此方法。它将返回Odoo实例的版本信息。version()方法的使用示例以下:

from xmlrpc import client
server_url = 'http://localhost:8069'
common = client.ServerProxy('%s/xmlrpc/2/common' % server_url)
version_info = common.version()
print(version_info)

输出以下

经过XML-RPC搜索和读取数据

经过XML-RPC建立、更新、删除数据

经过XML-RPC调用函数

经过JSON-RPC登陆odoo

odoo提供了JSON-RPC。正如其名,JSON-RPC使用JSOM格式,并经过jsonrpc2.0实现。本节,咱们将演示如何使用JSON-RPC实现登陆及获取数据。

准备

步骤

  1. 添加jsonrpc_authenticate.py文件
  2. 添加以下代码:
import json
import random
import requests

server_url = "http://localhost:8069"
db_name = "book-db-14"
username = "admin"
password = "admin"
json_endpoint = "%s/jsonrpc" % server_url
headers = {"Content-Type": "application/json"}


def get_json_payload(service, method, *args):
    return json.dumps(
        {
            "jsonrpc": "2.0",
            "method": "call",
            "params": {"service": service, "method": method, "args": args},
            "id": random.randint(0, 100000000),
        }
    )

payload = get_json_payload("common", "login", db_name, username, password)
response = requests.post(json_endpoint, data=payload, headers=headers)
user_id = response.json()["result"]
if user_id:
    print("Success: User id is", user_id)
else:
    print("Failed: wrong credentials")
  1. 运行参数
python3 jsonrpc_authenticate.py

结果以下:

原理

JSON-RPC使用JSON格式经过/jsonrpc端点与服务器交互数据。在咱们的例子中,咱们使用python的requests包发起post请求,固然,你也能够经过其余的包,好比urllib。
JSON-RPC仅支持JSON-RPC 2.0格式的数据负载。你可在https://www.jsonrpc.org/specification。在咱们的例子中,咱们新建了get_json_payload()方法。该方法负责将数据封装成JSON-RPC 2.0格式的负载。方法接受三个参数,service、method及可变参数。JSON-RPC请求体是以JSON格式的,同时请求头需包含{"Content-Type": "application/json"}。返回结果也是JSON格式的。

与XML-RPC相似,全部公开的方法都位于common服务中。所以,咱们以service=common,method=login准备负载。登陆函数须要额外的参数,包括数据库名称、帐户、密码。当咱们的帐户密码经过验证后,将获得用户的ID。

小贴士
get_json_payload()可实现代码复用。

更多

JSON-RPC一样支持version函数。咱们能够获取odoo实例的版本信息。以下:

import json
import random
import requests

server_url = 'http://localhost:8069'
json_endpoint = '%s/jsonrpc' % server_url
headers = {"Content-Type": "application/json"}

def get_json_payload(service, method, *args):
	...
payload = get_json_payload('common', 'version')
response = requests.post(json_endpoint, data=payload, headers=headers)

print(response.json())

结果以下:

经过JSON-RPC获取及搜索数据

本节,咱们将了解如何经过JSON-RPC获取数据。

准备

步骤

  1. 添加jsonrpc_fetch_data.py文件
  2. 添加代码
# place authentication and get_json_payload methods (see first jsonrpc recipe)
if user_id:
    # search for the book's ids
    search_domain = ['|', ['name', 'ilike', 'odoo'],['name', 'ilike', 'sql']]
    payload = get_json_payload("object", "execute_kw",db_name, user_id, password, 'library.book', 'search',[search_domain], {'limit': 5})
    res = requests.post(json_endpoint, data=payload,
        headers=headers).json() print('Search Result:', res)
    # ids will be in result keys
    # read data for books ids
    payload = get_json_payload("object", "execute_kw", db_name, user_id, password,'library.book', 'read', [res['result'],['name', 'date_release']])
    res = requests.post(json_endpoint, data=payload, headers=headers).json() print('Books data:', res)
else:
    print("Failed: wrong credentials")
  1. 运行脚本
python3 jsonrpc_fetch_data.py

结果以下:

原理

在上一节中,咱们经过JSON-RPC登陆系统并得到用户的ID。如今咱们能够经过用户的ID来获取模型数据了。咱们须要使用search及read来获取数据。为了获取数据,咱们调用了object做为service,execute_kw()做为method执行查询。execute_kw函数的参数以下:

  • 数据库的名称
  • 用户的ID
  • 密码
  • 模型名称
  • 方法名称
  • args,变量数组
  • kwargs,字典变量

在咱们的例子中,咱们调用了search方法。execute_kw()函数将强制变量做为位置变量,将可选变量做为关键字变量。在search方法中,domain是强制变量,可选变量Limit是关键字变量。
步骤2,咱们调用了read方法获取图书的详细信息。并将图书id的列表及字段的列表做为参数。

小贴士
咱们也可使用execute方法。该方法并不支持关键字变量,所以若是你想传递一些可选参数,你须要传递全部的中间参数。

更多

与XML-RPC相似,咱们可使用search_read()方法代替search()及read()方法的组合。以下:

# place authentication and get_json_payload methods (see firstjsonrpc recipe)
if user_id:
    # search and read for the book's ids 
    search_domain = ['|', ['name', 'ilike', 'odoo'],['name', 'ilike', 'sql']]
    payload = get_json_payload("object", "execute_kw", db_name, user_id, password, 'library.book', 'search_read', [search_domain, ['name', 'date_release']], {'limit': 5})
    res = requests.post(json_endpoint, data=payload, headers=headers).json() print('Books data:', res)
else:
    print("Failed: wrong credentials")

经过JSON-RPC建立、更新、删除数据

本节,咱们将学习如何经过RPC实现CRUD。

准备

步骤

  1. 添加jsonrpc_operation.py文件
  2. 添加代码
# place authentication and get_json_payload method (seelast recipe for more)
if user_id:
    # creates the books records 
    create_data = [
        {'name': 'Book 1', 'date_release':
        '2019-01-26'},
        {'name': 'Book 3', 'date_release':
        '2019-02-12'},
        {'name': 'Book 5', 'date_release':
        '2019-05-08'},
        {'name': 'Book 7', 'date_release':
        '2019-05-14'} ]
    payload = get_json_payload("object", "execute_kw",db_name, user_id, password, 'library.book','create', [create_data])
    res = requests.post(json_endpoint, data=payload,headers=headers).json() 
    print("Books created:", res) 
    books_ids = res['result']
    # Write in existing book record 
    book_to_write = books_ids[1]
    # We will use ids of recently created books 
    write_data = {'name': 'Book 2'}
    payload = get_json_payload("object", "execute_kw",db_name, user_id, password, 'library.book','write', [book_to_write, write_data])
    res = requests.post(json_endpoint, data=payload,headers=headers).json() 
    print("Books written:", res)
    # Delete in existing book record 
    book_to_unlink = books_ids[2:]
    # We will use ids of recently created books 
    payload = get_json_payload("object", "execute_kw", db_name, user_id, password, 'library.book', 'unlink', [book_to_unlink])
    res = requests.post(json_endpoint, data=payload,headers=headers).json() 
    print("Books deleted:", res)
else:
    print("Failed: wrong credentials")
  1. 运行
python3 jsonrpc_operation.py

结果以下:

若是操做成功,write和unlink方法返回True。这意味着,若是您的响应为True,则假定一条记录已被成功更新或删除。

原理

execute_kw()函数用于create、update和delete运算。自odoo12,create方法支持同时建立多条数据。

小贴士
当您尝试建立记录而没有为required字段提供值时,JSON-RPC和XML-RPC都会生成一个错误,所以请确保您已经将全部required字段添加到建立值中。

更多

与XML-RPC同样,您可使用JSON-RPC中的check_access_rights方法来检查您是否有执行该操做的访问权限。这个方法须要两个参数——模型名称和操做名称。在下面的示例中,咱们检查create操做的访问权限:

# place authentication and get_json_payload method (see lastrecipe for more)
if user_id:
    payload = get_json_payload("object", "execute_kw", db_name, user_id, password,'library.book', 'check_access_rights', ['create']) 
    res = requests.post(json_endpoint, data=payload, headers=headers).json()
    print("Has create access:", res['result'])
else:
    print("Failed: wrong credentials")

结果以下:

经过JSON-RPC调用函数

本节,咱们将学习如何经过JSON-RPC调用模型方法。好比,咱们将调用图书模型的make_available()方法改变图书的状态。

准备

步骤

  1. 添加jsonrpc_method.py文件
  2. 添加代码:
# place authentication and get_json_payload method (see last recipe for more)
if user_id:
    # Create the book in draft state
    payload = get_json_payload("object", "execute_kw",db_name, user_id, password,'library.book', 'create', [{'name': 'Book 1','state': 'draft'}])
    res = requests.post(json_endpoint, data=payload,headers=headers).json()
    print("Has create access:", res['result']) 
	book_id = res['result']
    # Change the book state by calling make_available
    # method
    payload = get_json_payload("object", "execute_kw",db_name, user_id, password,'library.book', 'make_available', [book_id]) 
    res = requests.post(json_endpoint, data=payload,headers=headers).json()
    # Check the book status after method call
    payload = get_json_payload("object", "execute_kw",db_name, user_id, password, 'library.book', 'read', [book_id,['name', 'state']])
    res = requests.post(json_endpoint, data=payload,headers=headers).json()
    print("Book state after the method call:",res['result'])
else:
    print("Failed: wrong credentials")
  1. 运行文件
python3 jsonrpc_method.py

前面的命令将使用draft建立一本书,而后经过调用make_available方法更改该书的状态。以后,咱们将获取图书数据来检查图书的状态,这将产生如下输出:

原理

execute_kw()可以调用模型的任何公共方法。正如咱们在经过XML-RPC配方调用方法中看到的,公共方法是那些名称不以_(下划线)开头的方法。以_开头的方法是私有的,你不能从JSON-RPC调用它们。
在咱们的示例中,咱们建立了一个状态为draft的书籍。而后,咱们再进行一次RPC调用来调用make_available方法,这将把该书的状态更改成available。最后,咱们再进行一次RPC调用来检查book的状态。这将显示该书的状态已更改成available,如图20.10所示。
不返回任何内容的方法在内部默认返回None。这些方法不能从RPC中使用。所以,若是您想使用来自RPC的方法,至少要添加return True语句。

OCA的odoorpc库(超好用)

OCA提供了名为odoorpc的包。可为咱们提供便捷的方式与odoo实例交互。安装odoorpc:

pip install OdooRPC

步骤

  1. 添加odoorpc_library.py文件
  2. 添加代码
import odoorpc

db_name = 'book-db-14'
user_name = 'admin'
password = 'admin'

# Prepare the connection to the server
odoo = odoorpc.ODOO('localhost', port=8069)
odoo.login(db_name, user_name, password) # login

# User information
user = odoo.env.user
print(user.name)
print(user.company_id.name)
print(user.email)

BookModel = odoo.env['library.book']
search_domain = ['|', ['name', 'ilike', 'odoo'], ['name', 'ilike', 'sql']]
books_ids = BookModel.search(search_domain, limit=5)
for book in BookModel.browser(books_ids):
	print(book.name, book.date_release)
	
# create the book and update the state
book_id = BookModel.create({'name': 'Test book', 'state': 'draft'})
print("Book state before make_available:", book.state) 
book = BookModel.browse(book_id)
book.make_available()
book = BookModel.browse(book_id)
print("Book state before make_available:", book.state)
  1. 运行文件
python3 odoorpc_library.py

结果以下:

原理

odoorpc在底层使用的jsonrpc实现与odoo的交互。

更多

odoorpc为咱们作了很是完美的封装,但咱们依然能够会用原生的RPC语法:

import odoorpc
db_name = 'book-db-14' 
user_name = 'admin' 
password = 'admin'
# Prepare the connection to the server
odoo = odoorpc.ODOO('localhost', port=8069) 
odoo.login(db_name, user_name, password) # login
books_info = odoo.execute('library.book', 'search_read', [['name', 'ilike', 'odoo']], ['name', 'date_release'])
print(books_info)

参考

还有几个其余的odoo rpc包,以下:

生成API key

odoo14开始支持双因素认证(Two-Factor Authentication, 2FA)。2FA是用户账户的额外安全层,用户须要输入密码和基于时间的代码。若是您已经启用了2FA,那么您将不能经过输入用户ID和密码来使用RPC。要解决这个问题,您须要为用户生成一个API密钥。本节,咱们将看到如何生成API密钥。

步骤

  1. 打开用户首选项并打开账户安全选项卡。

  2. 点击New API Key按钮:

  3. 它将打开一个弹出窗口,以下图所示。输入API密钥名和点击Generate key按钮:

  4. 这将生成API密钥,并在一个新的弹出窗口中显示它。记下API键,由于你还须要它:

一旦生成了API密钥,您就能够开始以与普通密码相同的方式为RPC使用API密钥。

原理

使用API键很简单。然而,有一些事情你须要注意。API密钥是为每一个用户生成的,若是您但愿为多个用户使用RPC,则须要为每一个用户生成API密钥。此外,用户的API密钥将拥有与用户相同的访问权限,所以若是某人得到了密钥的访问权限,他们能够执行用户能够执行的全部操做。所以,您须要对API密钥保密。

小贴士
生成API密钥时,只显示一次。你得把这个键记下来。若是你失去了它,就没有办法再找回来了。在这种状况下,您须要删除API键并生成一个新的API键。

使用API密钥很是简单。在RPC调用期间,您只须要使用API密钥而不是用户密码。即便激活了2FA,你也能够调用RPC。

相关文章
相关标签/搜索