Run An Odoo REPL / IPython Prompt

$ ./odoo-bin shell \
-c /etc/odoo.conf \
--xmlrpc-port=8888 \
--longpolling-port=8899 \
-d odoo
Starting up the REPL prompt.

Update — Mar 1st, 2021

Hello! If you’ve seen my articles pop up in your searches before, I really appreciate the time people have taken to read my articles. At this point, there’s been over 75k views across the 25 or so articles I’ve written here on Medium. That’s amazing to me since writing is a hobby I started doing just to try to get a bit better at writing and communicating.

I wanted to let everyone who lands on these articles that I have migrated everything over to a self hosted blog (for a bunch of reasons that I won’t get into here). So please take a look at for all of the articles or to specifically see this article.

Thanks again! — Holden

In Odoo, you have the ability to run Odoo as a web server and access it via a GUI, but you can also run a python REPL with all of the Odoo modules loaded in as globals. This is extremely helpful for debugging and for learning.

For example, you could start up the shell, query for information via env/search/browse commands, run individual functions, access variables and properties associated with core classes, load in new functions if needed for testing, etc.

How to run an Odoo shell

Let’s break down the command:

$ ./odoo-bin shell \
-c /etc/odoo.conf \
--xmlrpc-port=8888 \
--longpolling-port=8899 \
-d odoo

./odoo-bin shell

odoo-bin is the executable in the root directory of the core Odoo project. This is how you run an Odoo instance.

If you run odoo-bin help you will see that we have a few different commands that we can run. One of those commands is shell which will start up our REPL.

-c /etc/odoo.conf

Reference to your configuration files, if relevant. If you do not need all of your configurations and addons referenced then you can leave this off.

--xmlrpc-port=8888 --longpolling-port=8899

More optional flags. I use these because then I can run a standard Odoo instance on 8069/8072, but run a shell prompt at the same time on separate non-conflicting ports. You can use any open ports that you would like.

-d odoo

The database that you want to connect to. All Odoo shell prompts are connected to a single database at a time.

What do you have reference to?

Once you got a shell prompt up and running, then check out what you actually have reference to. You can see this by runnng globals():

Here are some of the globals that I end up using the most often:


In [7]: self
Out[7]: res.users(1,)

self is a reference to the currently logged in user. By default, this is going to be id=1 (the admin user.)


A global reference to the Environment similar to if you would access it via self.env .

This is where we can start querying/accessing different data in the system:

In [8]: attachments = env['ir.attachment'].search([])In [9]: attachments
Out[9]: ir.attachment(356, 355, 354, 353, 352)

odoo / openerp

The global reference to the odoo core. Anything that you would typically import in modules is accessible. So if you need to access odoo.models , , odoo.exceptions , etc. you can import or reference those in the shell prompt.

In [11]: f = odoo.fields.Many2oneIn [12]: dir(f)
... ]

Some Tricks

Here are just a couple of quick tricks that I use pretty often within the odoo shell.

General Imports

Just like any ipython prompt, you can import any accessible library. This is extremely helpful as you start debugging. Bring different libraries into the prompt.

In [14]: import math, string, io

Viewing Properties and Functions

At the beginning of this article, I said that the shell is great for both debugging and learning. Seeing the properties and functions available helped me initially learn how Odoo worked internally.

You can go through everything available to you via the global odoo or env module.

Let’s take the search method for example. This is something that many odoo developers use via commands like env['my.model'].search . But we can see a quick description of this directly in the prompt by using ?? :

Above, we are assuming that we already know that the search method exists. If we actually need to find methods then we can hit tab at the end of a variable to see all available properties and methods:

Committing Data

Be careful with this since it actually writes to your database.

If you need to update some record via the odoo shell, you have to run the update method like you would in a standard custom module, but then you have to manually commit them to the database via

In [23]: users = env['res.users'].search([])In [24]: for user in users:
...: user.update({'create_uid': 1, })
In [25]:

Thanks For Reading

Go try it out and let me know how Odoo shell works for you or your team.

Follow me on Twitter for random thoughts and articles about Odoo. Or follow me directly here at Medium to stay up to date on my dev articles.





🧑‍💻 Software Freelancer and Consultant | Works mostly with #odoo and #python web apps | Writes at

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

CS373 Fall 2021: Raphael Samuel: Final Entry

From Paperclip to Active Storage

(Re)Introducing Relic Scout

A Brand New Faraday Is Up And Running!


Artificial Intelligence application with Android using Microsoft cognitive services.

Serverless simply works?

Developer Advocate Journal #2

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Holden Rehg

Holden Rehg

🧑‍💻 Software Freelancer and Consultant | Works mostly with #odoo and #python web apps | Writes at

More from Medium

webKnossos Python library

The “Business card raytracer” in python, part 2

Deleting a file or folder in Python

Python GUI frameworks