我正在开发一个 Python Flask 应用程序,我需要使用 XML-RPC 或 JSON-RPC 从 Odoo 15 下载销售订单发票。但是,由于安全限制,我无法通过 SSH 访问 Odoo 源代码。我拥有的唯一数据是 Odoo 数据库名称、用户名、密码和我要下载的发票 ID。
有没有办法调用API或利用XML-RPC/JSON-RPC方法直接从Odoo 15下载销售订单发票,而无需访问源代码?任何有关如何在 Python Flask 环境中实现此目的的代码片段或指南将不胜感激。
import xmlrpc.client
import json
import base64
from urllib.request import urlopen
from flask import Flask, request, send_file
# Odoo Configuration
url = 'https://your_odoo_instance_url.com'
db = 'your_odoo_database'
username = 'your_odoo_username'
password = 'your_odoo_password'
# Core Invoice Fetching Logic
def fetch_and_download_invoice_xmlrpc(invoice_id):
"""Fetches and downloads a sales invoice using XML-RPC"""
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
# Fetch the PDF content
pdf_content_encoded = models.execute_kw(
db, uid, password, 'ir.actions.report', 'render_qweb_pdf_inherit', [invoice_id]
)
pdf_data = base64.b64decode(pdf_content_encoded)
with open('invoice_{}.pdf'.format(invoice_id), 'wb') as f:
f.write(pdf_data)
def fetch_and_download_invoice_jsonrpc(invoice_id):
"""Fetches and downloads a sales invoice using JSON-RPC"""
aurl = f"{url}/jsonrpc"
headers = {'Content-type': 'application/json'}
# Authentication
auth_data = {
"jsonrpc": "2.0",
"method": "call",
"params": {"db": db, "login": username, "password": password},
"id": 1
}
auth_response = json.loads(urlopen(aurl, json.dumps(auth_data).encode()).read())
if auth_response.get('error'):
raise Exception(auth_response['error'])
uid = auth_response['result']
# Fetch and download invoice
data = {
"jsonrpc": "2.0",
"method": "call",
"params": {
"service": "object",
"method": "execute",
"args": [db, uid, password, 'ir.actions.report', 'render_qweb_pdf', [invoice_id]]
},
"id": 2
}
pdf_response = json.loads(urlopen(aurl, json.dumps(data).encode()).read())
pdf_data = base64.b64decode(pdf_response['result'])
with open('invoice_{}.pdf'.format(invoice_id), 'wb') as f:
f.write(pdf_data)
# Flask Application
app = Flask(__name__)
@app.route('/download_invoice', methods=['GET'])
def download_invoice():
invoice_id = request.args.get('invoice_id')
if not invoice_id:
return "Please provide an invoice ID", 400
try:
# Choose either XML-RPC or JSON-RPC
fetch_and_download_invoice_xmlrpc(int(invoice_id)) # Convert to integer
fetch_and_download_invoice_jsonrpc(int(invoice_id))
return send_file('invoice_{}.pdf'.format(invoice_id), as_attachment=True)
except Exception as e:
return str(e), 500
if __name__ == '__main__':
app.run(debug=True)
这就是我尝试使用 XML-RPC 和 JSON-RPC 的方法
请尝试使用以下代码,如果有帮助请告诉我:
import xmlrpc.client
import json
import base64
from urllib.request import urlopen
from flask import Flask, request, send_file
# Odoo Configuration
url = 'https://your_odoo_instance_url.com'
db = 'your_odoo_database'
username = 'your_odoo_username'
password = 'your_odoo_password'
# Core Invoice Fetching Logic
def fetch_and_download_invoice(invoice_id, rpc_method):
"""Fetches and downloads a sales invoice using the specified RPC method"""
if rpc_method not in ['xmlrpc', 'jsonrpc']:
raise ValueError("Invalid RPC method")
if rpc_method == 'xmlrpc':
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
else: # jsonrpc
aurl = f"{url}/jsonrpc"
auth_data = {"jsonrpc": "2.0", "method": "call", "params": {"db": db, "login": username, "password": password}, "id": 1}
auth_response = json.loads(urlopen(aurl, json.dumps(auth_data).encode()).read())
if auth_response.get('error'):
raise Exception(auth_response['error'])
uid = auth_response['result']
# Fetch and download invoice
data = {"jsonrpc": "2.0" if rpc_method == 'jsonrpc' else None,
"method": "call",
"params": {"service": "object", "method": "execute", "args": [db, uid, password, 'ir.actions.report', 'render_qweb_pdf', [invoice_id]]},
"id": 2 if rpc_method == 'jsonrpc' else None}
pdf_response = json.loads(urlopen(aurl, json.dumps(data).encode()).read()) if rpc_method == 'jsonrpc' else models.execute_kw(
db, uid, password, 'ir.actions.report', 'render_qweb_pdf_inherit', [invoice_id]
)
pdf_data = base64.b64decode(pdf_response['result'] if rpc_method == 'jsonrpc' else pdf_response)
with open(f'invoice_{invoice_id}.pdf', 'wb') as f:
f.write(pdf_data)
# Flask Application
app = Flask(__name__)
@app.route('/download_invoice', methods=['GET'])
def download_invoice():
invoice_id = request.args.get('invoice_id')
rpc_method = request.args.get('rpc_method', 'jsonrpc') # Default to JSON-RPC if not specified
if not invoice_id:
return "Please provide an invoice ID", 400
try:
fetch_and_download_invoice(int(invoice_id), rpc_method)
return send_file(f'invoice_{invoice_id}.pdf', as_attachment=True)
except Exception as e:
return str(e), 500
if __name__ == '__main__':
app.run(debug=True)
此代码将 XML-RPC 和 JSON-RPC 的逻辑合并到单个
fetch_and_download_invoice
函数中,该函数允许您根据 rpc_method
参数动态选择 RPC 方法。