odoo-client-lib 1.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: odoo-client-lib
3
+ Version: 1.2.4
4
+ Summary: Odoo Client Library allows to easily interact with Odoo in Python.
5
+ Home-page:
6
+ Author: Nicolas Vanhoren
7
+ Author-email:
8
+ License: BSD
9
+ Keywords: odoo library com communication rpc xml-rpc net-rpc xmlrpc python client lib web service
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Programming Language :: Python
12
+ Requires-Dist: requests
13
+ Dynamic: author
14
+ Dynamic: classifier
15
+ Dynamic: description
16
+ Dynamic: keywords
17
+ Dynamic: license
18
+ Dynamic: requires-dist
19
+ Dynamic: summary
20
+
21
+ See the home page for any information: https://github.com/odoo/odoo-client-lib .
@@ -0,0 +1,7 @@
1
+ odoolib/__init__.py,sha256=MPs3zGu069RR57C79EAVD78Zc-XZ9jTNsajaDJb4aBA,1688
2
+ odoolib/dates.py,sha256=E5arcSE32h-dHxvDN5ikmmOlqNJNnaRLOjvdrbT7Cr4,3613
3
+ odoolib/main.py,sha256=CYvjIs6C1vRPz6Vx29sY818gNEF35JrxZ5Y5C4sX1Do,15341
4
+ odoo_client_lib-1.2.4.dist-info/METADATA,sha256=748HguXUMcCuXs5IwaU6lyhjM159EUIk7Hy5M5fYqiM,630
5
+ odoo_client_lib-1.2.4.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
6
+ odoo_client_lib-1.2.4.dist-info/top_level.txt,sha256=zJJ0KUA_b-iQPYRzgyH5a4zT9uBNhAVzVxKRuz6UoA8,8
7
+ odoo_client_lib-1.2.4.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (79.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ odoolib
odoolib/__init__.py ADDED
@@ -0,0 +1,32 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##############################################################################
3
+ #
4
+ # Copyright (C) Stephane Wirtel
5
+ # Copyright (C) 2011 Nicolas Vanhoren
6
+ # Copyright (C) 2011 OpenERP s.a. (<http://openerp.com>)
7
+ # Copyright (C) 2018 Odoo s.a. (<http://odoo.com>).
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # 1. Redistributions of source code must retain the above copyright notice, this
14
+ # list of conditions and the following disclaimer.
15
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ #
30
+ ##############################################################################
31
+
32
+ from .main import *
odoolib/dates.py ADDED
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##############################################################################
3
+ #
4
+ # Copyright (C) Stephane Wirtel
5
+ # Copyright (C) 2011 Nicolas Vanhoren
6
+ # Copyright (C) 2011 OpenERP s.a. (<http://openerp.com>)
7
+ # Copyright (C) 2018 Odoo s.a. (<http://odoo.com>).
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # 1. Redistributions of source code must retain the above copyright notice, this
14
+ # list of conditions and the following disclaimer.
15
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ #
30
+ ##############################################################################
31
+
32
+ import datetime
33
+
34
+ DEFAULT_SERVER_DATE_FORMAT = "%Y-%m-%d"
35
+ DEFAULT_SERVER_TIME_FORMAT = "%H:%M:%S"
36
+ DEFAULT_SERVER_DATETIME_FORMAT = "%s %s" % (
37
+ DEFAULT_SERVER_DATE_FORMAT,
38
+ DEFAULT_SERVER_TIME_FORMAT)
39
+
40
+ def str_to_datetime(str):
41
+ """
42
+ Converts a string to a datetime object using Odoo's
43
+ datetime string format (exemple: '2011-12-01 15:12:35').
44
+
45
+ No timezone information is added, the datetime is a naive instance, but
46
+ according to Odoo 9.0 specification the timezone is always UTC.
47
+ """
48
+ if not str:
49
+ return str
50
+ return datetime.datetime.strptime(str.split(".")[0], DEFAULT_SERVER_DATETIME_FORMAT)
51
+
52
+ def str_to_date(str):
53
+ """
54
+ Converts a string to a date object using Odoo's
55
+ date string format (exemple: '2011-12-01').
56
+ """
57
+ if not str:
58
+ return str
59
+ return datetime.datetime.strptime(str, DEFAULT_SERVER_DATE_FORMAT).date()
60
+
61
+ def str_to_time(str):
62
+ """
63
+ Converts a string to a time object using Odoo's
64
+ time string format (exemple: '15:12:35').
65
+ """
66
+ if not str:
67
+ return str
68
+ return datetime.datetime.strptime(str.split(".")[0], DEFAULT_SERVER_TIME_FORMAT).time()
69
+
70
+ def datetime_to_str(obj):
71
+ """
72
+ Converts a datetime object to a string using Odoo's
73
+ datetime string format (exemple: '2011-12-01 15:12:35').
74
+
75
+ The datetime instance should not have an attached timezone and be in UTC.
76
+ """
77
+ if not obj:
78
+ return False
79
+ return obj.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
80
+
81
+ def date_to_str(obj):
82
+ """
83
+ Converts a date object to a string using Odoo's
84
+ date string format (exemple: '2011-12-01').
85
+ """
86
+ if not obj:
87
+ return False
88
+ return obj.strftime(DEFAULT_SERVER_DATE_FORMAT)
89
+
90
+ def time_to_str(obj):
91
+ """
92
+ Converts a time object to a string using Odoo's
93
+ time string format (exemple: '15:12:35').
94
+ """
95
+ if not obj:
96
+ return False
97
+ return obj.strftime(DEFAULT_SERVER_TIME_FORMAT)
odoolib/main.py ADDED
@@ -0,0 +1,387 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##############################################################################
3
+ #
4
+ # Copyright (C) Stephane Wirtel
5
+ # Copyright (C) 2011 Nicolas Vanhoren
6
+ # Copyright (C) 2011 OpenERP s.a. (<http://openerp.com>)
7
+ # Copyright (C) 2018 Odoo s.a. (<http://odoo.com>).
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # 1. Redistributions of source code must retain the above copyright notice, this
14
+ # list of conditions and the following disclaimer.
15
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ #
30
+ ##############################################################################
31
+
32
+ """
33
+ Odoo Client Library
34
+
35
+ Home page: http://pypi.python.org/pypi/odoo-client-lib
36
+ Code repository: https://github.com/odoo/odoo-client-lib
37
+ """
38
+
39
+ import sys
40
+ import requests
41
+ if sys.version_info >= (3, 0, 0):
42
+ from xmlrpc.client import ServerProxy
43
+ else:
44
+ from xmlrpclib import ServerProxy
45
+ import logging
46
+ import json
47
+ import random
48
+
49
+ _logger = logging.getLogger(__name__)
50
+
51
+ def _getChildLogger(logger, subname):
52
+ return logging.getLogger(logger.name + "." + subname)
53
+
54
+ class Connector(object):
55
+ """
56
+ The base abstract class representing a connection to an Odoo Server.
57
+ """
58
+
59
+ __logger = _getChildLogger(_logger, 'connector')
60
+
61
+ def get_service(self, service_name):
62
+ """
63
+ Returns a Service instance to allow easy manipulation of one of the services offered by the remote server.
64
+
65
+ :param service_name: The name of the service.
66
+ """
67
+ return Service(self, service_name)
68
+
69
+ class XmlRPCConnector(Connector):
70
+ """
71
+ A type of connector that uses the XMLRPC protocol.
72
+ """
73
+ PROTOCOL = 'xmlrpc'
74
+
75
+ __logger = _getChildLogger(_logger, 'connector.xmlrpc')
76
+
77
+ def __init__(self, hostname, port=8069):
78
+ """
79
+ Initialize by specifying the hostname and the port.
80
+ :param hostname: The hostname of the computer holding the instance of Odoo.
81
+ :param port: The port used by the Odoo instance for XMLRPC (default to 8069).
82
+ """
83
+ self.url = 'http://%s:%d/xmlrpc' % (hostname, port)
84
+
85
+ def send(self, service_name, method, *args):
86
+ url = '%s/%s' % (self.url, service_name)
87
+ service = ServerProxy(url)
88
+ return getattr(service, method)(*args)
89
+
90
+ class XmlRPCSConnector(XmlRPCConnector):
91
+ """
92
+ A type of connector that uses the secured XMLRPC protocol.
93
+ """
94
+ PROTOCOL = 'xmlrpcs'
95
+
96
+ __logger = _getChildLogger(_logger, 'connector.xmlrpcs')
97
+
98
+ def __init__(self, hostname, port=8069):
99
+ super(XmlRPCSConnector, self).__init__(hostname, port)
100
+ self.url = 'https://%s:%d/xmlrpc' % (hostname, port)
101
+
102
+ class JsonRPCException(Exception):
103
+ def __init__(self, error):
104
+ self.error = error
105
+ def __str__(self):
106
+ return repr(self.error)
107
+
108
+ def json_rpc(url, fct_name, params):
109
+ data = {
110
+ "jsonrpc": "2.0",
111
+ "method": fct_name,
112
+ "params": params,
113
+ "id": random.randint(0, 1000000000),
114
+ }
115
+ result_req = requests.post(url, data=json.dumps(data), headers={
116
+ "Content-Type":"application/json",
117
+ })
118
+ result = result_req.json()
119
+ if result.get("error", None):
120
+ raise JsonRPCException(result["error"])
121
+ return result.get("result", False)
122
+
123
+ class JsonRPCConnector(Connector):
124
+ """
125
+ A type of connector that uses the JsonRPC protocol.
126
+ """
127
+ PROTOCOL = 'jsonrpc'
128
+
129
+ __logger = _getChildLogger(_logger, 'connector.jsonrpc')
130
+
131
+ def __init__(self, hostname, port=8069):
132
+ """
133
+ Initialize by specifying the hostname and the port.
134
+ :param hostname: The hostname of the computer holding the instance of Odoo.
135
+ :param port: The port used by the Odoo instance for JsonRPC (default to 8069).
136
+ """
137
+ self.url = 'http://%s:%d/jsonrpc' % (hostname, port)
138
+
139
+ def send(self, service_name, method, *args):
140
+ return json_rpc(self.url, "call", {"service": service_name, "method": method, "args": args})
141
+
142
+ class JsonRPCSConnector(Connector):
143
+ """
144
+ A type of connector that uses the JsonRPC protocol.
145
+ """
146
+ PROTOCOL = 'jsonrpcs'
147
+
148
+ __logger = _getChildLogger(_logger, 'connector.jsonrpc')
149
+
150
+ def __init__(self, hostname, port=8069):
151
+ """
152
+ Initialize by specifying the hostname and the port.
153
+ :param hostname: The hostname of the computer holding the instance of Odoo.
154
+ :param port: The port used by the Odoo instance for JsonRPC (default to 8069).
155
+ """
156
+ self.url = 'https://%s:%d/jsonrpc' % (hostname, port)
157
+
158
+ def send(self, service_name, method, *args):
159
+ return json_rpc(self.url, "call", {"service": service_name, "method": method, "args": args})
160
+
161
+ class Service(object):
162
+ """
163
+ A class to execute RPC calls on a specific service of the remote server.
164
+ """
165
+ def __init__(self, connector, service_name):
166
+ """
167
+ :param connector: A valid Connector instance.
168
+ :param service_name: The name of the service on the remote server.
169
+ """
170
+ self.connector = connector
171
+ self.service_name = service_name
172
+ self.__logger = _getChildLogger(_getChildLogger(_logger, 'service'),service_name or "")
173
+
174
+ def __getattr__(self, method):
175
+ """
176
+ :param method: The name of the method to execute on the service.
177
+ """
178
+ self.__logger.debug('method: %r', method)
179
+ def proxy(*args):
180
+ """
181
+ :param args: A list of values for the method
182
+ """
183
+ self.__logger.debug('args: %r', args)
184
+ result = self.connector.send(self.service_name, method, *args)
185
+ self.__logger.debug('result: %r', result)
186
+ return result
187
+ return proxy
188
+
189
+ class Connection(object):
190
+ """
191
+ A class to represent a connection with authentication to an Odoo Server.
192
+ It also provides utility methods to interact with the server more easily.
193
+ """
194
+ __logger = _getChildLogger(_logger, 'connection')
195
+
196
+ def __init__(self, connector,
197
+ database=None,
198
+ login=None,
199
+ password=None,
200
+ user_id=None):
201
+ """
202
+ Initialize with login information. The login information is facultative to allow specifying
203
+ it after the initialization of this object.
204
+
205
+ :param connector: A valid Connector instance to send messages to the remote server.
206
+ :param database: The name of the database to work on.
207
+ :param login: The login of the user.
208
+ :param password: The password of the user.
209
+ :param user_id: The user id is a number identifying the user. This is only useful if you
210
+ already know it, in most cases you don't need to specify it.
211
+ """
212
+ self.connector = connector
213
+
214
+ self.set_login_info(database, login, password, user_id)
215
+ self.user_context = None
216
+
217
+ def set_login_info(self, database, login, password, user_id=None):
218
+ """
219
+ Set login information after the initialisation of this object.
220
+
221
+ :param connector: A valid Connector instance to send messages to the remote server.
222
+ :param database: The name of the database to work on.
223
+ :param login: The login of the user.
224
+ :param password: The password of the user.
225
+ :param user_id: The user id is a number identifying the user. This is only useful if you
226
+ already know it, in most cases you don't need to specify it.
227
+ """
228
+ self.database, self.login, self.password = database, login, password
229
+
230
+ self.user_id = user_id
231
+
232
+ def check_login(self, force=True):
233
+ """
234
+ Checks that the login information is valid. Throws an AuthenticationError if the
235
+ authentication fails.
236
+
237
+ :param force: Force to re-check even if this Connection was already validated previously.
238
+ Default to True.
239
+ """
240
+ if self.user_id and not force:
241
+ return
242
+
243
+ if not self.database or not self.login or self.password is None:
244
+ raise AuthenticationError("Credentials not provided")
245
+
246
+ # TODO use authenticate instead of login
247
+ self.user_id = self.get_service("common").login(self.database, self.login, self.password)
248
+ if not self.user_id:
249
+ raise AuthenticationError("Authentication failure")
250
+ self.__logger.debug("Authenticated with user id %s", self.user_id)
251
+
252
+ def get_user_context(self):
253
+ """
254
+ Query the default context of the user.
255
+ """
256
+ if not self.user_context:
257
+ self.user_context = self.get_model('res.users').context_get()
258
+ return self.user_context
259
+
260
+ def get_model(self, model_name):
261
+ """
262
+ Returns a Model instance to allow easy remote manipulation of an Odoo model.
263
+
264
+ :param model_name: The name of the model.
265
+ """
266
+ return Model(self, model_name)
267
+
268
+ def get_service(self, service_name):
269
+ """
270
+ Returns a Service instance to allow easy manipulation of one of the services offered by the remote server.
271
+ Please note this Connection instance does not need to have valid authentication information since authentication
272
+ is only necessary for the "object" service that handles models.
273
+
274
+ :param service_name: The name of the service.
275
+ """
276
+ return self.connector.get_service(service_name)
277
+
278
+ class AuthenticationError(Exception):
279
+ """
280
+ An error thrown when an authentication to an Odoo server failed.
281
+ """
282
+ pass
283
+
284
+ class Model(object):
285
+ """
286
+ Useful class to dialog with one of the models provided by an Odoo server.
287
+ An instance of this class depends on a Connection instance with valid authentication information.
288
+ """
289
+
290
+ def __init__(self, connection, model_name):
291
+ """
292
+ :param connection: A valid Connection instance with correct authentication information.
293
+ :param model_name: The name of the model.
294
+ """
295
+ self.connection = connection
296
+ self.model_name = model_name
297
+ self.__logger = _getChildLogger(_getChildLogger(_logger, 'object'), model_name or "")
298
+
299
+ def __getattr__(self, method):
300
+ """
301
+ Provides proxy methods that will forward calls to the model on the remote Odoo server.
302
+
303
+ :param method: The method for the linked model (search, read, write, unlink, create, ...)
304
+ """
305
+ def proxy(*args, **kw):
306
+ """
307
+ :param args: A list of values for the method
308
+ """
309
+ self.connection.check_login(False)
310
+ self.__logger.debug(args)
311
+ result = self.connection.get_service('object').execute_kw(
312
+ self.connection.database,
313
+ self.connection.user_id,
314
+ self.connection.password,
315
+ self.model_name,
316
+ method,
317
+ args, kw)
318
+ if method == "read":
319
+ if isinstance(result, list) and len(result) > 0 and "id" in result[0]:
320
+ index = {}
321
+ for r in result:
322
+ index[r['id']] = r
323
+ if isinstance(args[0], list):
324
+ result = [index[x] for x in args[0] if x in index]
325
+ elif args[0] in index:
326
+ result = index[args[0]]
327
+ else:
328
+ result = False
329
+ self.__logger.debug('result: %r', result)
330
+ return result
331
+ return proxy
332
+
333
+ def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None, context=None):
334
+ """
335
+ A shortcut method to combine a search() and a read().
336
+
337
+ :param domain: The domain for the search.
338
+ :param fields: The fields to extract (can be None or [] to extract all fields).
339
+ :param offset: The offset for the rows to read.
340
+ :param limit: The maximum number of rows to read.
341
+ :param order: The order to class the rows.
342
+ :param context: The context.
343
+ :return: A list of dictionaries containing all the specified fields.
344
+ """
345
+ record_ids = self.search(domain or [], offset, limit or False, order or False, context=context or {})
346
+ if not record_ids: return []
347
+ records = self.read(record_ids, fields or [], context=context or {})
348
+ return records
349
+
350
+ def get_connector(hostname=None, protocol="xmlrpc", port="auto"):
351
+ """
352
+ A shortcut method to easily create a connector to a remote server using XMLRPC.
353
+
354
+ :param hostname: The hostname to the remote server.
355
+ :param protocol: The name of the protocol, must be "xmlrpc", "xmlrpcs", "jsonrpc" or "jsonrpcs".
356
+ :param port: The number of the port. Defaults to auto.
357
+ """
358
+ if port == 'auto':
359
+ port = 8069
360
+ if protocol == "xmlrpc":
361
+ return XmlRPCConnector(hostname, port)
362
+ elif protocol == "xmlrpcs":
363
+ return XmlRPCSConnector(hostname, port)
364
+ if protocol == "jsonrpc":
365
+ return JsonRPCConnector(hostname, port)
366
+ elif protocol == "jsonrpcs":
367
+ return JsonRPCSConnector(hostname, port)
368
+ else:
369
+ raise ValueError("You must choose xmlrpc, xmlrpcs, jsonrpc or jsonrpcs")
370
+
371
+ def get_connection(hostname=None, protocol="xmlrpc", port='auto', database=None,
372
+ login=None, password=None, user_id=None):
373
+ """
374
+ A shortcut method to easily create a connection to a remote Odoo server.
375
+
376
+ :param hostname: The hostname to the remote server.
377
+ :param protocol: The name of the protocol, must be "xmlrpc", "xmlrpcs", "jsonrpc" or "jsonrpcs".
378
+ :param port: The number of the port. Defaults to auto.
379
+ :param connector: A valid Connector instance to send messages to the remote server.
380
+ :param database: The name of the database to work on.
381
+ :param login: The login of the user.
382
+ :param password: The password of the user.
383
+ :param user_id: The user id is a number identifying the user. This is only useful if you
384
+ already know it, in most cases you don't need to specify it.
385
+ """
386
+ return Connection(get_connector(hostname, protocol, port), database, login, password, user_id)
387
+