OERPLib is a RPC client library to OpenERP server written in Python. It aims to provide an easy way to remotely pilot an OpenERP server.
How does it work? See below:
import oerplib
# Prepare the connection to the OpenERP server
oerp = oerplib.OERP('localhost', protocol='xmlrpc', port=8069)
# Check available databases
print(oerp.db.list())
# Login (the object returned is a browsable record)
user = oerp.login('user', 'passwd', 'db_name')
print(user.name) # name of the user connected
print(user.company_id.name) # the name of its company
# Simple 'raw' query
user_data = oerp.execute('res.users', 'read', [user.id])
print(user_data)
# Use all methods of a model class
order_obj = oerp.get('sale.order')
order_ids = order_obj.search([])
for order in order_obj.browse(order_ids):
print(order.name)
products = [line.product_id.name for line in order.order_line]
print(products)
# Update data through a browsable record
user.name = "Brian Jones"
oerp.write_record(user)
For more details and features, see the tutorials, the Frequently Asked Questions (FAQ) and the API reference sections.
You can install OERPLib with the easy_install tool:
$ easy_install oerplib
Or with pip:
$ pip install oerplib
An alternative way is to download the tarball from Python Package Index page, and install manually (replace X.Y.Z accordingly):
$ wget http://pypi.python.org/packages/source/O/OERPLib/OERPLib-X.Y.Z.tar.gz
$ tar xzvf OERPLib-X.Y.Z.tar.gz
$ cd OERPLib-X.Y.Z
$ python setup.py install
No dependency is required except pydot for some methods of the inspect service (optional).
The project is hosted on Launchpad. To get the current development branch (the trunk), just type:
$ bzr branch lp:oerplib
For the last version of a stable branch (replace X.Y accordingly):
$ bzr branch lp:oerplib/X.Y
New in version 0.4.0.
Unit tests depends on unittest2 (Python 2.3+) or unittest (Python 2.7 and 3.x), and argparse.
To run unit tests from the project directory, run the following command:
$ PYTHONPATH=.:$PYTHONPATH ./tests/runtests.py --help
Then, set your parameters in order to indicate the OpenERP server on which you want to perform the tests, for instance:
$ PYTHONPATH=.:$PYTHONPATH ./tests/runtests.py --create_db --server 192.168.1.4 --test_xmlrpc --xmlrpc_port 8069
The name of the database created is oerplib-test by default.
You need an instance of the OERP class to dialog with an OpenERP server. Let’s pretend that you want to connect as admin on the db_name database of the local OpenERP server (with the XML-RPC service which listens on port 8071). First, prepare the connection:
>>> import oerplib
>>> oerp = oerplib.OERP(server='localhost', protocol='xmlrpc', port=8071)
You can also specify the default database to use with the database parameter:
>>> oerp = oerplib.OERP(server='localhost', database='db_name', protocol='xmlrpc', port=8071)
To check databases available, use the oerp.db attribute with the list method:
>>> oerp.db.list()
['db_name', 'db_name2', ...]
The connection is ready, you are able to log in on the server with the account of your choice:
>>> user = oerp.login(user='admin', passwd='admin')
Or, if no default database was specified before:
>>> user = oerp.login(user='admin', passwd='admin', database='db_name')
The login method returns an object representing the user connected. It is built from the server-side model res.users, and all its informations are accessible (see Browse records section):
>>> print(user.name) # print the full name of the user
>>> print(user.company_id.name) # print the name of its company
Now you are connected, you can easily execute any kind of RPC queries on the the OpenERP server (execute model methods, trigger workflow, download reports, and handle wizards).
The basic method to execute queries (related to the /object RPC service) is execute. It takes at least two parameters (model name and the method name) following by variable parameters according to the method called. Example:
>>> order_data = oerp.execute('sale.order', 'read', [1], ['name'])
This instruction will call the read method of the model sale.order with the parameters [1] (list of record IDs) and ['name'] (list of fields to return).
However, for usual methods such as create, read, write, unlink and search there are convenient shortcuts available (see oerplib.OERP):
>>> partner_id = oerp.create('res.partner', {'name': 'Jacky Bob', 'lang': 'fr_FR'})
>>> partner_data = oerp.read('res.partner', [partner_id], ['name'])
>>> oerp.write('res.partner', [partner_id], {'name': 'Charly Bob'})
True
>>> partner_ids = oerp.search('res.partner', [('name', 'ilike', 'Bob')])
>>> oerp.unlink('res.partner', [partner_id])
True
There is another way to perform all methods of a model, with the get method, which provide an API almost syntactically identical to the OpenERP server side API (see oerplib.service.osv.Model):
>>> user_obj = oerp.get('res.users')
>>> user_obj.write([1], {'name': "Dupont D."})
True
>>> context = user_obj.context_get()
>>> context
{'lang': 'fr_FR', 'tz': False}
>>> product_obj = oerp.get('product.product')
>>> product_obj.name_get([3, 4])
[[3, '[PC1] PC Basic'], [4, u'[PC2] Basic+ PC (assembl\xe9 sur commande)']]
If you run an OpenERP version 6.1 or above, the user context is automatically sent. You can disable this behaviour with the oerplib.OERP.config property:
>>> oerp.config['auto_context'] = False
>>> product_obj.name_get([3, 4]) # Without context, lang 'en_US' by default
[[3, '[PC1] Basic PC'], [4, '[PC2] Basic+ PC (assembly on order)']]
Note
The auto_context option only affect model methods.
Here is another example of how to install a module (you have to be logged as an administrator to perform this task). The button_immediate_install method used here is available since OpenERP v6.1:
>>> module_obj = oerp.get('ir.module.module')
>>> module_id = module_obj.search([('name', '=', 'purchase')])
>>> module_obj.button_immediate_install(module_id)
A great functionality of OERPLib is its ability to generate objects that are similar to browsable records found on the OpenERP server. All this is possible using the browse method:
# fetch one record
partner = oerp.browse('res.partner', 1) # Partner ID = 1
print(partner.name)
# fetch several records
for partner in oerp.browse('res.partner', [1, 2]):
print(partner.name)
From such objects, it is possible to easily explore relationships. The related records are generated on the fly:
partner = oerp.browse('res.partner', 3)
for child in partner.child_ids:
print(child.name)
You can browse objects through a model too. In fact, both methods are strictly identical, oerplib.OERP.browse() is simply a shortcut to the other:
>>> partner1 = oerp.browse('res.partner', 3)
>>> partner2 = oerp.get('res.partner').browse(3)
>>> partner1 == partner2
True
Outside relation fields, Python data types are used, like datetime.date and datetime.datetime:
>>> order = oerp.browse('purchase.order', 42)
>>> order.minimum_planned_date
datetime.datetime(2012, 3, 10, 0, 0)
>>> order.date_order
datetime.date(2012, 3, 8)
A list of data types used by browse_record fields are available here.
Update data of a browsable record is workable with the write_record method of an OERP instance. Let’s update the name of a partner:
>>> partner.name = "Caporal Jones"
>>> oerp.write_record(partner)
This is equivalent to:
>>> oerp.write('res.partner', [partner.id], {'name': "Caporal Jones"})
As see above, it’s as simple as that:
>>> partner.name = "OpenERP"
>>> oerp.write_record(partner)
Same as above, except there is a check about the value assigned. For instance, the field type of the res.partner model accept values contains in ['default', 'invoice', 'delivery', 'contact', 'other']:
>>> partner.type = 'default' # Ok
>>> partner.type = 'foobar' # Error!
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "oerplib/fields.py", line 58, in setter
value = self.check_value(value)
File "oerplib/fields.py", line 73, in check_value
field_name=self.name,
ValueError: The value 'foobar' supplied doesn't match with the possible values '['default', 'invoice', 'delivery', 'contact', 'other']' for the 'type' field
You can also update a many2one field, with either an ID or a browsable record:
>>> partner.parent_id = 1 # with an ID
>>> oerp.write_record(partner)
>>> parent = oerp.browse('res.partner', 1) # with a browsable record
>>> partner.parent_id = parent
>>> oerp.write_record(partner)
You can’t put any ID or browsable record, a check is made on the relationship to ensure data integrity:
>>> user = oerp.browse('res.users', 1)
>>> partner = oerp.browse('res.partner', 2)
>>> partner.parent_id = user
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "oerplib/fields.py", line 128, in setter
o_rel = self.check_value(o_rel)
File "oerplib/fields.py", line 144, in check_value
field_name=self.name))
ValueError: Instance of 'res.users' supplied doesn't match with the relation 'res.partner' of the 'parent_id' field.
one2many and many2many fields can be updated by providing a list of tuple as specified in the OpenERP documentation, a list of records, a list of record IDs or an empty list or False:
With a standard OpenERP tuple, no magic here:
>>> user = oerp.get('res.users').browse(1)
>>> user.groups_id = [(6, 0, [8, 5, 6, 4])]
>>> oerp.write_record(user)
With a list of records:
>>> user = oerp.get('res.users').browse(1)
>>> groups = oerp.get('res.groups').browse([8, 5, 6, 4])
>>> user.groups_id = list(groups)
>>> oerp.write_record(user)
With a list of record IDs:
>>> user = oerp.get('res.users').browse(1)
>>> user.groups_id = [8, 5, 6, 4]
>>> oerp.write_record(user)
The last two examples are equivalent to the first (they generate a (6, 0, IDS) tuple).
However, if you set an empty list or False, a (5, ) tuple will be generated to cut the relation between records:
>>> user = oerp.get('res.users').browse(1)
>>> user.groups_id = []
>>> list(user.groups_id)
[]
>>> user.__data__['updated_values']['groups_id']
[(5,)]
>>> user.groups_id = False
>>> list(user.groups_id)
[]
>>> user.__data__['updated_values']['groups_id']
[(5,)]
Another facility provided by OERPLib is adding and removing objects using Python operators += and -=. As usual, you can add an ID, a record, or a list of them:
With a list of records:
>>> user = oerp.get('res.users').browse(1)
>>> groups = oerp.get('res.groups').browse([4, 5])
>>> user.groups_id += list(groups)
>>> [g.id for g in user.groups_id]
[1, 2, 3, 4, 5]
With a list of record IDs:
>>> user.groups_id += [4, 5]
>>> [g.id for g in user.groups_id]
[1, 2, 3, 4, 5]
With an ID only:
>>> user.groups_id -= 4
>>> [g.id for g in user.groups_id]
[1, 2, 3, 5]
With a record only:
>>> group = oerp.get('res.groups').browse(5)
>>> user.groups_id -= group
>>> [g.id for g in user.groups_id]
[1, 2, 3]
To update a reference field, you have to use either a string or a browsable record as below:
>>> helpdesk = oerp.browse('crm.helpdesk', 1)
>>> helpdesk.ref = 'res.partner,1' # with a string with the format '{relation},{id}'
>>> oerp.write_record(helpdesk)
>>> partner = oerp.browse('res.partner', 1)
>>> helpdesk.ref = partner # with a browsable record
>>> oerp.write_record(helpdesk)
A check is made on the relation name:
>>> helpdesk.ref = 'foo.bar,42'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "oerplib/service/osv/fields.py", line 213, in __set__
value = self.check_value(value)
File "oerplib/service/osv/fields.py", line 244, in check_value
self._check_relation(relation)
File "oerplib/service/osv/fields.py", line 225, in _check_relation
field_name=self.name,
ValueError: The value 'foo.bar' supplied doesn't match with the possible values '['res.partner', 'calendar.event', 'crm.meeting']' for the 'ref' field
date and datetime fields accept either string values or datetime.date/datetime.datetime objects.
With datetime.date and datetime.datetime objects:
>>> import datetime
>>> order = oerp.browse('purchase.order', 42)
>>> order.date_order = datetime.date(2011, 9, 20)
>>> order.minimum_planned_date = datetime.datetime(2011, 9, 20, 12, 31, 24)
>>> oerp.write_record(order)
With formated strings:
>>> order.date_order = "2011-09-20" # %Y-%m-%d
>>> order.minimum_planned_date = "2011-09-20 12:31:24" # %Y-%m-%d %H:%M:%S
>>> oerp.write_record(order)
As always, a wrong type will raise an exception:
>>> order.date_order = "foobar"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "oerplib/fields.py", line 187, in setter
value = self.check_value(value)
File "oerplib/fields.py", line 203, in check_value
self.pattern))
ValueError: Value not well formatted, expecting '%Y-%m-%d' format
Another nice functionnality is the reports generation (related to the /report RPC service) with the report method. You have to supply the name of the report, the name of the model and the ID of the record related:
>>> oerp.report('sale.order', 'sale.order', 1)
'/tmp/oerplib_uJ8Iho.pdf'
>>> oerp.report('webkitaccount.invoice', 'account.invoice', 1)
'/tmp/oerplib_r1W9jG.pdf'
The method will return the path to the generated temporary report file.
You can manage OpenERP databases with the oerplib.OERP.db property. It offers you a dynamic access to all methods of the /db RPC service in order to list, create, drop, dump, restore databases and so on.
Note
You have not to be logged in to perform database management tasks. Instead, you have to use the “super admin” password.
Prepare a connection:
>>> import oerplib
>>> oerp = oerplib.OERP(server='localhost')
At this point, you are able to list databases of this server:
>>> oerp.db.list()
[]
Let’s create a new database:
>>> database_id = oerp.db.create('super_admin_passwd', 'test_db', False, 'fr_FR', 'admin')
The creation process may take some time on the OpenERP server, and you have to wait before using the new database. The state of the creation process is returned by the get_progress method:
>>> database_id = oerp.db.create('super_admin_passwd', 'test_db', False, 'fr_FR', 'admin')
>>> while not oerp.db.get_progress('super_admin_passwd', database_id)[0]
... pass
>>> oerp.login('admin', 'admin', 'test_db')
However, OERPLib simplifies this by providing the create_and_wait method:
>>> oerp.db.create_and_wait('super_admin_passwd', 'test_db', False, 'fr_FR', 'admin')
[{'login': u'admin', 'password': u'admin', 'name': u'Administrator'},
{'login': u'demo', 'password': u'demo', 'name': u'Demo User'}]
Some documentation about methods offered by the OpenERP /db RPC service is available here.
Note
This functionality requires the installation of pydot.
The relations method will help you to generate a graphic of such relationships:
>>> graph = oerp.inspect.relations(['res.partner'])
>>> graph.write('rel_res_partner_v1.png', format='png')
Legend:
Element | Meaning |
---|---|
partner_id |
many2one |
bank_ids |
one2many |
company_ids |
many2many |
[R] |
Field required |
[F] |
Field function (readonly) |
[Fw] |
Field function (writable) |
[Fs] |
Field function (searchable) |
By default, only the direct relationships of the model res.partner are shown (this behaviour can be changed with the maxdepth parameter), and model attributes are hidden. You can control the displayed models through the whitelist and blacklist parameters. For instance, assume that you only want data models whose name begins with res.partner excluding the res.partner.bank model:
>>> graph = oerp.inspect.relations(['res.partner'], whitelist=['res.partner*'], blacklist=['res.partner.bank']) # Notice the use of wildcard here
>>> graph.write('rel_res_partner_v2.png', format='png')
Note
The blacklist has a higher priority than the whitelist
To display attributes, use the attrs_whitelist parameter. A wildcard is used here to show attributes of all models (but you can specify which models you want):
>>> graph = oerp.inspect.relations(['res.partner'], whitelist=['res.partner*'], blacklist=['res.partner.bank'], attrs_whitelist=['*'])
>>> graph.write('rel_res_partner_v3.png', format='png')
To hide attributes of some models, you can use the attrs_blacklist parameter:
>>> graph = oerp.inspect.relations(['res.partner'], whitelist=['res.partner*'], blacklist=['res.partner.bank'], attrs_whitelist=['*'], attrs_blacklist=['res.partner'])
>>> graph.write('rel_res_partner_v4.png', format='png')
Also, some configuration options can be set through the config parameter. Here is how to display many2many table names:
>>> config = {'show_many2many_table': True}
>>> graph = oerp.inspect.relations(['res.partner'], whitelist=['res.partner*'], blacklist=['res.partner.bank'], config=config)
>>> graph.write('rel_res_partner_v5.png', format='png')
For more details, take a look at the relations method documentation.
Note
This functionality requires the installation of pydot.
You will be able to generate a graphic representing dependencies between all modules with the dependencies method:
>>> graph = oerp.inspect.dependencies()
>>> graph.write('dependencies_v1.png', format='png')
By default all installed modules are shown on the resulting graph, the red ones can be seen as root modules (they depend on no module in the current graph). Assume we have installed the Accounting and Finance application, and want to only display dependencies related to the account module:
>>> graph = oerp.inspect.dependencies(['account'])
>>> graph.write('dependencies_v2.png', format='png')
This time the root module is account. Modules may also contain data models. To highlight some of them among the modules, set the models and models_blacklist parameters with one or several patterns (a joker * can be used):
>>> graph = oerp.inspect.dependencies(['account'], models=['account.invoice.*'])
>>> graph.write('dependencies_v3.png', format='png')
Modules related to the matching models are shown in green (in addition to the red one). It is possible to display transient models too through the show_transient_model configuration option (displayed in gray in the following graph):
>>> config = {'show_transient_model': True}
>>> graph = oerp.inspect.dependencies(['account'], models=['account.invoice.*'], config=config)
>>> graph.write('dependencies_v4.png', format='png')
To hide “noisy” modules and restrict the resulting graph only to data models that interest you, add the restrict=True parameter:
>>> config = {'show_transient_model': True}
>>> graph = oerp.inspect.dependencies(['account'], ['account.invoice.*'], restrict=True, config=config)
>>> graph.write('dependencies_v5.png', format='png')
Even in restricted mode, root modules which are not concerned by matching models are always displayed. Also, if no dependency can be satisfied between modules, the method will try to add one. For instance, the base module have no account.invoice.tax model, and account does not directly depends on base, so a dependency between base and account should be added to display a suitable graph:
>>> graph = oerp.inspect.dependencies(['base'], ['account.invoice.tax'], restrict=True)
>>> graph.write('dependencies_v6.png', format='png')
For more details, take a look at the dependencies method documentation.
on_change functions of a model can be listed with the scan_on_change method. Each detected function can be present on several views:
>>> oerp.inspect.scan_on_change(['res.users'])
{'res.users': {'on_change_company_id': {'base.view_users_form_simple_modif': {'company_id': ['company_id']},
'mail.view_users_form_simple_modif_mail': {'company_id': ['company_id']}},
'onchange_state': {'base.view_users_simple_form': {'state_id': ['state_id']}}}}
The dictionary returned is formatted as follows: {model: {on_change: {view_name: field: [args]}}}, e.g. the onchange_state method is set on the state_id field of the view base.view_users_simple_form, and take the same field as parameter.
Once you are authenticated with your OERP instance, you can save these connection information under a code name and use this one to quickly instanciate a new OERP class:
>>> import oerplib
>>> oerp = oerplib.OERP('localhost')
>>> user = oerp.login('admin', 'admin', 'my_database')
>>> oerp.save('foo')
By default, these informations are stored in the ~/.oerplibrc file. You can however use another file:
>>> oerp.save('foo', '~/my_own_oerplibrc')
Then, use the oerplib.OERP.load() class method:
>>> import oerplib
>>> oerp = oerplib.OERP.load('foo')
Or, if you have saved your configuration in another file:
>>> oerp = oerplib.OERP.load('foo', '~/my_own_oerplibrc')
You can check available sessions with oerplib.OERP.list(), and remove them with oerplib.OERP.remove():
>>> oerplib.OERP.list()
['foo']
>>> oerplib.OERP.remove('foo')
>>> 'foo' not in oerplib.OERP.list()
True
By default, the timeout is set to 120 seconds for all RPC requests. If your requests need a higher timeout, you can set it through the oerplib.OERP.config property:
>>> oerp.config['timeout']
120
>>> oerp.config['timeout'] = 300 # Set the timeout to 300 seconds
First, you have to connect on your OpenERP instance, and set a password for your user account in order to active the XML-RPC protocol.
Then, just use the xmlrpc+ssl protocol with the port 443:
>>> import oerplib
>>> oerp = oerplib.OERP('foobar.my.openerp.com', protocol='xmlrpc+ssl', port=443)
>>> oerp.db.server_version()
'7.saas~1'
OERPLib does not provide helpers for such methods currently. A call to an on_change method intend to be executed from a view and there is no support for that (not yet?) such as fill a form, validate it, etc...
But you can emulate an on_change by writing your own function, for instance:
def on_change(oerp, record, method, *args):
"""Update `record` with the result of the on_change `method`"""
res = oerp.execute(record.__osv__['name'], method, *args)
for k, v in res['value'].iteritems():
setattr(record, k, v)
return record
And call it on a record with the desired method and its parameters:
>>> order = oerp.get('sale.order').browse(42)
>>> order = on_change(oerp, order, 'product_id_change', ARGS...)
>>> oerp.write_record(order) # Save your record
To know what parameters to send to the on_change, the scan_on_change method can help you.
Since OpenERP 6.1, the context parameter can be sent automatically for each call to an OSV/Model method (this is the default behaviour since OERPLib 0.7). But on the side of the OpenERP server, some OSV methods have no context parameter, and OERPLib has no way to guess it, which results in an nasty exception. So you have to disable temporarily this behaviour by yourself by setting the auto_context option to False:
>>> oerp.config['auto_context'] = False # 'get()' method of 'ir.sequence' does not support the context parameter
>>> next_seq = oerp.get('ir.sequence').get('stock.lot.serial')
>>> oerp.config['auto_context'] = True # Restore the configuration
You can compare versions of OpenERP servers with the v function applied on the OERP.version property, for instance:
import oerplib
from oerplib.tools import v
for session in oerplib.OERP.list():
oerp = oerplib.OERP.load(session)
if v(oerp.version) <= v('6.1'):
pass # do some stuff
else:
pass # do something else
The table below presents the Python types returned by OERPLib for each OpenERP fields used by browse_record objects (see the browse method):
OpenERP fields | Python types used in OERPLib |
---|---|
fields.binary | basestring (str or unicode) |
fields.boolean | bool |
fields.char | basestring (str or unicode) |
fields.date | datetime.date |
fields.datetime | datetime.datetime |
fields.float | float |
fields.integer | integer |
fields.selection | basestring (str or unicode) |
fields.text | basestring (str or unicode) |
Exceptions made for relation fields:
OpenERP fields | Types used in OERPLib |
---|---|
fields.many2one | browse_record instance |
fields.one2many | generator to iterate on browse_record instances |
fields.many2many | generator to iterate on browse_record instances |
fields.reference | browse_record instance |
The oerplib module defines the OERP class.
The OERP class manage the client-side operations which are related to an OpenERP server. You can use this one to write Python programs that performs a variety of automated jobs that communicate with an OpenERP server.
You can load a pre-configured OERP session with the load() function.
Here’s a sample session using this module:
>>> import oerplib
>>> oerp = oerplib.OERP('localhost') # connect to localhost, default port
>>> user = oerp.login('admin', 'admin', 'my_database') # login returns an user object
>>> user.name
'Administrator'
>>> oerp.save('foo') # save session informations in ~/.oerplibrc
>>> oerp = oerplib.load('foo') # get a pre-configured session from ~/.oerplibrc
Return a new instance of the OERP class. The optional database parameter specifies the default database to use when the login method is called. If no database is set, the database parameter of the login method will be mandatory.
XML-RPC and Net-RPC protocols are supported. Respective values for the protocol parameter are xmlrpc, xmlrpc+ssl and netrpc.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost', protocol='xmlrpc', port=8069)
Since the version 0.7, OERPLib will try by default to detect the OpenERP server version in order to adapt its requests. However, it is possible to force the version of OpenERP with the version parameter:
>>> oerp = oerplib.OERP('localhost', version='6.0')
Raise: | oerplib.error.InternalError, oerplib.error.RPCError |
---|
Browse one or several records (if ids is a list of IDs) from model. The fields and values for such objects are generated dynamically.
>>> oerp.browse('res.partner', 1)
browse_record(res.partner, 1)
>>> [partner.name for partner in oerp.browse('res.partner', [1, 2])]
[u'Your Company', u'ASUStek']
A list of data types used by browse_record fields are available here.
Returns: | a browse_record instance |
---|---|
Returns: | a generator to iterate on browse_record instances |
Raise: | oerplib.error.RPCError |
New in version 0.6.
The common service (/common RPC service). See the oerplib.service.common.Common class.
Dictionary of available configuration options.
>>> oerp.config
{'auto_context': True, 'timeout': 120}
auto_context: if set to True, the user context will be sent automatically to every call of a model method (default: True):
New in version 0.7.
Note
This option only works on OpenERP version 6.1 and above.
>>> product_osv = oerp.get('product.product') >>> product_osv.name_get([3]) # Context sent by default ('lang': 'fr_FR' here) [[3, '[PC1] PC Basic']] >>> oerp.config['auto_context'] = False >>> product_osv.name_get([3]) # No context sent [[3, '[PC1] Basic PC']]
timeout: set the maximum timeout in seconds for a RPC request (default: 120):
New in version 0.6.
>>> oerp.config['timeout'] = 300
The context of the user connected.
>>> oerp.login('admin', 'admin')
browse_record('res.users', 1)
>>> oerp.context
{'lang': 'fr_FR', 'tz': False}
>>> oerp.context['lang'] = 'en_US'
Create a new model record with values contained in the vals dictionary.
>>> partner_id = oerp.create('res.partner', {'name': 'Jacky Bob', 'lang': 'fr_FR'})
Returns: | the ID of the new record. |
---|---|
Raise: | oerplib.error.RPCError |
The database currently used.
New in version 0.4.
The database management service (/db RPC service). See the oerplib.service.db.DB class.
Execute the workflow signal on the instance having the ID obj_id of model.
Raise: | oerplib.error.RPCError |
---|
Execute the method of model. *args parameters varies according to the method used.
>>> oerp.execute('res.partner', 'read', [1, 2], ['name'])
[{'name': u'ASUStek', 'id': 2}, {'name': u'Your Company', 'id': 1}]
Returns: | the result returned by the method called |
---|---|
Raise: | oerplib.error.RPCError |
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.
>>> oerp.execute_kw('res.partner', 'read', [[1, 2]], {'fields': ['name']})
[{'name': u'ASUStek', 'id': 2}, {'name': u'Your Company', 'id': 1}]
Warning
This method only works on OpenERP version 6.1 and above.
Returns: | the result returned by the method called |
---|---|
Raise: | oerplib.error.RPCError |
New in version 0.5.
Return a proxy of the model built from the OpenERP server (see oerplib.service.osv.Model).
Returns: | an instance of oerplib.service.osv.Model |
---|
Deprecated since version 0.7: use the __osv__ attribute instead (see BrowseRecord).
>>> partner = oerp.browse('res.partner', 1)
>>> oerp.get_osv_name(partner)
'res.partner'
Returns: | the model name of the browsable record |
---|
New in version 0.8.
The inspect service (custom service). See the oerplib.service.inspect.Inspect class.
New in version 0.8.
Return a list of all sessions available in the rc_file file:
>>> import oerplib
>>> oerplib.OERP.list()
['foo', 'bar']
Then, use the load() function with the desired session:
>>> oerp = oerplib.OERP.load('foo')
New in version 0.8.
Return a OERP session pre-configured and connected with informations identified by name:
>>> import oerplib
>>> oerp = oerplib.OERP.load('foo')
Such informations are stored with the OERP.save method.
Log in as the given user with the password passwd on the database database and return the corresponding user as a browsable record (from the res.users model). If database is not specified, the default one will be used instead.
>>> user = oerp.login('admin', 'admin', database='db_name')
>>> user.name
u'Administrator'
Returns: | the user connected as a browsable record |
---|---|
Raise: | oerplib.error.RPCError, oerplib.error.Error |
The port used.
The protocol used.
Return fields values for each model record identified by ids. If fields is not specified, all fields values will be retrieved.
>>> oerp.read('res.partner', [1, 2], ['name'])
[{'name': u'ASUStek', 'id': 2}, {'name': u'Your Company', 'id': 1}]
Returns: | list of dictionaries |
---|---|
Raise: | oerplib.error.RPCError |
Restore original values on browse_record with data fetched on the OpenERP database. As a result, all changes made locally on the record are canceled.
Raise: | oerplib.error.RPCError |
---|
New in version 0.8.
Remove the session identified by name from the rc_file file:
>>> import oerplib
>>> oerplib.OERP.remove('foo')
True
Download a report from the OpenERP server and return the path of the file.
>>> oerp.report('sale.order', 'sale.order', 1)
'/tmp/oerplib_uJ8Iho.pdf'
>>> oerp.report('sale.order', 'sale.order', [1, 2])
'/tmp/oerplib_giZS0v.pdf'
Returns: | the path to the generated temporary file |
---|---|
Raise: | oerplib.error.RPCError |
Cancel all changes made locally on the browse_record. No request to the server is executed to perform this operation. Therefore, values restored may be outdated.
New in version 0.8.
Save the session configuration under the name name. These informations are stored in the ~/.oerplibrc file by default.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost', protocol='xmlrpc', port=8069)
>>> oerp.login('admin', 'admin', 'db_name')
>>> oerp.save('foo')
Such informations can be loaded with the oerplib.load() function by returning a pre-configured session of OERP, or with the oerp command line tool supplied with oerplib.
Return a list of IDs of records matching the given criteria in args parameter. args must be of the form [('name', '=', 'John'), (...)]
>>> oerp.search('res.partner', [('name', 'like', 'Agrolait')])
[3]
Returns: | a list of IDs |
---|---|
Raise: | oerplib.error.RPCError |
The server name.
Delete model records identified by ids.
>>> oerp.unlink('res.partner', [1])
Returns: | True |
---|---|
Raise: | oerplib.error.RPCError |
New in version 0.4.
Delete the record corresponding to browse_record from the OpenERP database.
>>> partner = oerp.browse('res.partner', 1)
>>> oerp.unlink_record(partner) # unlink('res.partner', [1])
Returns: | True |
---|---|
Raise: | oerplib.error.RPCError |
The browsable record of the user connected.
>>> oerp.login('admin', 'admin') == oerp.user
True
The version of the OpenERP server.
>>> oerp.version
'7.0-20131014-231047'
New in version 0.6.
The wizard service (/wizard RPC service). See the oerplib.service.wizard.Wizard class.
Update model records identified by ids with the given values contained in the vals dictionary.
>>> oerp.write('res.users', [1], {'name': "Administrator"})
True
Returns: | True |
---|---|
Raise: | oerplib.error.RPCError |
New in version 0.4.
Update the record corresponding to browse_record by sending its values to the OpenERP database (only field values which have been changed).
>>> partner = oerp.browse('res.partner', 1)
>>> partner.name = "Test"
>>> oerp.write_record(partner) # write('res.partner', [1], {'name': "Test"})
Returns: | True |
---|---|
Raise: | oerplib.error.RPCError |
New in version 0.5.
Represent a data model from the OpenERP server.
Note
This class have to be used through the oerplib.OERP.get() method.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost')
>>> user = oerp.login('admin', 'passwd', 'database')
>>> user_obj = oerp.get('res.users')
>>> user_obj
<oerplib.service.osv.osv.Model object at 0xb75ba4ac>
>>> user_obj.name_get(user.id) # Use any methods from the model instance
[[1, 'Administrator']]
Warning
The only method implemented in this class is browse. Except this one, 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 tutorial).
Browse one or several records (if ids is a list of IDs) from model. The fields and values for such objects are generated dynamically.
>>> oerp.get('res.partner').browse(1)
browse_record(res.partner, 1)
>>> [partner.name for partner in oerp.get('res.partner').browse([1, 2])]
[u'Your Company', u'ASUStek']
A list of data types used by browse_record fields are available here.
Returns: | a browse_record instance |
---|---|
Returns: | a generator to iterate on browse_record instances |
Raise: | oerplib.error.RPCError |
Base class that all browsable records inherit from. No attributes should be defined in this class (except _id/id, __oerp__, __osv__, __data__ and Python magic methods) in order to not be conflicted with the fields defined in the model class on the OpenERP server.
A reference to the OERP object used to instanciate a browse_record is available through the __oerp__ attribute:
>>> oerp = oerplib.OERP('localhost')
>>> user = oerp.login('admin', 'admin', 'db_name')
>>> user.__oerp__ == oerp
True
The __data__ attribute is used to store some data related to the record (it is not recommended to edit them):
>>> user.__data__
{'updated_values': {},
'raw_data': {'action_id': False,
'active': True,
'company_id': [1, 'Your Company'],
...},
'values': {'action_id': False,
'active': True,
'company_id': [1, 'Your Company'],
...}}
In the same way, information about the model class and its columns may be obtained via the __osv__ attribute:
>>> user.__osv__
{'columns': {'action_id': <oerplib.service.osv.fields.Many2OneField object at 0xb75786ec>,
'active': <oerplib.service.osv.fields.ValueField object at 0xb7598b6c>,
'company_id': <oerplib.service.osv.fields.Many2OneField object at 0xb757868c>,
...},
'name': 'res.users'}
ID of the record.
New in version 0.6.
The Common class represents the /common RPC service. Lets you log in on OpenERP, and provides various utility functions.
Note
This service have to be used through the oerplib.OERP.common property.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost')
>>> oerp.common
<oerplib.service.common.Common object at 0xb76266ac>
Warning
All methods documented below are not strictly implemented in OERPLib
Method calls are purely dynamic, and the following documentation can be wrong if the API of OpenERP is changed between versions. Anyway, if you know the API used by the OpenERP server for the /common RPC service, it will work.
>>> oerp.common.login('test_db', 'admin', 'admin_passwd')
1
Returns: | the user’s ID or False |
---|
>>> oerp.common.authenticate('test_db', 'admin', 'admin_passwd', {})
1
Returns: | the user’s ID or False |
---|
>>> oerp.common.version()
{'protocol_version': 1, 'server_version': '6.1'}
Return information about the OpenERP Server.
>>> oerp.common.about()
'\n\nOpenERP is an ERP+CRM program for small and medium businesses.\n\nThe whole source code is distributed under the terms of the\nGNU Public Licence.\n\n(c) 2003-TODAY, Fabien Pinckaers - Tiny sprl'
>>> oerp.common.about(True)
['\n\nOpenERP is an ERP+CRM program for small and medium businesses.\n\nThe whole source code is distributed under the terms of the\nGNU Public Licence.\n\n(c) 2003-TODAY, Fabien Pinckaers - Tiny sprl', '5.0.16']
Param: | extended: if True then return version info |
---|---|
Returns: | string if extended is False else tuple |
>>> oerp.common.timezone_get('test_db', 'admin', 'admin_passwd')
'UTC'
>>> print(oerp.common.get_server_environment())
Environment Information :
System : Linux-2.6.32-5-686-i686-with-debian-6.0.4
OS Name : posix
Distributor ID: Debian
Description: Debian GNU/Linux 6.0.4 (squeeze)
Release: 6.0.4
Codename: squeeze
Operating System Release : 2.6.32-5-686
Operating System Version : #1 SMP Mon Mar 26 05:20:33 UTC 2012
Operating System Architecture : 32bit
Operating System Locale : fr_FR.UTF8
Python Version : 2.6.6
OpenERP-Server Version : 5.0.16
Last revision No. & ID :
>>> oerp.common.login_message()
'Welcome'
>>> oerp.common.set_loglevel('DEBUG')
>>> print(oerp.common.get_stats())
OpenERP server: 5 threads
Servers started
Net-RPC: running
>>> oerp.common.list_http_services()
[]
>>> oerp.common.check_connectivity()
True
>>> oerp.common.get_os_time()
(0.01, 0.0, 0.0, 0.0, 17873633.129999999)
>>> oerp.common.get_sqlcount()
>>> oerp.common.get_available_updates('super_admin_passwd', 'MY_CONTRACT_ID', 'MY_CONTRACT_PASSWORD')
>>> oerp.common.get_migration_scripts('super_admin_passwd', 'MY_CONTRACT_ID', 'MY_CONTRACT_PASSWORD')
New in version 0.4.
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 oerplib.OERP.db property.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost')
>>> oerp.db
<oerplib.service.db.DB object at 0xb75fb04c>
Warning
All methods documented below are not strictly implemented in OERPLib (except the create_and_wait method).
Method calls are purely dynamic, and the following documentation can be wrong if the API of OpenERP is changed between versions. Anyway, if you know the API used by the OpenERP server for the /db RPC service, it will work.
Return a list of the OpenERP databases:
>>> oerp.db.list()
['prod_db', 'test_db']
Returns: | a list of database names |
---|
Return a list of codes and names of language supported by OpenERP:
>>> oerp.db.list_lang()
[['sq_AL', 'Albanian / Shqipëri'], ['ar_AR', 'Arabic / الْعَرَبيّة'], ...]
Returns: | a list of pairs representing languages with their codes and names |
---|
Return the version of the OpenERP Server:
>>> oerp.db.server_version()
'6.1'
Returns: | the version of the OpenERP Server as string |
---|
Return a dump of database in base64:
>>> binary_data = oerp.db.dump('super_admin_passwd', 'prod_db')
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | the base64 string representation of the database |
---|
Restore in database a dump previously created with the dump method:
>>> oerp.db.restore('super_admin_passwd', 'test_db', binary_data)
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Drop the database from OpenERP:
>>> oerp.db.drop('super_admin_passwd', 'test_db')
True
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | True |
---|
Request the OpenERP server to create a new database named database which will have admin_passwd as administrator password and localized with the lang parameter. You have to set the flag demo_data to True in order to insert demonstration data.
As the creating process may take some time, you can execute the get_progress method with the database ID returned to know its current state.
>>> database_id = oerp.db.create('super_admin_passwd', 'test_db', False, 'fr_FR', 'my_admin_passwd')
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | the ID of the new database |
---|
Check the state of the creating process for the database identified by the database_id parameter.
>>> oerp.db.get_progress('super_admin_passwd', database_id) # Just after the call to the 'create' method
(0, [])
>>> oerp.db.get_progress('super_admin_passwd', database_id) # Once the database is fully created
(1.0, [{'login': 'admin', 'password': 'admin', 'name': 'Administrator'},
{'login': 'demo', 'password': 'demo', 'name': 'Demo User'}])
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | A tuple with the progressing state and a list of user accounts created (once the database is fully created). |
---|
Available since OpenERP 6.1
Similar to create but blocking.
>>> oerp.db.create_database('super_admin_passwd', 'test_db', False, 'fr_FR', 'my_admin_passwd')
True
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | True |
---|
Available since OpenERP 7.0
Duplicate original_database’ as `database.
>>> oerp.db.duplicate_database('super_admin_passwd', 'prod_db', 'test_db')
True
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | True |
---|
Rename the old_name database to new_name.
>>> oerp.db.rename('super_admin_passwd', 'test_db', 'test_db2')
True
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | True |
---|
Check if connection to database is possible.
>>> oerp.db.db_exist('prod_db')
True
Returns: | True or False |
---|
Change the administrator password by new_passwd.
>>> oerp.db.change_admin_password('super_admin_passwd', 'new_passwd')
True
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | True |
---|
Note
This method is not part of the official API of OpenERP. It’s just a wrapper around the create and get_progress methods. For OpenERP in version 6.1 or above, please prefer the use of the standard create_database method.
Like the create method, but waits the end of the creating process by executing the get_progress method regularly to check its state.
>>> oerp.db.create_and_wait('super_admin_passwd', 'test_db', False, 'fr_FR', 'my_admin_passwd')
[{'login': 'admin', 'password': 'my_admin_passwd', 'name': 'Administrateur'},
{'login': 'demo', 'password': 'demo', 'name': 'Demo User'}]
The super administrator password super_admin_passwd of OpenERP is required to perform this action.
Returns: | a list of user accounts created |
---|---|
Raise: | oerplib.error.RPCError |
New in version 0.6.
The Wizard class represents the /wizard RPC service which lets you access to the old-style wizards.
Note
This service have to be used through the oerplib.OERP.wizard property.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost')
>>> user = oerp.login('admin', 'passwd', 'database')
>>> oerp.wizard
<oerplib.service.wizard.Wizard object at 0xb76266ac>
Warning
All methods documented below are not strictly implemented in OERPLib
Method calls are purely dynamic, and the following documentation can be wrong if the API of OpenERP is changed between versions. Anyway, if you know the API used by the OpenERP server for the /wizard RPC service, it will work.
>>> oerp.wizard.create('wiz_name')
1
Returns: | the wizard’s instance ID |
---|
>>> oerp.wizard.execute(1, {'one_field': "Value"})
Provide the Inspect class which can output useful data from OpenERP.
New in version 0.8.
The Inspect class provides methods to output useful data from OpenERP.
Note
This service have to be used through the oerplib.OERP.inspect property.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost')
>>> user = oerp.login('admin', 'passwd', 'database')
>>> oerp.inspect
<oerplib.service.inspect.Inspect object at 0xb42fa84f>
Return a Relations object containing relations between data models, starting from models (depth = 0) and iterate recursively until reaching the maxdepth limit.
whitelist and blacklist of models can be defined with patterns (a joker * can be used to match several models like account*). The whitelist has a lower priority than the blacklist, and all models declared in models are automatically integrated to the whitelist.
In the same way, displaying attributes can be defined for each model with attrs_whitelist and attrs_blacklist. By default, model attributes are not displayed, unless the '*' pattern is supplied in attrs_whitelist, or if only the attrs_blacklist is defined.
>>> oerp.inspect.relations(
... ['res.users'],
... maxdepth=1,
... whitelist=['res*'],
... blacklist=['res.country*'],
... attrs_whitelist=['*'],
... attrs_blacklist=['res.partner', 'res.company'],
... ).write('res_users.png', format='png')
config is a dictionary of options to override some attributes of the graph. Here the list of options and their default values:
- relation_types: ['many2one', 'one2many', 'many2many'],
- show_many2many_table: False,
- color_many2one: #0E2548,
- color_one2many: #008200,
- color_many2many: #6E0004,
- model_root_bgcolor_title: #A50018,
- model_bgcolor_title: #64629C,
- model_color_title: white,
- model_color_subtitle': #3E3D60,
- model_bgcolor: white,
- color_normal: black,
- color_required: blue
- color_function: #D9602E
- space_between_models: 0.25,
>>> oerp.inspect.relations(
... ['res.users'],
... config={'relation_types': ['many2one']}, # Only show many2one relations
... ).write('res_users.png', format='png')
Note
With OpenERP < 6.1, many2one and one2many relationships can not be bound together. Hence, a one2many relationship based on a many2one will draw a separate arrow.
Return a Dependencies object describing dependencies between modules. The modules defines a list of root nodes to reach among all dependencies (modules not related to them are not displayed). The default behaviour is to compute all dependencies between installed modules. The models list can be used to display all matching models among computed dependencies.
models and models_blacklist parameters can be defined with patterns (a joker * can be used to match several models like account*). The whitelist (models) has a lower priority than the blacklist (models_blacklist):
>>> oerp.inspect.dependencies(
... models=['res.partner*'],
... models_blacklist=['res.partner.title', 'res.partner.bank'],
... ).write('dependencies_res_partner.png', format='png')
By default all installed modules are shown on the graph. To limit the result to modules related to the base one (its childs):
>>> oerp.inspect.dependencies(
... ['base'],
... ['res.partner*'],
... ['res.partner.title', 'res.partner.bank'],
... ).write('dependencies_res_partner_base.png', format='png')
All modules related to base are shown on the resulting graph, and matching models are highlighted among them, but some modules remain empty. To hide these “noisy” modules and restrict the resulting graph to data models that interest you, add the restrict=True parameter:
>>> oerp.inspect.dependencies(
... ['base'],
... ['res.partner*'],
... ['res.partner.title', 'res.partner.bank'],
... restrict=True,
... ).write('dependencies_res_partner_base_restricted.png', format='png')
In any case, root modules are always displayed on the graph in restricted mode (even if they have no matching model), and some unrelated modules may be added to satisfy dependencies.
config is a dictionary of options to override some attributes of the graph. Here the list of options and their default values:
- module_uninst_bgcolor_title: #DEDFDE,
- module_uninst_color_title: black,
- module_inst_bgcolor_title: #64629C,
- module_inst_color_title: white,
- module_root_bgcolor_title: #A50018,
- module_root_color_title: white,
- module_highlight_bgcolor_title: #1F931F,
- module_highlight_color_title: white,
- module_bgcolor: white,
- module_color_comment: grey,
- model_color_normal: black,
- model_color_transient: #7D7D7D,
- show_module_inst: True,
- show_module_uninst: False,
- show_model_normal: True,
- show_model_transient: False,
>>> oerp.inspect.dependencies(
... ['base'],
... ['res.partner*'],
... ['res.partner.title', 'res.partner.bank'],
... config={'show_model_transient': True}, # Show TransientModel/osv_memory models
... ).write('dependencies_res_partner_transient.png', format='png')
Note
With OpenERP 5.0, data models can not be bound to their related modules, and as such the models and models_blacklist parameters are ignored.
Scan all on_change methods detected among views of models, and returns a dictionary formatted as {model: {on_change: {view_id: field: [args]}}}
>>> oerp.inspect.scan_on_change(['sale.order'])
{'sale.order': {
'onchange_partner_id': {
'sale.view_order_form': {
'partner_id': ['partner_id']}},
'onchange_partner_order_id': {
'sale.view_order_form': {
'partner_order_id': ['partner_order_id', 'partner_invoice_id', 'partner_shipping_id']}},
'onchange_pricelist_id': {
'sale.view_order_form': {
'pricelist_id': ['pricelist_id', 'order_line']}},
'onchange_shop_id': {
'sale.view_order_form': {
'shop_id': ['shop_id']}},
'shipping_policy_change': {
'sale.view_order_form': {
'order_policy': ['order_policy']}}},
'sale.order.line': {
'product_id_change': {
'sale.view_order_form': {
'product_id': [
'parent.pricelist_id', 'product_id', 'product_uom_qty', 'product_uom',
'product_uos_qty', 'product_uos', 'name', 'parent.partner_id', False, True,
'parent.date_order', 'product_packaging', 'parent.fiscal_position', False, 'context'],
'product_uom_qty': [
'parent.pricelist_id', 'product_id', 'product_uom_qty', 'product_uom',
'product_uos_qty', 'product_uos', 'name', 'parent.partner_id', False, False,
'parent.date_order', 'product_packaging', 'parent.fiscal_position', True, 'context']}},
...
}}
Draw relations between models with Graphviz.
Returns a pydot.Dot object representing relations between models.
>>> graph = oerp.inspect.relations(['res.partner'])
>>> graph.make_dot()
<pydot.Dot object at 0x2bb0650>
See the pydot documentation for details.
Write the resulting graph in a file. It is just a wrapper around the pydot.Dot.write() method (see the pydot documentation for details). Below a common way to use it:
>>> graph = oerp.inspect.relations(['res.partner'])
>>> graph.write('relations_res_partner.png', format='png')
About supported formats, consult the Graphviz documentation.
Draw dependencies between modules. Models can be displayed in their respecting modules as well.
Returns a pydot.Dot object representing dependencies between modules.
>>> graph = oerp.inspect.dependencies(['base'], ['res.partner'])
>>> graph.make_dot()
<pydot.Dot object at 0x2f01990>
See the pydot documentation for details.
Write the resulting graph in a file. It is just a wrapper around the pydot.Dot.write() method (see the pydot documentation for details). Below a common way to use it:
>>> graph = oerp.inspect.dependencies(['base'], ['res.partner'])
>>> graph.write('dependencies_res_partner.png', format='png')
About supported formats, consult the Graphviz documentation.
This module provides RPC connectors which use the XML-RPC, Net-RPC or JSON-RPC protocol to communicate with an OpenERP server.
Afterwards, RPC services and their associated methods can be accessed dynamically from the connector returned.
XML-RPC and Net-RPC provide the same interface, such as services like db, common or object. On the other hand, JSON-RPC provides a completely different interface, with services provided by Web modules of OpenERP like web/session, web/dataset and so on.
Connector base class defining the interface used to interact with an OpenERP server.
Connector class using the XML-RPC protocol.
>>> from oerplib import rpc
>>> cnt = rpc.ConnectorXMLRPC('localhost', port=8069)
Login and retrieve ID of the user connected:
>>> uid = cnt.common.login('database', 'user', 'passwd')
Execute a query:
>>> res = cnt.object.execute('database', uid, 'passwd', 'res.partner', 'read', [1])
Execute a workflow query:
>>> res = cnt.object.exec_workflow('database', uid, 'passwd', 'sale.order', 'order_confirm', 4)
Connector class using the XML-RPC protocol over SSL.
Note
No longer available since OpenERP 7.0.
Connector class using the Net-RPC protocol.
Deprecated since version 0.8.
Return a RPC connector to interact with an OpenERP server. Supported protocols are:
- xmlrpc: Standard XML-RPC protocol (default),
- xmlrpc+ssl: XML-RPC protocol over SSL,
- netrpc: Net-RPC protocol made by OpenERP (no longer available since OpenERP v7.0).
If the version parameter is set to None, the last API supported will be used to send requests to OpenERP. Otherwise, you can force the API to use with the corresponding string version (e.g.: '6.0', '6.1', '7.0', ...):
>>> from oerplib import rpc
>>> cnt = rpc.get_connector('localhost', 8069, 'xmlrpc', version='7.0')
Warning
The support of JSON-RPC is still in the experimental stage.
Connector class using the JSON-RPC protocol.
>>> from oerplib import rpc
>>> cnt = rpc.ConnectorJSONRPC('localhost', port=8069)
Open a user session:
>>> cnt.proxy.web.session.authenticate(db='database', login='admin', password='admin')
{u'jsonrpc': u'2.0', u'id': 202516757,
u'result': {u'username': u'admin', u'user_context': {u'lang': u'fr_FR', u'tz': u'Europe/Brussels', u'uid': 1},
u'db': u'test70', u'uid': 1, u'session_id': u'308816f081394a9c803613895b988540'}}
Read data of a partner:
>>> cnt.proxy.web.dataset.call(model='res.partner', method='read', args=[[1]])
{u'jsonrpc': u'2.0', u'id': 454236230,
u'result': [{u'id': 1, u'comment': False, u'ean13': False, u'property_account_position': False, ...}]}
You can send requests this way too:
>>> cnt.proxy['/web/dataset'].call(model='res.partner', method='read', args=[[1]])
{u'jsonrpc': u'2.0', u'id': 328686288,
u'result': [{u'id': 1, u'comment': False, u'ean13': False, u'property_account_position': False, ...}]}
Or like this:
>>> cnt.proxy['web']['dataset'].call(model='res.partner', method='read', args=[[1]])
{u'jsonrpc': u'2.0', u'id': 102320639,
u'result': [{u'id': 1, u'comment': False, u'ean13': False, u'property_account_position': False, ...}]}
Connector class using the JSON-RPC protocol over SSL.
>>> from oerplib import rpc
>>> cnt = rpc.ConnectorJSONRPCSSL('localhost', port=8069)
This module contains the Config class which manage the configuration related to an instance of OERP, and some useful helper functions used internally in OERPLib.
Class which manage the configuration of an OERP instance.
Note
This class have to be used through the oerplib.OERP.config property.
>>> import oerplib
>>> oerp = oerplib.OERP('localhost')
>>> type(oerp.config)
<class 'oerplib.tools.Config'>
Clean a version string.
>>> from oerplib.tools import clean_version
>>> clean_version('7.0alpha-20121206-000102')
'7.0'
Returns: | a cleaner version string |
---|
Deprecated since version 0.8.
Try to detect the OpenERP server version.
>>> from oerplib.tools import detect_version
>>> detect_version('localhost', 'xmlrpc', 8069)
'7.0'
Returns: | the version as string |
---|
Convert a version string to a tuple. The tuple can be use to compare versions between them.
>>> from oerplib.tools import v
>>> v('7.0')
[7, 0]
>>> v('6.1')
[6, 1]
>>> v('7.0') < v('6.1')
False
Returns: | the version as tuple |
---|
This module contains some helper functions used to save and load sessions in OERPLib.
Return the session configuration identified by name from the rc_file file.
>>> import oerplib
>>> oerplib.tools.session.get('foo')
{'protocol': 'xmlrpc', 'user': 'admin', 'timeout': 120, 'database': 'db_name', 'passwd': 'admin', 'type': 'OERP', 'port': 8069, 'server': 'localhost'}
Raise: | oerplib.error.Error |
---|
Return all session configurations from the rc_file file.
>>> import oerplib
>>> oerplib.tools.session.get_all()
{'foo': {'protocol': 'xmlrpc', 'user': 'admin', 'timeout': 120, 'database': 'db_name', 'passwd': 'admin', 'type': 'OERP', 'port': 8069, 'server': 'localhost'}}
Remove the session configuration identified by name from the rc_file file.
>>> import oerplib
>>> oerplib.tools.session.remove('foo')
Raise: | oerplib.error.Error |
---|
Save the data session configuration under the name name in the rc_file file.
>>> import oerplib
>>> oerplib.tools.session.save('foo', {'type': 'OERP', 'server': 'localhost', 'protocol': 'xmlrpc', 'port': 8069, 'timeout': 120, 'user': 'admin', 'passwd': 'admin', 'database': 'db_name'})
This module contains all exceptions raised by OERPLib when an error occurred.
Exception raised when an error occurred during an internal operation.
Exception raised when an error related to a RPC query occurred.
OERPLib has been tested on OpenERP server v5.0, v6.0, v6.1, v7.0 and v8.0. It should work on next versions if OpenERP keeps a stable API.
OERPLib support Python versions 2.6, 2.7.
This software is made available under the LGPL v3 license.
Please, feel free to report bugs or suggestions in the Bug Tracker!
OERPLib is mainly developed on free time. To show your appreciation and support this project, it is possible to make a donation through PayPal: