Scripts

Write reusable Python scripts and run them against your Odoo services from the dashboard.

Scripts let you write small Python snippets once and run them on demand against any compatible Odoo service. They execute through click-odoo inside the service's container, so you have direct access to the standard Odoo shell globals (env, self) — exactly like an interactive odoo shell session.

Typical use cases:

  • One-off data fixes ("update all draft invoices created before X")
  • Bulk setting changes across several customer instances
  • Recurring maintenance tasks you don't want to re-type each time
  • Triggering recomputations or running custom code that needs the Odoo ORM

#Where to find scripts

Scripts live under the Developer → Scripts navigation entry. From there you can list, create, edit, and run them.

You can also run a script directly from a service:

  • Open a service and click Run script in the header — pick from the scripts compatible with that Odoo version.
  • Select multiple services in the services table and use the bulk Run script action — only scripts compatible with every selected service's version are offered.

#Creating a script

  1. Open Developer → Scripts and click New Script.
  2. Fill in the Details:
    • Name — shown in the script list and the run modal.
    • Compatible Odoo versions — pick every version this script is safe to run on. Services on other versions will not be selectable as targets.
    • Description — optional context, e.g. what the script does and any prerequisites.
  3. Optionally define Parameters (see below).
  4. Write the Python code in the Script editor and save.

The script body runs through click-odoo, so an open transaction is committed automatically when the script finishes successfully. If anything raises an exception, the transaction is rolled back.

#A minimal example

# Disable mail sending on a copied database
env['ir.mail_server'].search([]).write({'active': False})
print('Disabled', env['ir.mail_server'].search_count([('active', '=', False)]), 'mail servers.')

When this script runs against a service, the output is captured on that service's Actions tab.

#Parameters

Parameters are optional inputs prompted for at run time. Each parameter is exposed as a regular Python variable at the top of your script, so you can use it directly without any boilerplate.

For each parameter you define:

Field Description
Variable name A valid Python identifier — letters, digits, and underscores; must not start with a digit.
Label Human-friendly label shown in the run modal. Defaults to the variable name.
Type One of string, integer, float, boolean. Determines how the value is rendered in Python.
Default Pre-filled value in the run modal. Optional.
Required If on, the script will refuse to run when the value is empty.

The platform renders the chosen value as a native Python literal before your code runs, so you can use it directly:

# Parameters: partner_id (integer, required), only_unpaid (boolean, default true)
domain = [('partner_id', '=', partner_id)]
if only_unpaid:
    domain.append(('payment_state', '!=', 'paid'))

invoices = env['account.move'].search(domain)
print('Found', len(invoices), 'invoices.')

Parameter values are rendered as Python literals — strings are properly quoted, booleans become True/False, numbers stay numeric. You don't need to parse or cast them yourself.

#Running a script

Click Run on a script (from the Scripts list, the edit page, or a service action) to open the run modal:

  1. Target services — pick one or more services. Only services running an Odoo version listed under Compatible Odoo versions are available.
  2. Parameters — fill in any inputs the script declared.
  3. Click Run.

The script is queued as one action per selected service. The notification confirms how many services it was queued on.

Each run is a separate action. Output, exit status, and timing are recorded on the Actions tab of the corresponding service — exactly like backups, restarts, or deployments.

#How scripts execute

When a run is dispatched the platform:

  1. Renders any parameter values as Python literals and prepends them to your script body.
  2. Writes the resulting file into the service's data volume with a random name (e.g. aura_script_<random>.py).
  3. Runs docker compose run --rm <container> click-odoo --database=<db> <script-path> against the service.
  4. Captures stdout and stderr into the action record and removes the script file afterwards.

Because execution happens inside the service container with the Odoo environment fully booted, you have the same capabilities as an interactive odoo shell — including access to env, models, the registry, and any installed addons.

#Safety notes

Scripts run with full database access through the Odoo ORM. Test on a copy or preview deployment before running against production data. There is no undo for committed changes.

  • Use Creating Copies or Preview Deployments to test scripts on a non-production database first.
  • A failing script aborts its own transaction, but a script that "succeeds" with bad logic will commit. Add print(...) calls and run on a copy to verify the result before pointing it at production.
  • Compatible versions act as a safety rail — a script can never be queued against a service whose Odoo version isn't in its allow-list.
  • Scripts are scoped to your team. Other teams cannot see, edit, or run them.

#Auditing

Every script run shows up on the target service's Actions tab with the script name, who triggered it, when it ran, and the full output. Edits to a script itself are tracked in its activity timeline.