Ok, so I thought a little, and it seems that the following might work. This is probably not the final decision, but it seems to be the first step.
I can extend the MultiCommand class:
# my_click_classes.py import click class ClickApp(click.MultiCommand): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.commands = {} def add_command(self, command_name, command): self.commands.update({command_name: command}) def list_commands(self, ctx): return [name for name, _ in self.commands.items()] def get_command(self, ctx, name): return self.commands.get(name)
And the Command class:
class MyCommand(click.Command): def init_app(self, app): return app.add_command(self.name, self) def mycommand(*args, **kwargs): return click.command(cls=MyCommand)
This allows you to have commands defined in separate modules:
# commands.py from my_click_classes import command @command def run(): print("run!!!") @command def walk(): print("walk...")
and "application" in a separate module:
from my_click_classes import ClickApp from commands import run, walk app = ClickApp() run.init_app(app) walk.init_app(app) if __name__ == '__main__': app()
Or even use the "app factory" template.
Perhaps this is not a final decision. If you guys can see any way to improve it, please let me know.