无SSH权限下,用Python Flask通过XML-RPC/JSON-RPC下载Odoo15销售订单发票
问题
我正在开发一个Python Flask应用,需要通过XML-RPC或JSON-RPC从Odoo 15下载销售订单发票。但受安全限制,我无法通过SSH访问Odoo源码,仅拥有Odoo数据库名称、用户名、密码以及需要下载的发票ID。
请问是否可以通过调用API或使用XML-RPC/JSON-RPC方法,在不访问源码的情况下直接从Odoo 15下载销售订单发票?希望能提供在Python Flask环境下实现的代码片段或指导。
最初的尝试(XML-RPC & JSON-RPC)
我分别用XML-RPC和JSON-RPC做了以下尝试:
import xmlrpc.client import json import base64 from urllib.request import urlopen from flask import Flask, request, send_file # Odoo 配置 url = 'https://your_odoo_instance_url.com' db = 'your_odoo_database' username = 'your_odoo_username' password = 'your_odoo_password' # 核心发票获取逻辑 def fetch_and_download_invoice_xmlrpc(invoice_id): """使用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)) # 获取PDF内容 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): """使用JSON-RPC获取并下载销售发票""" aurl = f"{url}/jsonrpc" headers = {'Content-type': 'application/json'} # 认证 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'] # 获取并下载发票 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 应用 app = Flask(__name__) @app.route('/download_invoice', methods=['GET']) def download_invoice(): invoice_id = request.args.get('invoice_id') if not invoice_id: return "请提供发票ID", 400 try: # 选择XML-RPC或JSON-RPC其中一种即可 fetch_and_download_invoice_xmlrpc(int(invoice_id)) # 转换为整数 # 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)
可行解决方案
我已经找到可以正常运行的方案,代码如下:
# 导入Flask框架及其他必要库 from flask import Flask, request, jsonify, send_file import xmlrpc.client import requests # 配置Odoo实例的凭证和URL url = 'https://your_odoo_instance_url.com' db = 'your_odoo_database' username = 'your_odoo_username' password = 'your_odoo_password' # 向Odoo认证并获取会话ID session_url = f'{url}web/session/authenticate' data = { 'jsonrpc': '2.0', 'method': 'call', 'params': { "service": "common", "method": "login", 'db': db, 'login': username, 'password': password, } } session_response = requests.post(session_url, json=data) session_data = session_response.json() session_id = session_response.cookies['session_id'] # 建立与Odoo的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)) # 指定要获取的发票ID invoice_id = 21566 # 从Odoo获取指定发票的信息 invoice = models.execute_kw(db, uid, password, 'account.move', 'read', [invoice_id], {'fields': ['name']}) # 触发发票发送并打印的动作,获取生成的PDF链接 pdf_file_url = models.execute_kw(db, uid, password, 'account.move.send', 'action_send_and_print', [4, [invoice_id]]) # 设置包含会话ID的请求头用于下载PDF headers = {'Cookie': f'session_id={session_id}'} download_url = f'{url}{pdf_file_url["url"]}' # 下载发票的PDF内容 response = requests.get(download_url, headers=headers) pdf_content = response.content # 根据发票名称指定下载后的PDF文件名 filename = '{}.pdf'.format(invoice[0]['name']) # 将PDF内容保存到文件 with open(filename, 'wb') as f: f.write(pdf_content)
内容的提问来源于stack exchange,提问作者Aditya Irri
相关产品推荐
相关产品推荐

