odoorpc API Reference
Official Python client to pilot Odoo servers through JSON-RPC, providing model access, workflow execution, and record browsing.
odoorpc.ODOO
Python Library Documentation: class ODOO in module odoorpc.odoo
class ODOO(builtins.object)
| ODOO(host='localhost', protocol='jsonrpc', port=8069, timeout=120, version=None, opener=None)
|
| Return a new instance of the :class:`ODOO` class.
| `JSON-RPC` protocol is used to make requests, and the respective values
| for the `protocol` parameter are ``jsonrpc`` (default) and ``jsonrpc+ssl``.
|
| .. doctest::
| :options: +SKIP
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO('localhost', protocol='jsonrpc', port=8069)
|
| `OdooRPC` will try by default to detect the server version in order to
| adapt its requests if necessary. However, it is possible to force the
| version to use with the `version` parameter:
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo = odoorpc.ODOO('localhost', version='12.0')
|
| You can also define a custom URL opener to handle HTTP requests. A use
| case is to manage a basic HTTP authentication in front of `Odoo`:
|
| .. doctest::
| :options: +SKIP
|
| >>> import urllib.request
| >>> import odoorpc
| >>> pwd_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
| >>> pwd_mgr.add_password(None, "http://example.net", "userName", "passWord")
| >>> auth_handler = urllib.request.HTTPBasicAuthHandler(pwd_mgr)
| >>> opener = urllib.request.build_opener(auth_handler)
| >>> odoo = odoorpc.ODOO('example.net', port=80, opener=opener)
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.InternalError`
| :raise: `ValueError` (wrong protocol, port value, timeout value)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.InternalError`
| :raise: `ValueError` (wrong protocol, port value, timeout value)
| :raise: `urllib.error.URLError` (connection error)
|
| Methods defined here:
|
| __init__(self, host='localhost', protocol='jsonrpc', port=8069, timeout=120, version=None, opener=None)
| Initialize self. See help(type(self)) for accurate signature.
|
| close(self)
| Same than :attr:`odoorpc.ODOO.logout` method.
|
| Here for the compatibility with `contextlib.closing`:
|
| .. doctest::
| :options: +SKIP
|
| >>> import contextlib
| >>> odoo.login('db_name', 'admin', 'admin')
| >>> with contextlib.closing(odoo):
| ... print(odoo.env.user.name)
| ...
| Mitchell Admin
|
| exec_workflow(self, model, record_id, signal)
| Execute the workflow `signal` on
| the instance having the ID `record_id` of `model`.
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.RPCError`
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.RPCError`
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `urllib.error.URLError` (connection error)
|
| execute(self, model, method, *args)
| Execute the `method` of `model`.
| `*args` parameters varies according to the `method` used.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.execute('res.partner', 'read', [1], ['name'])
| [{'id': 1, 'name': 'YourCompany'}]
|
| .. doctest::
| :hide:
|
| >>> data = odoo.execute('res.partner', 'read', [1], ['name'])
| >>> data[0]['id'] == 1
| True
| >>> data[0]['name'] == 'YourCompany'
| True
|
| *Python 2:*
|
| :return: the result returned by the `method` called
| :raise: :class:`odoorpc.error.RPCError`
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: the result returned by the `method` called
| :raise: :class:`odoorpc.error.RPCError`
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `urllib.error.URLError` (connection error)
|
| execute_kw(self, model, method, args=None, kwargs=None)
| Execute the `method` of `model`.
| `args` is a list of parameters (in the right order),
| and `kwargs` a dictionary (named parameters). Both varies according
| to the `method` used.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.execute_kw('res.partner', 'read', [[1]], {'fields': ['name']})
| [{'id': 1, 'name': 'YourCompany'}]
|
| .. doctest::
| :hide:
|
| >>> data = odoo.execute_kw('res.partner', 'read', [[1]], {'fields': ['name']})
| >>> data[0]['id'] == 1
| True
| >>> data[0]['name'] == 'YourCompany'
| True
|
| *Python 2:*
|
| :return: the result returned by the `method` called
| :raise: :class:`odoorpc.error.RPCError`
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: the result returned by the `method` called
| :raise: :class:`odoorpc.error.RPCError`
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `urllib.error.URLError` (connection error)
|
| http(self, url, data=None, headers=None)
| Low level method to execute raw HTTP queries.
|
| .. note::
|
| For low level JSON-RPC queries, see the more convenient
| :func:`odoorpc.ODOO.json` method instead.
|
| You have to know the names of each POST parameter required by the
| URL, and set them in the `data` string/buffer.
| The `data` argument must be built by yourself, following the expected
| URL parameters (with :func:`urllib.urlencode` function for simple
| parameters, or multipart/form-data structure to handle file upload).
|
| E.g., the HTTP raw query to get the company logo on `Odoo 12.0`:
|
| .. doctest::
|
| >>> response = odoo.http('web/binary/company_logo')
| >>> binary_data = response.read()
|
| *Python 2:*
|
| :return: `urllib.addinfourl`
| :raise: `urllib2.HTTPError`
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: `http.client.HTTPResponse`
| :raise: `urllib.error.HTTPError`
| :raise: `urllib.error.URLError` (connection error)
|
| json(self, url, params)
| Low level method to execute JSON queries.
| It basically performs a request and raises an
| :class:`odoorpc.error.RPCError` exception if the response contains
| an error.
|
| You have to know the names of each parameter required by the function
| called, and set them in the `params` dictionary.
|
| Here an authentication request:
|
| .. doctest::
| :options: +SKIP
|
| >>> data = odoo.json(
| ... '/web/session/authenticate',
| ... {'db': 'db_name', 'login': 'admin', 'password': 'admin'})
| >>> from pprint import pprint
| >>> pprint(data)
| {'id': 645674382,
| 'jsonrpc': '2.0',
| 'result': {'db': 'db_name',
| 'session_id': 'fa740abcb91784b8f4750c5c5b14da3fcc782d11',
| 'uid': 1,
| 'user_context': {'lang': 'en_US',
| 'tz': 'Europe/Brussels',
| 'uid': 1},
| 'username': 'admin'}}
|
| .. doctest::
| :hide:
|
| >>> data = odoo.json(
| ... '/web/session/authenticate',
| ... {'db': DB, 'login': USER, 'password': PWD})
| >>> data['result']['db'] == DB
| True
| >>> data['result']['uid'] in [1, 2]
| True
| >>> data['result']['username'] == USER
| True
|
| And a call to the ``read`` method of the ``res.users`` model:
|
| .. doctest::
| :options: +SKIP
|
| >>> data = odoo.json(
| ... '/web/dataset/call',
| ... {'model': 'res.users', 'method': 'read',
| ... 'args': [[2], ['name']]})
| >>> from pprint import pprint
| >>> pprint(data)
| {'id': ...,
| 'jsonrpc': '2.0',
| 'result': [{'id': 2, 'name': 'Mitchell Admin'}]}
|
| *Python 2:*
|
| :return: a dictionary (JSON response)
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib2.HTTPError` (if `params` is not a dictionary)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: a dictionary (JSON response)
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib.error.HTTPError` (if `params` is not a dictionary)
| :raise: `urllib.error.URLError` (connection error)
|
| login(self, db, login='admin', password='admin')
| Log in as the given `user` with the password `passwd` on the
| database `db`.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.login('db_name', 'admin', 'admin')
| >>> odoo.env.user.name
| 'Administrator'
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib.error.URLError` (connection error)
|
| logout(self)
| Log out the user.
|
| >>> odoo.logout()
| True
|
| *Python 2:*
|
| :return: `True` if the operation succeed, `False` if no user was logged
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: `True` if the operation succeed, `False` if no user was logged
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib.error.URLError` (connection error)
|
| save(self, name, rc_file='~/.odoorpcrc')
| Save the current :class:`ODOO <odoorpc.ODOO>` instance (a `session`)
| inside `rc_file` (``~/.odoorpcrc`` by default). This session will be
| identified by `name`::
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO('localhost', port=8069)
| >>> odoo.login('db_name', 'admin', 'admin')
| >>> odoo.save('foo')
|
| Use the :func:`list <odoorpc.ODOO.list>` class method to list all
| stored sessions, and the :func:`load <odoorpc.ODOO.load>` class method
| to retrieve an already-connected :class:`ODOO <odoorpc.ODOO>` instance.
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `IOError`
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.InternalError` (if not logged)
| :raise: `PermissionError`
| :raise: `FileNotFoundError`
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| list(rc_file='~/.odoorpcrc')
| Return a list of all stored sessions available in the
| `rc_file` file:
|
| .. doctest::
| :options: +SKIP
|
| >>> import odoorpc
| >>> odoorpc.ODOO.list()
| ['foo', 'bar']
|
| Use the :func:`save <odoorpc.ODOO.save>` and
| :func:`load <odoorpc.ODOO.load>` methods to manage such sessions.
|
| *Python 2:*
|
| :raise: `IOError`
|
| *Python 3:*
|
| :raise: `PermissionError`
| :raise: `FileNotFoundError`
|
| load(name, rc_file='~/.odoorpcrc')
| Return a connected :class:`ODOO` session identified by `name`:
|
| .. doctest::
| :options: +SKIP
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO.load('foo')
|
| Such sessions are stored with the
| :func:`save <odoorpc.ODOO.save>` method.
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.RPCError`
| :raise: `urllib.error.URLError` (connection error)
|
| remove(name, rc_file='~/.odoorpcrc')
| Remove the session identified by `name` from the `rc_file` file:
|
| .. doctest::
| :options: +SKIP
|
| >>> import odoorpc
| >>> odoorpc.ODOO.remove('foo')
| True
|
| *Python 2:*
|
| :raise: `ValueError` (if the session does not exist)
| :raise: `IOError`
|
| *Python 3:*
|
| :raise: `ValueError` (if the session does not exist)
| :raise: `PermissionError`
| :raise: `FileNotFoundError`
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| config
| Dictionary of available configuration options.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.config
| {'auto_commit': True, 'auto_context': True, 'timeout': 120}
|
| .. doctest::
| :hide:
|
| >>> 'auto_commit' in odoo.config
| True
| >>> 'auto_context' in odoo.config
| True
| >>> 'timeout' in odoo.config
| True
|
| - ``auto_commit``: if set to `True` (default), each time a value is set
| on a record field a RPC request is sent to the server to update the
| record (see :func:`odoorpc.env.Environment.commit`).
|
| - ``auto_context``: if set to `True` (default), the user context will
| be sent automatically to every call of a
| :class:`model <odoorpc.models.Model>` method (default: `True`):
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.env.context['lang'] = 'fr_FR'
| >>> Product = odoo.env['product.product']
| >>> Product.name_get([2]) # Context sent by default ('lang': 'fr_FR' here)
| [[2, 'Surveillance sur site']]
| >>> odoo.config['auto_context'] = False
| >>> Product.name_get([2]) # No context sent, 'en_US' used
| [[2, 'On Site Monitoring']]
|
| - ``timeout``: set the maximum timeout in seconds for a RPC request
| (default: `120`):
|
| >>> odoo.config['timeout'] = 300
|
| db
| The database management service.
| See the :class:`odoorpc.db.DB` class.
|
| env
| The environment which wraps data to manage records such as the
| user context and the registry to access data model proxies.
|
| >>> Partner = odoo.env['res.partner']
| >>> Partner
| Model('res.partner')
|
| See the :class:`odoorpc.env.Environment` class.
|
| host
| Hostname of IP address of the the server.
|
| port
| The port used.
|
| protocol
| The protocol used.
|
| report
| The report management service.
| See the :class:`odoorpc.report.Report` class.
|
| version
| The version of the server.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.version
| '12.0'
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
odoorpc.db.DB
Python Library Documentation: class DB in module odoorpc.db
class DB(builtins.object)
| DB(odoo)
|
| The `DB` class represents the database management service.
| It provides functionalities such as list, create, drop, dump
| and restore databases.
|
| .. note::
| This service have to be used through the :attr:`odoorpc.ODOO.db`
| property.
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO('localhost') # doctest: +SKIP
| >>> odoo.db
| <odoorpc.db.DB object at 0x...>
|
| Methods defined here:
|
| __init__(self, odoo)
| Initialize self. See help(type(self)) for accurate signature.
|
| change_password(self, password, new_password)
| Change the administrator password by `new_password`.
|
| >>> odoo.db.change_password('super_admin_passwd', 'new_admin_passwd') # doctest: +SKIP
|
| .. doctest:
| :hide:
|
| >>> odoo.db.change_password(SUPER_PWD, 'new_admin_passwd')
| >>> odoo.db.change_password('new_admin_passwd', SUPER_PWD)
|
| The super administrator password is required to perform this method.
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.RPCError` (access denied)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.RPCError` (access denied)
| :raise: `urllib.error.URLError` (connection error)
|
| create(self, password, db, demo=False, lang='en_US', admin_password='admin')
| Request the server to create a new database named `db`
| which will have `admin_password` as administrator password and
| localized with the `lang` parameter.
| You have to set the flag `demo` to `True` in order to insert
| demonstration data.
|
| >>> odoo.db.create('super_admin_passwd', 'prod', False, 'fr_FR', 'my_admin_passwd') # doctest: +SKIP
|
| If you get a timeout error, increase this one before performing the
| request:
|
| >>> timeout_backup = odoo.config['timeout']
| >>> odoo.config['timeout'] = 600 # Timeout set to 10 minutes
| >>> odoo.db.create('super_admin_passwd', 'prod', False, 'fr_FR', 'my_admin_passwd') # doctest: +SKIP
| >>> odoo.config['timeout'] = timeout_backup
|
| The super administrator password is required to perform this method.
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.RPCError` (access denied)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.RPCError` (access denied)
| :raise: `urllib.error.URLError` (connection error)
|
| drop(self, password, db)
| Drop the `db` database. Returns `True` if the database was removed,
| `False` otherwise (database did not exist):
|
| >>> odoo.db.drop('super_admin_passwd', 'test') # doctest: +SKIP
| True
|
| The super administrator password is required to perform this method.
|
| *Python 2:*
|
| :return: `True` or `False`
| :raise: :class:`odoorpc.error.RPCError` (access denied)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: `True` or `False`
| :raise: :class:`odoorpc.error.RPCError` (access denied)
| :raise: `urllib.error.URLError` (connection error)
|
| dump(self, password, db, format_='zip')
| Backup the `db` database. Returns the dump as a binary ZIP file
| containing the SQL dump file alongside the filestore directory (if any).
|
| >>> dump = odoo.db.dump('super_admin_passwd', 'prod') # doctest: +SKIP
|
| .. doctest::
| :hide:
|
| >>> dump = odoo.db.dump(SUPER_PWD, DB)
|
| If you get a timeout error, increase this one before performing the
| request:
|
| >>> timeout_backup = odoo.config['timeout']
| >>> odoo.config['timeout'] = 600 # Timeout set to 10 minutes
| >>> dump = odoo.db.dump('super_admin_passwd', 'prod') # doctest: +SKIP
| >>> odoo.config['timeout'] = timeout_backup
|
| Write it on the file system:
|
| .. doctest::
| :options: +SKIP
|
| >>> with open('dump.zip', 'wb') as dump_zip:
| ... dump_zip.write(dump.read())
| ...
|
| .. doctest::
| :hide:
|
| >>> with open('dump.zip', 'wb') as dump_zip:
| ... fileno = dump_zip.write(dump.read()) # Python 3
| ...
|
| You can manipulate the file with the `zipfile` module for instance:
|
| .. doctest::
| :options: +SKIP
|
| >>> import zipfile
| >>> zipfile.ZipFile('dump.zip').namelist()
| ['dump.sql',
| 'filestore/ef/ef2c882a36dbe90fc1e7e28d816ad1ac1464cfbb',
| 'filestore/dc/dcf00aacce882bbfd117c0277e514f829b4c5bf0',
| ...]
|
| .. doctest::
| :hide:
|
| >>> import zipfile
| >>> zipfile.ZipFile('dump.zip').namelist() # doctest: +NORMALIZE_WHITESPACE
| ['dump.sql'...'filestore/...'...]
|
| The super administrator password is required to perform this method.
|
| *Python 2:*
|
| :return: `io.BytesIO`
| :raise: :class:`odoorpc.error.RPCError` (access denied / wrong database)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: `io.BytesIO`
| :raise: :class:`odoorpc.error.RPCError` (access denied / wrong database)
| :raise: `urllib.error.URLError` (connection error)
|
| duplicate(self, password, db, new_db)
| Duplicate `db' as `new_db`.
|
| >>> odoo.db.duplicate('super_admin_passwd', 'prod', 'test') # doctest: +SKIP
|
| The super administrator password is required to perform this method.
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.RPCError` (access denied / wrong database)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.RPCError` (access denied / wrong database)
| :raise: `urllib.error.URLError` (connection error)
|
| list(self)
| Return the list of the databases:
|
| >>> odoo.db.list() # doctest: +SKIP
| ['prod', 'test']
|
| *Python 2:*
|
| :return: `list` of database names
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: `list` of database names
| :raise: `urllib.error.URLError` (connection error)
|
| restore(self, password, db, dump, copy=False)
| Restore the `dump` database into the new `db` database.
| The `dump` file object can be obtained with the
| :func:`dump <DB.dump>` method.
| If `copy` is set to `True`, the restored database will have a new UUID.
|
| >>> odoo.db.restore('super_admin_passwd', 'test', dump_file) # doctest: +SKIP
|
| If you get a timeout error, increase this one before performing the
| request:
|
| >>> timeout_backup = odoo.config['timeout']
| >>> odoo.config['timeout'] = 7200 # Timeout set to 2 hours
| >>> odoo.db.restore('super_admin_passwd', 'test', dump_file) # doctest: +SKIP
| >>> odoo.config['timeout'] = timeout_backup
|
| The super administrator password is required to perform this method.
|
| *Python 2:*
|
| :raise: :class:`odoorpc.error.RPCError`
| (access denied / database already exists)
| :raise: :class:`odoorpc.error.InternalError` (dump file closed)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :raise: :class:`odoorpc.error.RPCError`
| (access denied / database already exists)
| :raise: :class:`odoorpc.error.InternalError` (dump file closed)
| :raise: `urllib.error.URLError` (connection error)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
odoorpc.db.encode2bytes
Python Library Documentation: function encode2bytes in module odoorpc.db encode2bytes(data)
odoorpc.db.v
Python Library Documentation: function v in module odoorpc.tools
v(version)
Convert a version string to a tuple. The tuple can be use to compare
versions between them.
>>> from odoorpc.tools import v
>>> v('7.0')
[7, 0]
>>> v('6.1')
[6, 1]
>>> v('7.0') < v('6.1')
False
:return: the version as tuple
odoorpc.env.Environment
Python Library Documentation: class Environment in module odoorpc.env
class Environment(builtins.object)
| Environment(odoo, db, uid, context)
|
| An environment wraps data like the user ID, context or current database
| name, and provides an access to data model proxies.
|
| .. doctest::
| :options: +SKIP
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO('localhost')
| >>> odoo.login('db_name', 'admin', 'password')
| >>> odoo.env
| Environment(db='db_name', uid=1, context={'lang': 'fr_FR', 'tz': 'Europe/Brussels', 'uid': 1})
|
| .. doctest::
| :hide:
|
| >>> odoo.env
| Environment(db=..., uid=..., context=...)
|
| Methods defined here:
|
| __call__(self, context=None)
| Return an environment based on `self` with a different
| user context.
|
| __contains__(self, model)
| Check if the given `model` exists on the server.
|
| >>> 'res.partner' in odoo.env
| True
|
| :return: `True` or `False`
|
| __getitem__(self, model)
| Return the model class corresponding to `model`.
|
| >>> Partner = odoo.env['res.partner']
| >>> Partner
| Model('res.partner')
|
| :return: a :class:`odoorpc.models.Model` class
|
| __init__(self, odoo, db, uid, context)
| Initialize self. See help(type(self)) for accurate signature.
|
| __repr__(self)
| Return repr(self).
|
| commit(self)
| Commit dirty records to the server. This method is automatically
| called when the `auto_commit` option is set to `True` (default).
| It can be useful to set the former option to `False` to get better
| performance by reducing the number of RPC requests generated.
|
| With `auto_commit` set to `True` (default behaviour), each time a value
| is set on a record field a RPC request is sent to the server to update
| the record:
|
| .. doctest::
|
| >>> user = odoo.env.user
| >>> user.name = "Joe" # write({'name': "Joe"})
| >>> user.email = "joe@odoo.net" # write({'email': "joe@odoo.net"})
|
| With `auto_commit` set to `False`, changes on a record are sent all at
| once when calling the :func:`commit` method:
|
| .. doctest::
|
| >>> odoo.config['auto_commit'] = False
| >>> user = odoo.env.user
| >>> user.name = "Joe"
| >>> user.email = "joe@odoo.net"
| >>> user in odoo.env.dirty
| True
| >>> odoo.env.commit() # write({'name': "Joe", 'email': "joe@odoo.net"})
| >>> user in odoo.env.dirty
| False
|
| Only one RPC request is generated in the last case.
|
| invalidate(self)
| Invalidate the cache of records.
|
| ref(self, xml_id)
| Return the record corresponding to the given `xml_id` (also called
| external ID).
| Raise an :class:`RPCError <odoorpc.error.RPCError>` if no record
| is found.
|
| .. doctest::
|
| >>> odoo.env.ref('base.lang_en')
| Recordset('res.lang', [1])
|
| :return: a :class:`odoorpc.models.Model` instance (recordset)
| :raise: :class:`odoorpc.error.RPCError`
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| context
| The context of the user connected.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.env.context
| {'lang': 'en_US', 'tz': 'Europe/Brussels', 'uid': 2}
|
| .. doctest::
| :hide:
|
| >>> from pprint import pprint as pp
| >>> pp(odoo.env.context)
| {'lang': 'en_US', 'tz': 'Europe/Brussels', 'uid': ...}
|
| db
| The database currently used.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.env.db
| 'db_name'
|
| .. doctest::
| :hide:
|
| >>> odoo.env.db == DB
| True
|
| dirty
| .. warning::
|
| This property is used internally and should not be used directly.
| As such, it should not be referenced in the user documentation.
|
| List records having local changes.
| These changes can be committed to the server with the :func:`commit`
| method, or invalidated with :func:`invalidate`.
|
| lang
| Return the current language code.
|
| .. doctest::
|
| >>> odoo.env.lang
| 'en_US'
|
| registry
| The data model registry. It is a mapping between a model name and
| its corresponding proxy used to generate records.
| As soon as a model is needed the proxy is added to the registry. This
| way the model proxy is ready for a further use (avoiding costly `RPC`
| queries when browsing records through relations).
|
| .. doctest::
| :hide:
|
| >>> odoo.env.registry.clear()
|
| >>> odoo.env.registry
| {}
| >>> odoo.env.user.company_id.name # 'res.users' and 'res.company' Model proxies will be fetched
| 'YourCompany'
| >>> from pprint import pprint
| >>> pprint(odoo.env.registry)
| {'res.company': Model('res.company'), 'res.users': Model('res.users')}
|
| If you need to regenerate the model proxy, simply delete it from the
| registry:
|
| >>> del odoo.env.registry['res.company']
|
| To delete all model proxies:
|
| >>> odoo.env.registry.clear()
| >>> odoo.env.registry
| {}
|
| uid
| The user ID currently logged.
|
| .. doctest::
| :options: +SKIP
|
| >>> odoo.env.uid
| 1
|
| .. doctest::
| :hide:
|
| >>> odoo.env.uid in [1, 2]
| True
|
| user
| Return the current user (as a record).
|
| .. doctest::
| :options: +SKIP
|
| >>> user = odoo.env.user
| >>> user
| Recordset('res.users', [2])
| >>> user.name
| 'Mitchell Admin'
|
| .. doctest::
| :hide:
|
| >>> user = odoo.env.user
| >>> user.id in [1, 2]
| True
| >>> 'Admin' in user.name
| True
|
| :return: a :class:`odoorpc.models.Model` instance
| :raise: :class:`odoorpc.error.RPCError`
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
odoorpc.env.FIELDS_RESERVED
Python Library Documentation: list object class list(object) | list(iterable=(), /) | | Built-in mutable sequence. | | If no argument is given, the constructor creates a new empty list. | The argument must be an iterable if specified. | | Methods defined here: | | __add__(self, value, /) | Return self+value. | | __contains__(self, key, /) | Return bool(key in self). | | __delitem__(self, key, /) | Delete self[key]. | | __eq__(self, value, /) | Return self==value. | | __ge__(self, value, /) | Return self>=value. | | __getattribute__(self, name, /) | Return getattr(self, name). | | __getitem__(self, index, /) | Return self[index]. | | __gt__(self, value, /) | Return self>value. | | __iadd__(self, value, /) | Implement self+=value. | | __imul__(self, value, /) | Implement self*=value. | | __init__(self, /, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | __iter__(self, /) | Implement iter(self). | | __le__(self, value, /) | Return self<=value. | | __len__(self, /) | Return len(self). | | __lt__(self, value, /) | Return self<value. | | __mul__(self, value, /) | Return self*value. | | __ne__(self, value, /) | Return self!=value. | | __repr__(self, /) | Return repr(self). | | __reversed__(self, /) | Return a reverse iterator over the list. | | __rmul__(self, value, /) | Return value*self. | | __setitem__(self, key, value, /) | Set self[key] to value. | | __sizeof__(self, /) | Return the size of the list in memory, in bytes. | | append(self, object, /) | Append object to the end of the list. | | clear(self, /) | Remove all items from list. | | copy(self, /) | Return a shallow copy of the list. | | count(self, value, /) | Return number of occurrences of value. | | extend(self, iterable, /) | Extend list by appending elements from the iterable. | | index(self, value, start=0, stop=9223372036854775807, /) | Return first index of value. | | Raises ValueError if the value is not present. | | insert(self, index, object, /) | Insert object before index. | | pop(self, index=-1, /) | Remove and return item at index (default last). | | Raises IndexError if list is empty or index is out of range. | | remove(self, value, /) | Remove first occurrence of value. | | Raises ValueError if the value is not present. | | reverse(self, /) | Reverse *IN PLACE*. | | sort(self, /, *, key=None, reverse=False) | Sort the list in ascending order and return None. | | The sort is in-place (i.e. the list itself is modified) and stable (i.e. the | order of two equal elements is maintained). | | If a key function is given, apply it once to each list item and sort them, | ascending or descending, according to their function values. | | The reverse flag can be set to sort in descending order. | | ---------------------------------------------------------------------- | Class methods defined here: | | __class_getitem__(...) | See PEP 585 | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Data and other attributes defined here: | | __hash__ = None
odoorpc.env.Model
Python Library Documentation: class Model in module odoorpc.models
class Model(BaseModel)
| Base class for all data model proxies.
|
| .. note::
| All model proxies (based on this class) are generated by an
| :class:`environment <odoorpc.env.Environment>`
| (see the :attr:`odoorpc.ODOO.env` property).
|
| .. doctest::
| :options: +SKIP
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO('localhost', port=8069)
| >>> odoo.login('db_name', 'admin', 'password')
| >>> User = odoo.env['res.users']
| >>> User
| Model('res.users')
|
| .. doctest::
| :hide:
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO(HOST, protocol=PROTOCOL, port=PORT)
| >>> odoo.login(DB, USER, PWD)
| >>> User = odoo.env['res.users']
| >>> User
| Model('res.users')
|
| Use this data model proxy to call any method:
|
| .. doctest::
| :options: +SKIP
|
| >>> User.name_get([2]) # Use any methods from the model class
| [[1, 'Mitchell Admin']]
|
| .. doctest::
| :hide:
|
| >>> from odoorpc.tools import v
| >>> uid = 1
| >>> if v(VERSION) >= v('12.0'):
| ... uid = 2
| >>> data = User.name_get([uid])
| >>> 'Admin' in data[0][1]
| True
|
| Get a recordset:
|
| .. doctest::
| :options: +SKIP
|
| >>> user = User.browse(2)
| >>> user.name
| 'Mitchell Admin'
|
| .. doctest::
| :hide:
|
| >>> from odoorpc.tools import v
| >>> uid = 1
| >>> if v(VERSION) >= v('12.0'):
| ... uid = 2
| >>> user = User.browse(uid)
| >>> 'Admin' in user.name
| True
|
| And call any method from it, it will be automatically applied on the
| current record:
|
| .. doctest::
| :options: +SKIP
|
| >>> user.name_get() # No IDs in parameter, the method is applied on the current recordset
| [[1, 'Mitchell Admin']]
|
|
| .. doctest::
| :hide:
|
| >>> data = user.name_get()
| >>> 'Admin' in data[0][1]
| True
|
| .. warning::
|
| Excepted the :func:`browse <odoorpc.models.Model.browse>` method,
| method calls are purely dynamic. As long as you know the signature of
| the model method targeted, you will be able to use it
| (see the :ref:`tutorial <tuto-execute-queries>`).
|
| Method resolution order:
| Model
| BaseModel
| builtins.object
|
| Methods defined here:
|
| __eq__(self, other)
| Return self==value.
|
| __getattr__(self, method)
| Provide a dynamic access to a RPC *instance* method (which applies
| on the current recordset).
|
| .. doctest::
|
| >>> Partner = odoo.env['res.partner']
| >>> Partner.write([1], {'name': 'YourCompany'}) # Class method
| True
| >>> partner = Partner.browse(1)
| >>> partner.write({'name': 'YourCompany'}) # Instance method
| True
|
| __getitem__(self, key)
| If `key` is an integer or a slice, return the corresponding record
| selection as a recordset.
|
| __hash__(self, /) from builtins.object
| Return hash(self).
|
| __iadd__(self, records)
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| __int__(self)
|
| __isub__(self, records)
|
| __iter__(self)
| Return an iterator over `self`.
|
| __len__(self)
|
| __ne__(self, other)
| Return self!=value.
|
| __nonzero__(self)
|
| __repr__(self)
| Return repr(self).
|
| ----------------------------------------------------------------------
| Class methods defined here:
|
| browse(ids)
| Browse one or several records (if `ids` is a list of IDs).
|
| .. doctest::
|
| >>> odoo.env['res.partner'].browse(1)
| Recordset('res.partner', [1])
|
| .. doctest::
| :options: +SKIP
|
| >>> [partner.name for partner in odoo.env['res.partner'].browse([1, 3])]
| ['YourCompany', 'Mitchell Admin']
|
| .. doctest::
| :hide:
|
| >>> names = [partner.name for partner in odoo.env['res.partner'].browse([1, 3])]
| >>> 'YourCompany' in names[0]
| True
| >>> 'Admin' in names[1]
| True
|
| A list of data types returned by such record fields are
| available :ref:`here <fields>`.
|
| :return: a :class:`Model <odoorpc.models.Model>`
| instance (recordset)
| :raise: :class:`odoorpc.error.RPCError`
|
| with_context(*args, **kwargs)
| Return a model (or recordset) equivalent to the current model
| (or recordset) attached to an environment with another context.
| The context is taken from the current environment or from the
| positional arguments `args` if given, and modified by `kwargs`.
|
| Thus, the following two examples are equivalent:
|
| .. doctest::
|
| >>> Product = odoo.env['product.product']
| >>> Product.with_context(lang='fr_FR')
| Model('product.product')
|
| .. doctest::
|
| >>> context = Product.env.context
| >>> Product.with_context(context, lang='fr_FR')
| Model('product.product')
|
| This method is very convenient for example to search records
| whatever their active status are (active/inactive):
|
| .. doctest::
|
| >>> all_product_ids = Product.with_context(active_test=False).search([])
|
| Or to update translations of a recordset:
|
| .. doctest::
|
| >>> product_en = Product.browse(1)
| >>> product_en.env.lang
| 'en_US'
| >>> product_en.name = "My product" # Update the english translation
| >>> product_fr = product_en.with_context(lang='fr_FR')
| >>> product_fr.env.lang
| 'fr_FR'
| >>> product_fr.name = "Mon produit" # Update the french translation
|
| with_env(env)
| Return a model (or recordset) equivalent to the current model
| (or recordset) attached to `env`.
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| env
| The environment used for this model/recordset.
|
| id
| ID of the record (or the first ID of a recordset).
|
| ids
| IDs of the recorset.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __metaclass__ = <class 'odoorpc.models.MetaModel'>
| Define class methods for the :class:`Model` class.
|
|
| ----------------------------------------------------------------------
| Data descriptors inherited from BaseModel:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
odoorpc.env.v
Python Library Documentation: function v in module odoorpc.tools
v(version)
Convert a version string to a tuple. The tuple can be use to compare
versions between them.
>>> from odoorpc.tools import v
>>> v('7.0')
[7, 0]
>>> v('6.1')
[6, 1]
>>> v('7.0') < v('6.1')
False
:return: the version as tuple
odoorpc.report.Report
Python Library Documentation: class Report in module odoorpc.report
class Report(builtins.object)
| Report(odoo)
|
| The `Report` class represents the report management service.
|
| It provides methods to list and download available reports from the server.
|
| .. note::
| This service have to be used through the :attr:`odoorpc.ODOO.report`
| property.
|
| .. doctest::
| :options: +SKIP
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO('localhost', port=8069)
| >>> odoo.login('odoorpc_test', 'admin', 'password')
| >>> odoo.report
| <odoorpc.report.Report object at 0x7f82fe7a1d50>
|
| .. doctest::
| :hide:
|
| >>> import odoorpc
| >>> odoo = odoorpc.ODOO(HOST, protocol=PROTOCOL, port=PORT)
| >>> odoo.login(DB, USER, PWD)
| >>> odoo.report
| <odoorpc.report.Report object at ...>
|
| Methods defined here:
|
| __init__(self, odoo)
| Initialize self. See help(type(self)) for accurate signature.
|
| download(self, name, ids, datas=None, context=None)
| Download a report from the server and return it as a remote file.
|
| Warning: this feature is not supported for Odoo >= 14 (CSRF token required).
|
| For instance, to download the "Quotation / Order" report of sale orders
| identified by the IDs ``[2, 3]``:
|
| .. doctest::
| :options: +SKIP
|
| >>> report = odoo.report.download('sale.report_saleorder', [2, 3])
|
| .. doctest::
| :hide:
|
| >>> from odoorpc.tools import v
| >>> if v(VERSION) < v('14.0'):
| ... report = odoo.report.download('sale.report_saleorder', [2])
|
| Write it on the file system:
|
| .. doctest::
| :options: +SKIP
|
| >>> with open('sale_orders.pdf', 'wb') as report_file:
| ... report_file.write(report.read())
| ...
|
| .. doctest::
| :hide:
|
| >>> from odoorpc.tools import v
| >>> if v(VERSION) < v('14.0'):
| ... with open('sale_orders.pdf', 'wb') as report_file:
| ... fileno = report_file.write(report.read()) # Python 3
| ...
|
| *Python 2:*
|
| :return: `io.BytesIO`
| :raise: :class:`odoorpc.error.RPCError` (wrong parameters)
| :raise: `ValueError` (received invalid data)
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: `io.BytesIO`
| :raise: :class:`odoorpc.error.RPCError` (wrong parameters)
| :raise: `ValueError` (received invalid data)
| :raise: `urllib.error.URLError` (connection error)
|
| list(self)
| List available reports from the server.
|
| It returns a dictionary with reports classified by data model:
|
| .. doctest::
| :options: +SKIP
|
| >>> from odoorpc.tools import v
| >>> inv_model = 'account.move'
| >>> if v(VERSION) < v('13.0'):
| ... inv_model = 'account.invoice'
| >>> odoo.report.list()[inv_model]
| [{'name': u'Duplicates',
| 'report_name': u'account.account_invoice_report_duplicate_main',
| 'report_type': u'qweb-pdf'},
| {'name': 'Invoices',
| 'report_type': 'qweb-pdf',
| 'report_name': 'account.report_invoice'}]
|
| .. doctest::
| :hide:
|
| >>> from odoorpc.tools import v
| >>> inv_model = 'account.move'
| >>> if v(VERSION) < v('13.0'):
| ... inv_model = 'account.invoice'
| >>> from pprint import pprint as pp
| >>> any(data['report_name'] == 'account.report_invoice'
| ... for data in odoo.report.list()[inv_model])
| True
|
| *Python 2:*
|
| :return: `list` of dictionaries
| :raise: `urllib2.URLError` (connection error)
|
| *Python 3:*
|
| :return: `list` of dictionaries
| :raise: `urllib.error.URLError` (connection error)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
odoorpc.report.encode2bytes
Python Library Documentation: function encode2bytes in module odoorpc.report encode2bytes(data)
odoorpc.report.get_encodings
Python Library Documentation: function get_encodings in module odoorpc.tools
get_encodings(hint_encoding='utf-8')
Used to try different encoding.
Function copied from Odoo 11.0 (odoo.loglevels.get_encodings).
This piece of code is licensed under the LGPL-v3 and so it is compatible
with the LGPL-v3 license of OdooRPC::
- https://github.com/odoo/odoo/blob/11.0/LICENSE
- https://github.com/odoo/odoo/blob/11.0/COPYRIGHT
odoorpc.report.v
Python Library Documentation: function v in module odoorpc.tools
v(version)
Convert a version string to a tuple. The tuple can be use to compare
versions between them.
>>> from odoorpc.tools import v
>>> v('7.0')
[7, 0]
>>> v('6.1')
[6, 1]
>>> v('7.0') < v('6.1')
False
:return: the version as tuple
odoorpc.error.Error
Python Library Documentation: class Error in module odoorpc.error class Error(builtins.Exception) | Base class for exception. | | Method resolution order: | Error | builtins.Exception | builtins.BaseException | builtins.object | | Data descriptors defined here: | | __weakref__ | list of weak references to the object | | ---------------------------------------------------------------------- | Methods inherited from builtins.Exception: | | __init__(self, /, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | ---------------------------------------------------------------------- | Static methods inherited from builtins.Exception: | | __new__(*args, **kwargs) class method of builtins.Exception | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Methods inherited from builtins.BaseException: | | __getattribute__(self, name, /) | Return getattr(self, name). | | __reduce__(...) | Helper for pickle. | | __repr__(self, /) | Return repr(self). | | __setstate__(...) | | __str__(self, /) | Return str(self). | | add_note(...) | Exception.add_note(note) -- | add a note to the exception | | with_traceback(...) | Exception.with_traceback(tb) -- | set self.__traceback__ to tb and return self. | | ---------------------------------------------------------------------- | Data descriptors inherited from builtins.BaseException: | | __cause__ | exception cause | | __context__ | exception context | | __dict__ | | __suppress_context__ | | __traceback__ | | args
odoorpc.error.InternalError
Python Library Documentation: class InternalError in module odoorpc.error class InternalError(Error) | Exception raised for errors occurring during an internal operation. | | Method resolution order: | InternalError | Error | builtins.Exception | builtins.BaseException | builtins.object | | Data descriptors inherited from Error: | | __weakref__ | list of weak references to the object | | ---------------------------------------------------------------------- | Methods inherited from builtins.Exception: | | __init__(self, /, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | ---------------------------------------------------------------------- | Static methods inherited from builtins.Exception: | | __new__(*args, **kwargs) class method of builtins.Exception | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Methods inherited from builtins.BaseException: | | __getattribute__(self, name, /) | Return getattr(self, name). | | __reduce__(...) | Helper for pickle. | | __repr__(self, /) | Return repr(self). | | __setstate__(...) | | __str__(self, /) | Return str(self). | | add_note(...) | Exception.add_note(note) -- | add a note to the exception | | with_traceback(...) | Exception.with_traceback(tb) -- | set self.__traceback__ to tb and return self. | | ---------------------------------------------------------------------- | Data descriptors inherited from builtins.BaseException: | | __cause__ | exception cause | | __context__ | exception context | | __dict__ | | __suppress_context__ | | __traceback__ | | args
odoorpc.error.RPCError
Python Library Documentation: class RPCError in module odoorpc.error
class RPCError(Error)
| RPCError(message, info=False)
|
| Exception raised for errors related to RPC queries.
| Error details (like the `Odoo` server traceback) are available through the
| `info` attribute:
|
| .. doctest::
| :options: +SKIP
|
| >>> from pprint import pprint as pp
| >>> try:
| ... odoo.execute('res.users', 'wrong_method')
| ... except odoorpc.error.RPCError as exc:
| ... pp(exc.info)
| ...
| {'code': 200,
| 'data': {'arguments': ["type object 'res.users' has no attribute 'wrong_method'"],
| 'debug': 'Traceback (most recent call last):\n File ...',
| 'exception_type': 'internal_error',
| 'message': "'res.users' object has no attribute 'wrong_method'",
| 'name': 'exceptions.AttributeError'}
| 'message': 'Odoo Server Error'}
|
| .. doctest::
| :hide:
|
| >>> from pprint import pprint as pp
| >>> try:
| ... odoo.execute('res.users', 'wrong_method')
| ... except odoorpc.error.RPCError as exc:
| ... exc.info['code'] == 200
| ... 'message' in exc.info
| ... exc.info['data']['arguments'] in [
| ... ["'res.users' object has no attribute 'wrong_method'"], # >= 8.0
| ... ["type object 'res.users' has no attribute 'wrong_method'"], # >= 10.0
| ... ]
| ... exc.info['data']['debug'].startswith('Traceback (most recent call last):\n File')
| ... exc.info['data']['message'] in [
| ... "'res.users' object has no attribute 'wrong_method'", # >= 8.0
| ... "type object 'res.users' has no attribute 'wrong_method'", # >= 10.0
| ... ]
| ... exc.info['data']['name'] in [
| ... 'exceptions.AttributeError',
| ... 'builtins.AttributeError',
| ... ]
| ...
| True
| True
| True
| True
| True
| True
|
| Method resolution order:
| RPCError
| Error
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods defined here:
|
| __init__(self, message, info=False)
| Initialize self. See help(type(self)) for accurate signature.
|
| __repr__(self)
| Return repr(self).
|
| __str__(self)
| Return str(self).
|
| __unicode__(self)
|
| ----------------------------------------------------------------------
| Data descriptors inherited from Error:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.Exception:
|
| __new__(*args, **kwargs) class method of builtins.Exception
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __reduce__(...)
| Helper for pickle.
|
| __setstate__(...)
|
| add_note(...)
| Exception.add_note(note) --
| add a note to the exception
|
| with_traceback(...)
| Exception.with_traceback(tb) --
| set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
| exception cause
|
| __context__
| exception context
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args