Odoo CLI commands

Odoo has this somewhat arcane feature of CLI commands which allow you to add custom CLI commands that can be called from a shell by calling the Odoo executable.

The neat things about these commands are:

  1. You can define new CLI commands in your Odoo addons.
  2. These commands are loaded regardless of the module's installation status, so they can be executed even if the module is not installed (you don't even need to update the module list). Of course, the addon with the commands must be inside one of Odoo's addons paths.
  3. The module can even be disabled ('installable': False in the module's manifest) and the commands will still be available.

A few ideas on where they can be used come to mind:

  1. Long running scripts where you need to import odoo directly - think data import scripts - especially helpful if Odoo directory is not in your $PYTHON_PATH.
  2. Devops tasks where there is something that you need to do quite often inside the database, eg. disable incoming/outgoing email servers and Cron jobs, etc.

Custom Odoo CLI commands can be invoked like this:

odoo-bin --addons-path=<addons_path> <command_name> <extra_arguments>

where <addons_path> is a comma-separated list of all your Odoo addons paths, <command_name> is the name of the command and <extra_arguments> is an optional list of extra arguments you might want to pass to your command.

The equality sign (=) after the --addons-path is important (required), otherwise the CLI commands are not loaded.

We can also use the help command to list all currently available commands:

odoo-bin --addons-path=<addons_path> help

Odoo comes with these commands out of the box:

  • deploy - allows to bundle up a module (.xml files and static assests) in a ZIP file and deploy it to an Odoo instance. For it to work, the base_import_module addon must be installed on the Odoo instance.
  • scaffold - generates an Odoo module skeleton (useful when developing a new addon or theme).
  • server - starts Odoo - this is the default command.
  • shell - starts Odoo in an interactive Python interpreter - useful for quick scripts and testing out ideas.
  • start - quick starts Odoo for your project by creating an empty database (the name of the new database is based on you current working directory by default). Does not sound very useful.

I have found just two cases of these CLI commands on the Odoo App Store, the main one is the shell command backport by OCA, the other one is some fixdb command in ADHOC Modules.

Creating a custom command

The following example is made using Odoo 10.0.

Let's write a custom command which will allow us update the module list from the command line without installing/updating other modules - this is useful when updating a module which has a new (previously not installed) dependency. The steps are:

  • Create an Odoo addon with a minimal working manifest.
  • Create a cli directory in the addon's root directory.
  • Define commands which inherit from odoo.cli.command.Command.
  • Implement the command:

    import argparse
    
    from odoo import SUPERUSER_ID, api, cli, registry
    
    
    class Update_Module_List(cli.Command):
        '''Update module list in a given database.'''
    
        def run(self, cmd_args):
            # Define and parse our own custom command line parameters.
            parser = argparse.ArgumentParser()
            parser.add_argument('database')
            args = parser.parse_args(args=cmd_args)
    
            # Setup Odoo registry, get a database cursor.
            with api.Environment.manage():
                with registry(args.database).cursor() as cr:
                    # Create on ORM environment.
                    env = api.Environment(cr, SUPERUSER_ID, {})
                    # Update the module list.
                    env['ir.module.module'].update_list()
    

The command name is built by lowercasing the command's class name, so in our case the command can be invoked like this:

odoo-bin --addons-path=<addons_path> update_module_list <database_name>

The full source code of this command is available here.