1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
|
.. _tutorials:
Tutorials
=========
First step: prepare the connection and login
--------------------------------------------
You need an instance of the :class:`OERP <oerplib.OERP>` class to dialog with an
`OpenERP/Odoo` server. Let's pretend that you want to connect as `admin` on
the `db_name` database of your local 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 :attr:`oerp.db <oerplib.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 :ref:`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 your
server (execute model methods, trigger workflow, download reports,
and handle wizards).
.. _tutorials-execute-queries:
Execute queries
---------------
The basic method to execute queries (related to the ``/object`` `RPC` service)
is :func:`execute <oerplib.OERP.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
:class:`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
:func:`get <oerplib.OERP.get>` method, which provides an API
almost syntactically identical to the `OpenERP/Odoo` server side API
(see :class:`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 a server in version `6.1` or above, the user context is
automatically sent.
You can disable this behaviour with the :attr:`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 the `6.1` server version::
>>> module_obj = oerp.get('ir.module.module')
>>> module_id = module_obj.search([('name', '=', 'purchase')])
>>> module_obj.button_immediate_install(module_id)
.. _browse-records:
Browse records
--------------
A great functionality of `OERPLib` is its ability to generate objects that are
similar to browsable records used on the server side. All of this
is possible using the :func:`browse <oerplib.OERP.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 :class:`model <oerplib.service.osv.Model>`
too. In fact, both methods are strictly identical,
:func:`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 :ref:`here <fields>`.
Update data through browsable records
-------------------------------------
Update data of a browsable record is workable with the
:func:`write_record <oerplib.OERP.write_record>` method of an
:class:`OERP <oerplib.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"})
Char, Float, Integer, Boolean, Text and Binary
''''''''''''''''''''''''''''''''''''''''''''''
As see above, it's as simple as that::
>>> partner.name = "New Name"
>>> oerp.write_record(partner)
Selection
'''''''''
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
Many2One
''''''''
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
''''''''''''''''''''''
``one2many`` and ``many2many`` fields can be updated by providing
a list of tuple as specified in the `OpenERP/Odoo` documentation, a list of
records, a list of record IDs or an empty list or ``False``:
With a tuple (as documented), 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]
Reference
'''''''''
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
'''''''''''''''''
``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
Generate reports
----------------
Another nice functionnality is the reports generation (related to the
``/report`` `RPC` service) with the :func:`report <oerplib.OERP.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.
Manage databases
----------------
You can manage server databases with the :attr:`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 server, and you have
to wait before using the new database. The state of the creation process is
returned by the
:func:`get_progress <oerplib.service.db.DB.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
:func:`create_and_wait <oerplib.service.db.DB.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 ``/db`` RPC service
is available :class:`here <oerplib.service.db.DB>`.
Inspect the metadata of your server **(New in version 0.8)**
------------------------------------------------------------
Draw a graph of relationships between models
''''''''''''''''''''''''''''''''''''''''''''
.. note::
This functionality requires the installation of `pydot <http://code.google.com/p/pydot/>`_.
The :func:`relations <oerplib.service.inspect.Inspect.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')
.. figure:: _static/rel_res_partner_v1.png
:width: 100%
Legend:
+--------------------------------------------+--------------------------------------------+
| Element | Meaning |
+============================================+============================================+
| .. raw:: html | many2one |
| | |
| <font color="#0E2548">partner_id</font> | |
+--------------------------------------------+--------------------------------------------+
| .. raw:: html | one2many |
| | |
| <font color="#008200">bank_ids</font> | |
+--------------------------------------------+--------------------------------------------+
| .. raw:: html | many2many |
| | |
| <font color="#6E0004">company_ids</font>| |
+--------------------------------------------+--------------------------------------------+
| .. raw:: html | Field required |
| | |
| [<font color="blue">R</font>] | |
+--------------------------------------------+--------------------------------------------+
| .. raw:: html | Field function (readonly) |
| | |
| [<font color="#7D7D7D">F</font>] | |
+--------------------------------------------+--------------------------------------------+
| .. raw:: html | Field function (writable) |
| | |
| [<font color="#7D7D7D">Fw</font>] | |
+--------------------------------------------+--------------------------------------------+
| .. raw:: html | Field function (searchable) |
| | |
| [<font color="#7D7D7D">Fs</font>] | |
+--------------------------------------------+--------------------------------------------+
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
.. image:: _static/rel_res_partner_v2.png
:width: 350px
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')
.. image:: _static/rel_res_partner_v3.png
:width: 350px
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')
.. image:: _static/rel_res_partner_v4.png
:width: 350px
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')
.. image:: _static/rel_res_partner_v5.png
:height: 350px
For more details, take a look at the
:func:`relations <oerplib.service.inspect.Inspect.relations>` method
documentation.
Draw a graph of module dependencies
'''''''''''''''''''''''''''''''''''
.. note::
This functionality requires the installation of `pydot <http://code.google.com/p/pydot/>`_.
You will be able to generate a graphic representing dependencies between all
modules with the
:func:`dependencies <oerplib.service.inspect.Inspect.dependencies>` method::
>>> graph = oerp.inspect.dependencies()
>>> graph.write('dependencies_v1.png', format='png')
.. figure:: _static/dependencies_v1.png
:width: 900px
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')
.. figure:: _static/dependencies_v2.png
:height: 250px
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')
.. figure:: _static/dependencies_v3.png
:height: 250px
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')
.. figure:: _static/dependencies_v4.png
:height: 250px
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')
.. image:: _static/dependencies_v5.png
:height: 190px
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')
.. image:: _static/dependencies_v6.png
:height: 250px
For more details, take a look at the
:func:`dependencies <oerplib.service.inspect.Inspect.dependencies>` method
documentation.
Scan the views of data models to list `on_change` methods
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
`on_change` functions of a model can be listed with the
:func:`scan_on_change <oerplib.service.inspect.Inspect.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.
Save the session to open it quickly later **(New in version 0.8)**
------------------------------------------------------------------
Once you are authenticated with your :class:`OERP <oerplib.OERP>` instance, you
can :func:`save <oerplib.OERP.save>` these connection information under a code
name and use this one to quickly instanciate a new :class:`OERP <oerplib.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 :func:`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 :func:`oerplib.OERP.list`, and remove
them with :func:`oerplib.OERP.remove`::
>>> oerplib.OERP.list()
['foo']
>>> oerplib.OERP.remove('foo')
>>> 'foo' not in oerplib.OERP.list()
True
Change the timeout
------------------
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
:attr:`oerplib.OERP.config` property::
>>> oerp.config['timeout']
120
>>> oerp.config['timeout'] = 300 # Set the timeout to 300 seconds
|