Management commands

Zulip has a number of Django management commands that live under {zerver,zilencer,analytics}/management/commands/.

If you need some Python code to run with a Zulip context (access to the database, etc.) in a script, it should probably go in a management command. The key thing distinguishing these from production scripts (scripts/) and development scripts (tools/) is that management commands can access the database.

While Zulip takes advantage of built-in Django management commands for things like managing Django migrations, we also have dozens that we've written for a range of purposes:

Writing management commands

It's generally pretty easy to template off an existing management command to write a new one. Some good examples are change_user_email and deactivate_realm. The Django documentation is good, but we have a few pieces advice specific to the Zulip project.

Management commands are essentially independent Python scripts with access to the Zulip server's database and libraries; so you don't need to do anything special like restart the server when iteratively testing one, even if testing in a Zulip production environment where the server doesn't normally restart whenever a file is edited.