Custom Bench Commands
Frappe allows you to extend the Bench CLI by adding custom commands inside your own application. During execution, the bench_manager module scans installed apps for command modules and automatically makes those commands available through the Bench CLI.
Custom Bench commands are useful for automating repetitive tasks such as data migration, maintenance scripts, environment setup, or application-specific utilities.
How Bench Discovers Custom Commands
Along with the built-in framework commands, the bench_manager module searches every installed application for a commands module.
Any Click commands registered inside this module automatically become available through the Bench CLI.
Directory Structure
Create a commands module inside your application’s main package.
frappe-bench
├── apps
│ ├── frappe
│ └── flags
│ ├── README.md
│ ├── flags
│ │ └── commands
│ ├── license.txt
│ ├── requirements.txt
│ └── setup.py
The commands module can either be:
- A single
commands.pyfile. - A directory containing an
__init__.pyfile.
Create a Custom Command
Inside the commands module, define your command using Click decorators and register it in a list named commands.
import click
@click.command("set-flags")
@click.argument("state", type=click.Choice(["on", "off"]))
def set_flags(state):
from flags.utils import set_flags
set_flags(state=state)
commands = [
set_flags
]
The variable commands must contain a list of all Click commands that should be registered with Bench.
Run the Custom Command
Once the application is installed in the current Bench, the command becomes available like any built-in Bench command.
bench set-flags on
Flags are set to state: 'on'
How It Works
- Bench invokes the Frappe
bench_manager. - Frappe scans every installed application for a
commandsmodule. - All registered Click commands are collected.
- The commands become available through the Bench CLI.
Keep custom Bench commands focused on administrative or developer tasks. For reusable business logic, place the implementation in utility modules and simply call those functions from your CLI commands.