Package: openerp_proxy
ContentsOverviewFeaturesQuick exampleSupported Odoo server versionsExamplesInstallUsageUse as shellUse as libraryUse in Jupyter notebookGeneral usageAdditional featuresSession: db aliasesSugar extensionSession: Start-up importsPluginsOverviewThis project is justRPC clientfor Odoo.
It aims to ease access to openerp data via shell and used
mostly for data debuging purposes. This project provides interface similar to
Odoo internal code to perform operations onOpenERP/Odooobjects hidingXML-RPCorJSON-RPCbehind.Are You still using pgAdmin for quering Odoo database?Try this package (especialy with IPython Notebook), and You will forget about pgAdmin!FeaturesUseodoo-rpc-clientunder that hood, to get all its powerPython 3.3+supportYou can call any public method on any OpenERP / Odoo object including:read,search,write,unlinkand othersHavea lot of speed optimizations(caching, read only requested fields,
read data for all records in current set (cache), by one RPC call, etc)Desinged to take as more benefits ofIPython autocompleteas posibleWorks nice inJupyter NotebookprovidingHTML
representationfor a most of objects.Ability to export HTML table recordlist representation toCSV fileAbility to save connections to different databases in session.
(By default password is not saved, and will be asked, but if You need to save it, just do this:session.option('store_passwords',True); session.save())Providesbrowse_recordlike interface, allowing to browse related
models too. Supportsbrowsemethod.
Also adds methodsearch_recordsto simplify
search-and-read operations.Extension support. You can easily modify most of components of this app/lib
creating Your own extensions and plugins. It is realy simple. See for examples inopenerp_proxy/ext/directory.Plugin Support. Plugins are same as extensions, but aimed to implement additional logic.
For example look atopenerp_proxy/pluginsandopenerp_proxy/plugin.pySupport ofJSON-RPCforversion 8+of OdooSupport of usingnamed parametrsin RPC method calls (server version 6.1 and higher).Sugar extensionwhich simplifys code a lot.Experimentalintegration withAnyFieldMissed feature? ask inProject IssuesQuick examplefromopenerp_proxyimportClientclient=Client('localhost','my_db','user','password')# get current userclient.userprint(user.name)# simple rpc callsclient.execute('res.partner','read',[user.partner_id.id])# Model browsingSaleOrder=client['sale.order']s_orders=SaleOrder.search_records([])fororderins_orders:print(order.name)forlineinorder.order_line:print("\t%s"%line.name)print("-"*5)print()Supported Odoo server versionsTested with Odoo10.0,11.0But should support all odoo versions thatodoo_rpc_clientsupportsExamplesBasicsExamples & HTML testsRecordList RepresentationInstallThis project is present onPyPIso it could be installed via PIP:pip install openerp_proxythis will make available python packageopenerp_proxyand shell commandopenerp_proxySeeUsagefor more detailsIf You want to install development version ofOpenERP Proxyyou can do it via:pip install -e git+https://github.com/katyukha/openerp-proxy.git@dev#egg=openerp_proxyor (faster way):pip install https://github.com/katyukha/openerp-proxy/archive/dev.zipAlso it is recommened to install atJupyter(formelyIPythonnotebook)
to get all benefits ofJupyterintegration, provided by this project.
To install it just type:pip install jupyterUsageUse as shellAfter instalation run in shell:openerp_proxyAnd You will get the openerp_proxy shell. IfIPythonis installed then IPython shell
will be used, else usual python shell will be used. There issessionvariable present in locals. It is instance ofSessionclass and
represents current session and usualy is starting point of any shell work.
Seedocumentationfor more detailsNext You have to get connection to some Odoo database.
It is realy easy, just useconnectmethod of session>>>db=session.connect()This will ask You for host, port, database, etc to connect to
and returnClientinstance
which represents database connection.Use as libraryThe one diference betwen using as lib and using as shell is the way
connection to database is created. When using as shell the primary object
is session, which provides some interactivity. But when using as library
in most cases there are no need for that interactivity, so connection
should be created manualy, providing connection data from some other sources
like config file or something else.So here is a way to create connectionfromopenerp_proxy.coreimportClientdb=Client(host='my_host.int',dbname='my_db',user='my_db_user',pwd='my_password here')And next all there same, no more differences betwen shell and lib usage.Use in Jupyter notebookJupyterintegration is implemented as extensionopenerp_proxy.ext.repr,
so to use it, first, this extension should be enabled (just by importing extension).
As a shortcut, there isopenerp_proxy.ext.allmodule,
which imports default set of extensions, includingopenerp_proxy.ext.reprextension.
To better suit for HTML capable notebook You would like to use IPython’s version ofsessionobject andopenerp_proxy.ext.reprextension.
So in first cell of notebook import session and extensions/plugins You want:# also You may import all standard extensions in one line:fromopenerp_proxy.ext.allimport*# note that extensions were imported before session,# because some of them modify Session classfromopenerp_proxy.sessionimportSessionfromopenerp_proxy.coreimportClientsession=Session()Now most things same as for shell usage, but…
In some old versions of IPython’s notebook heve no patched version ofgetpassfunc/module,
so if You not provide password when getting database (connect,get_dbmethods, You would be asked
for it, but this prompt will be displayed in shell where notebook server is running, not on webpage.
To solve this, it is recommended to usesstore_passwordsoptionsession.option('store_passwords',True)session.save()Next use it like shell, butdo not forget to save session, after new connectiondb=session.connect()session.save()or like libdb=Client(host='my_host.int',dbname='my_db',user='my_db_user',pwd='my_password here')Note: in old version of IPython getpass was not work correctly,
so maybe You will need to pass password directly tosession.connectmethod.General usageFor example lets try to find how many sale orders in ‘done’ state we have in
our database. (Look above sections to get help on how to connect to Odoo database)>>>sale_order_obj=db['sale.order']# or You may use 'db.get_obj('sale.order')' if You like>>>>>># Now lets search for sale orders:>>>sale_order_obj.search([('state','=','done')],count=True)5So we have 5 orders in done state. So let’s read them.Default way to read data from Odoo is to search for required records
withsearchmethod which return’s list of IDs of records, then read
data usingreadmethod. Both methods mostly same as Odoo internal
ones:>>>sale_order_ids=sale_order_obj.search([('state','=','done')])>>>sale_order_datas=sale_order_obj.read(sale_order_ids,['name'])# Last argument is optional.# it describes list of fields to read# if it is not provided then all fields# will be read>>>sale_order_datas[0]{'id':3,'name':'SO0004'}As we see reading data in such way allows us to get list of dictionaries
where each contain fields have been readAnother way to read data is to usesearch_recordsorread_recordsmethod. Each of these methods receives same aguments assearchorreadmethod respectively. But passingcountargument forsearch\_recordswill cause error. Main difference betwen these methods
in usingRecordclass
instead ofdictfor each record had been read. Record class provides some orm-like abilities for records,
allowing for example access fields as attributes and provide mechanisms
to lazily fetch related fields.>>>sale_orders=sale_order_obj.search_records([('state','=','done')])>>>sale_orders[0]R(sale.order,9)[SO0011]>>>>>># So we have list of Record objects. Let's check what they are>>>so=sale_orders[0]>>>so.id9>>>so.nameSO0011>>>so.partner_idR(res.partner,9)[BetterCorp]>>>>>>so.partner_id.nameBetterCorp>>>so.partner_id.activeTrueAdditional featuresSession: db aliasesSession provides ability to add aliases to databases, which will simplify access to them.
For this featureSessionclass
provides methodaliaseand
propertyaliaseswhich allows to get all registered aliases in session.
To add aliase to our db do the folowing:>>>session.aliase('my_db',db)And now to access this database in future (even after restart)
You can use next code>>>db=session.my_dbthis allows to faster get connection to database Your with which You are working very oftenSugar extensionThis extension provides some syntax sugar to ease access to objects
To enable it, just importopenerp_proxy.ext.sugarmodule.
By default this extension will also be enabled on import ofopenerp_proxy.ext.allSo to start use it just import this extensionjust after startimportopenerp_proxy.ext.sugarAnd after that You will have folowing features workingdb['sale.order'][5]# fetches sale order with ID=5db['sale_order']('0050')# result in name_search for '0050' on sale order# result may be Record if one record found# or RecordList if there some set of records founddb['sale.order']([('state','=','done')])# Same as 'search_records' methoddb['sale.order'](state='done')# simplified search# Automatic object aliaces. Also supports autocompletition# via implementation of __dir__ methoddb._sale_order==db['sale.order']==db['sale_order']# => TrueFor other extensions look atopenerp_proxy/ext codeordocumentationSession: Start-up importsIf You want some modules (extensions/plugins) to be automatiacly loaded/imported
at start-up, there aresession.start_up_importsproperty, that points to list that holds names of modules to be imported at session creation time.For example, if You wantSugar extensionto be automaticaly imported, just
add it tosession.start_up_importslistsession.start_up_imports.append('openerp_proxy.ext.sugar')After this, when You will start new openerp_proxy shell,sugar extensionwill be automaticaly enable.PluginsIn version 0.4 plugin system was completly refactored. At this version
we start usingextend_melibrary to build extensions and plugins easily.Plugins are usual classes that provides functionality that should be available
atdb.plugins.*point, implementing logic not related to core system.To ilustrate what is plugins and what they can do we will create a simplest one.
So let’s startcreate some directory to place plugins in:mkdir ~/oerp_proxy_plugins/cd ~/oerp_proxy_plugins/next create simple file calledattendance.pyand edit itvim attendance.pywrite folowing code there (note that this example works and tested for Odoo version 6.0 only)from openerp_proxy.plugin import Plugin

class AttandanceUtils(Plugin):

    # This is required to register Your plugin
    # *name* - is for db.plugins.<name>
    class Meta:
        name = "attendance"

    def get_sign_state(self):
        # Note: folowing code works on version 6 of Openerp/Odoo
        emp_obj = self.client['hr.employee']
        emp_id = emp_obj.search([('user_id', '=', self.client.uid)])
        emp = emp_obj.read(emp_id, ['state'])
        return emp[0]['state']Now your plugin is completed, but it is not on python path.
There is ability to add additional paths to session, so
when session starts,sys.pathwill be patched with that paths.
To add your extra path to session You need do folowing:>>> session.add_path('~/oerp_proxy_plugins/')
>>> session.save()Now, each time session created, this path will be added to python pathNow we cat test our plugin.
Runopenerp_proxyand try to import it:>>> #import our plugin
>>> import attendance

>>> # and use it
>>> db = session.connect()
>>> db.plugin.attendance.get_sign_state()
'present'

>>> # If You want some plugins or extensions or other
>>> # modules imported at start-up of session, do this
>>> session.start_up_imports.add('attendance')As You see above, to use plugin (or extension), just import it’s module (better at startu-up)For more information seesource
codeordocumentation.