Use class-based odoo client for connection reuse
This commit is contained in:
parent
6ce13126d5
commit
8f75db5325
1 changed files with 60 additions and 52 deletions
|
@ -15,69 +15,77 @@ ADDRESS_FIELDS = [
|
||||||
"phone",
|
"phone",
|
||||||
"vat",
|
"vat",
|
||||||
"company_type",
|
"company_type",
|
||||||
|
"type",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def odoo_request(model, method, **kwargs):
|
class OdooClient:
|
||||||
url = settings.ODOO["URL"]
|
def __init__(self):
|
||||||
db = settings.ODOO["DB"]
|
self.url = settings.ODOO["URL"]
|
||||||
username = settings.ODOO["USERNAME"]
|
self.db = settings.ODOO["DB"]
|
||||||
password = settings.ODOO["PASSWORD"]
|
self.username = settings.ODOO["USERNAME"]
|
||||||
|
self.password = settings.ODOO["PASSWORD"]
|
||||||
|
|
||||||
try:
|
self.common_proxy = None
|
||||||
common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common")
|
self.models_proxy = None
|
||||||
uid = common.authenticate(db, username, password, {})
|
self.uid = None
|
||||||
|
|
||||||
if not uid:
|
def _connect(self):
|
||||||
raise Exception("Authentication failed with Odoo.")
|
"""This method is called on the first client request, not on instantiation,
|
||||||
|
so that we can instantiate the client on startup and reuse it across the entire
|
||||||
|
application."""
|
||||||
|
try:
|
||||||
|
self.common_proxy = xmlrpc.client.ServerProxy(f"{self.url}/xmlrpc/2/common")
|
||||||
|
self.uid = self.common_proxy.authenticate(
|
||||||
|
self.db, self.username, self.password, {}
|
||||||
|
)
|
||||||
|
|
||||||
models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object")
|
if not self.uid:
|
||||||
|
raise Exception("Authentication failed with Odoo: No UID returned.")
|
||||||
|
|
||||||
# Prepare arguments for execute_kw
|
self.models_proxy = xmlrpc.client.ServerProxy(f"{self.url}/xmlrpc/2/object")
|
||||||
# Odoo's execute_kw expects: db, uid, password, model, method, args_list, kwargs_dict
|
|
||||||
# For 'search_read', args_list typically contains [domain, fields]
|
|
||||||
# and kwargs_dict contains {'limit': ..., 'offset': ..., 'order': ...}
|
|
||||||
|
|
||||||
args_list = []
|
except xmlrpc.client.Fault as e:
|
||||||
kwargs_dict = {}
|
raise Exception(
|
||||||
|
f"Odoo XML-RPC Fault during connection: {e.faultString}"
|
||||||
|
) from e
|
||||||
|
except ConnectionRefusedError as e:
|
||||||
|
raise Exception(
|
||||||
|
f"Could not connect to Odoo at {self.url}. Connection refused."
|
||||||
|
) from e
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(
|
||||||
|
f"An error occurred while connecting to Odoo: {str(e)}"
|
||||||
|
) from e
|
||||||
|
|
||||||
if method == "search_read":
|
def execute(self, model, method, args_list, **kwargs):
|
||||||
# Extract domain and fields for positional arguments if present
|
if not self.uid or not self.models_proxy:
|
||||||
domain = kwargs.pop("domain", [])
|
self._connect()
|
||||||
fields = kwargs.pop("fields", [])
|
|
||||||
args_list = [domain, fields]
|
|
||||||
# Remaining kwargs are passed as the options dictionary
|
|
||||||
kwargs_dict = kwargs
|
|
||||||
else:
|
|
||||||
# For other methods, we might need a more generic way or specific handling.
|
|
||||||
# For now, assume kwargs can be passed directly if method is not 'search_read',
|
|
||||||
# or that they are passed as a list of arguments.
|
|
||||||
# This part might need refinement based on other Odoo methods used.
|
|
||||||
# A common pattern is to pass a list of IDs as the first arg for methods like 'read', 'write'.
|
|
||||||
# If 'args' is explicitly passed in kwargs, use it.
|
|
||||||
if "args" in kwargs:
|
|
||||||
args_list = kwargs.pop("args")
|
|
||||||
# Remaining kwargs are passed as the options dictionary
|
|
||||||
kwargs_dict = kwargs
|
|
||||||
|
|
||||||
breakpoint()
|
try:
|
||||||
result = models.execute_kw(
|
result = self.models_proxy.execute_kw(
|
||||||
db, uid, password, model, method, args_list, kwargs_dict
|
self.db, self.uid, self.password, model, method, args_list, kwargs
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
except xmlrpc.client.Fault as e:
|
except xmlrpc.client.Fault as e:
|
||||||
# Handle XML-RPC specific errors (e.g., Odoo operational errors)
|
print(f"Fault! {e}")
|
||||||
raise Exception(f"Odoo XML-RPC Fault: {e.faultString}") from e
|
raise Exception(f"Odoo XML-RPC Fault: {e.faultString}") from e
|
||||||
except ConnectionRefusedError as e:
|
except ConnectionRefusedError as e:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"Could not connect to Odoo at {url}. Connection refused."
|
f"Connection to Odoo at {self.url} lost or refused during operation."
|
||||||
) from e
|
) from e
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# General exception handling
|
print(e)
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"An error occurred while communicating with Odoo: {str(e)}"
|
f"An error occurred while communicating with Odoo: {str(e)}"
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
|
def search_read(self, model, domain, fields, **kwargs):
|
||||||
|
return self.execute(model, "search_read", args_list=[domain, fields], **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
CLIENT = OdooClient()
|
||||||
|
|
||||||
|
|
||||||
def get_invoice_addresses(user):
|
def get_invoice_addresses(user):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue