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呼叫,
本章內容如下:
- 通過XML-RPC實作登錄odoo
2. 通過XML-RPC獲取和讀取資料(未完成)
3. 通過XML-RPC創建、更新、洗掉資料(未完成)
4. 通過XML-RPC呼叫函式(未完成) - 通過JSON-RPC登錄odoo
6. 通過JSON-RPC過濾及搜索資料
7. 通過JSON-RPC創建、更新、洗掉資料
8. 通過JSON-RPC呼叫函式 - OCA的odoorpc庫(超好用)
- 生成API key
技術需求
本章,我們將使用第十九章的my_library模塊,可見GitHub repository: https://github.com/ PacktPublishing/Odoo-12-Development-Cookbook-Third-Edition/tree/master/Chapter19/r0_initial_module.
假設你已經有一個在運行的odoo實體,http://localhost:8069,使用名為book-db-14的資料庫,安裝了名為my_library的模塊,
通過XML-RPC實作登錄odoo
本節,我們通過RPC實作用戶驗證并檢查用戶憑證是否有效,
準備
步驟
- 添加odoo_authenticate.py檔案,放在哪里隨意,
- 添加代碼
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")
- 運行檔案
python3 odoo_authenticate.py
原理
本節,我們通過python的xmlrpc包實作訪問odoo實體,這是python自帶的標準包,不用額外安裝,
odoo提供/xmlrpc/2/common節點用于XML-RPC呼叫,此端點用于不需要身份驗證的元方法,authentication()方法本身是一個公共方法,因此可以公開呼叫它,authentication()方法接受四個引數——資料庫名稱、用戶名、密碼和用戶代理環境,用戶代理環境是一個強制引數,但是如果您不想傳遞用戶代理引數,至少要傳遞空字典,
當您使用所有有效引數執行authenticate()方法時,它將呼叫Odoo服務器并執行身份驗證,然后,如果給定的登錄ID和密碼是正確的,它將回傳用戶ID,如果用戶不存在或者密碼不正確,則回傳False,
在通過RPC訪問任何資料之前,您需要使用authenticate()方法,這是因為使用錯誤的憑據訪問資料將產生錯誤,
小貼士
Odoo的在線實體(*.odoo.com)使用OAuth認證,
因此,本地密碼沒有在實體上設定,要在這些實體上使用XML-RPC,您需要從實體的Settings | Users | Users選單手動設定用戶的密碼,
此外,用于訪問資料的方法需要用戶ID,而不是用戶名,因此需要使用authenticate()方法來獲取用戶ID,
更多
/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實作登錄及獲取資料,
準備
步驟
- 添加jsonrpc_authenticate.py檔案
- 添加如下代碼:
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=https://www.cnblogs.com/xushuotec/p/payload, headers=headers)
user_id = response.json()["result"]
if user_id:
print("Success: User id is", user_id)
else:
print("Failed: wrong credentials")
- 運行引數
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=https://www.cnblogs.com/xushuotec/p/payload, headers=headers)
print(response.json())
結果如下:

通過JSON-RPC獲取及搜索資料
本節,我們將了解如何通過JSON-RPC獲取資料,
準備
步驟
- 添加jsonrpc_fetch_data.py檔案
- 添加代碼
# 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=https://www.cnblogs.com/xushuotec/p/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=https://www.cnblogs.com/xushuotec/p/payload, headers=headers).json() print('Books data:', res)
else:
print("Failed: wrong credentials")
- 運行腳本
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=https://www.cnblogs.com/xushuotec/p/payload, headers=headers).json() print('Books data:', res)
else:
print("Failed: wrong credentials")
通過JSON-RPC創建、更新、洗掉資料
本節,我們將學習如何通過RPC實作CRUD,
準備
步驟
- 添加jsonrpc_operation.py檔案
- 添加代碼
# place authentication and get_json_payload method (seelast recipe for more)
if user_id:
# creates the books records
create_data = https://www.cnblogs.com/xushuotec/p/[
{'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=https://www.cnblogs.com/xushuotec/p/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 = https://www.cnblogs.com/xushuotec/p/{'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=https://www.cnblogs.com/xushuotec/p/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=https://www.cnblogs.com/xushuotec/p/payload,headers=headers).json()
print("Books deleted:", res)
else:
print("Failed: wrong credentials")
- 運行
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=https://www.cnblogs.com/xushuotec/p/payload, headers=headers).json()
print("Has create access:", res['result'])
else:
print("Failed: wrong credentials")
結果如下:

通過JSON-RPC呼叫函式
本節,我們將學習如何通過JSON-RPC呼叫模型方法,比如,我們將呼叫圖書模型的make_available()方法改變圖書的狀態,
準備
步驟
- 添加jsonrpc_method.py檔案
- 添加代碼:
# 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=https://www.cnblogs.com/xushuotec/p/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=https://www.cnblogs.com/xushuotec/p/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=https://www.cnblogs.com/xushuotec/p/payload,headers=headers).json()
print("Book state after the method call:",res['result'])
else:
print("Failed: wrong credentials")
- 運行檔案
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
步驟
- 添加odoorpc_library.py檔案
- 添加代碼
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)
- 運行檔案
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包,如下:
- https://github.com/akretion/ooor
- https://github.com/OCA/odoorpc
- https://github.com/odoo/openerp-client-lib
- http://pythonhosted.org/OdooRPC
- https://github.com/abhishek-jaiswal/php-openerp-lib
生成API key
odoo14開始支持雙因素認證(Two-Factor Authentication, 2FA),2FA是用戶帳戶的額外安全層,用戶需要輸入密碼和基于時間的代碼,如果您已經啟用了2FA,那么您將不能通過輸入用戶ID和密碼來使用RPC,要解決這個問題,您需要為用戶生成一個API密鑰,本節,我們將看到如何生成API密鑰,
步驟
-
打開用戶首選項并打開帳戶安全選項卡,
-
點擊New API Key按鈕:

-
它將打開一個彈出視窗,如下圖所示,輸入API密鑰名和點擊Generate key按鈕:

-
這將生成API密鑰,并在一個新的彈出視窗中顯示它,記下API鍵,因為你還需要它:

一旦生成了API密鑰,您就可以開始以與普通密碼相同的方式為RPC使用API密鑰,
原理
使用API鍵很簡單,然而,有一些事情你需要注意,API密鑰是為每個用戶生成的,如果您希望為多個用戶使用RPC,則需要為每個用戶生成API密鑰,此外,用戶的API密鑰將擁有與用戶相同的訪問權限,因此如果某人獲得了密鑰的訪問權限,他們可以執行用戶可以執行的所有操作,因此,您需要對API密鑰保密,
小貼士
生成API密鑰時,只顯示一次,你得把這個鍵記下來,如果你失去了它,就沒有辦法再找回來了,在這種情況下,您需要洗掉API鍵并生成一個新的API鍵,
使用API密鑰非常簡單,在RPC呼叫期間,您只需要使用API密鑰而不是用戶密碼,即使激活了2FA,你也可以呼叫RPC,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/270818.html
標籤:其他
下一篇:等保常見問題
