|
| 1 | +title: flask.cli AppGroup Example Code |
| 2 | +category: page |
| 3 | +slug: flask-cli-appgroup-examples |
| 4 | +sortorder: 500021005 |
| 5 | +toc: False |
| 6 | +sidebartitle: flask.cli AppGroup |
| 7 | +meta: Example code for understanding how to use the AppGroup class from the flask.cli module of the Flask project. |
| 8 | + |
| 9 | + |
| 10 | +AppGroup is a class within the flask.cli module of the Flask project. |
| 11 | + |
| 12 | + |
| 13 | +## Example 1 from indico |
| 14 | +[indico](https://github.com/indico/indico) |
| 15 | +([project website](https://getindico.io/), |
| 16 | +[documentation](https://docs.getindico.io/en/stable/installation/) |
| 17 | +and [sandbox demo](https://sandbox.getindico.io/)) |
| 18 | +is a [Flask](/flask.html)-based web app for event management. |
| 19 | +The code is open sourced under the |
| 20 | +[MIT license](https://github.com/indico/indico/blob/master/LICENSE). |
| 21 | + |
| 22 | +[**indico / indico / cli / util.py**](https://github.com/indico/indico/blob/master/indico/cli/util.py) |
| 23 | + |
| 24 | +```python |
| 25 | +# util.py |
| 26 | + |
| 27 | +from __future__ import unicode_literals |
| 28 | + |
| 29 | +import traceback |
| 30 | +from importlib import import_module |
| 31 | + |
| 32 | +import click |
| 33 | +~~from flask.cli import AppGroup, FlaskGroup, ScriptInfo |
| 34 | +from flask_pluginengine import wrap_in_plugin_context |
| 35 | +from werkzeug.utils import cached_property |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | +def _create_app(info): |
| 41 | + from indico.web.flask.app import make_app |
| 42 | + return make_app(set_path=True) |
| 43 | + |
| 44 | + |
| 45 | +class IndicoFlaskGroup(FlaskGroup): |
| 46 | + |
| 47 | + def __init__(self, **extra): |
| 48 | + super(IndicoFlaskGroup, self).__init__(create_app=_create_app, add_default_commands=False, |
| 49 | + add_version_option=False, set_debug_flag=False, **extra) |
| 50 | + self._indico_plugin_commands = None |
| 51 | + |
| 52 | + def _load_plugin_commands(self): |
| 53 | + assert False |
| 54 | + |
| 55 | + def _wrap_in_plugin_context(self, plugin, cmd): |
| 56 | + cmd.callback = wrap_in_plugin_context(plugin, cmd.callback) |
| 57 | + for subcmd in getattr(cmd, 'commands', {}).viewvalues(): |
| 58 | + self._wrap_in_plugin_context(plugin, subcmd) |
| 59 | + |
| 60 | + def _get_indico_plugin_commands(self, ctx): |
| 61 | + if self._indico_plugin_commands is not None: |
| 62 | + return self._indico_plugin_commands |
| 63 | + try: |
| 64 | + from indico.core import signals |
| 65 | + from indico.util.signals import named_objects_from_signal |
| 66 | + ctx.ensure_object(ScriptInfo).load_app() |
| 67 | + cmds = named_objects_from_signal(signals.plugin.cli.send(), plugin_attr='_indico_plugin') |
| 68 | + rv = {} |
| 69 | + for name, cmd in cmds.viewitems(): |
| 70 | + if cmd._indico_plugin: |
| 71 | + self._wrap_in_plugin_context(cmd._indico_plugin, cmd) |
| 72 | + rv[name] = cmd |
| 73 | + except Exception as exc: |
| 74 | + if 'No indico config found' not in unicode(exc): |
| 75 | + click.echo(click.style('Loading plugin commands failed:', fg='red', bold=True)) |
| 76 | + click.echo(click.style(traceback.format_exc(), fg='red')) |
| 77 | + rv = {} |
| 78 | + self._indico_plugin_commands = rv |
| 79 | + return rv |
| 80 | + |
| 81 | + def get_command(self, ctx, name): |
| 82 | +~~ rv = AppGroup.get_command(self, ctx, name) |
| 83 | + if rv is not None: |
| 84 | + return rv |
| 85 | + return self._get_indico_plugin_commands(ctx).get(name) |
| 86 | + |
| 87 | + def list_commands(self, ctx): |
| 88 | + rv = set(click.Group.list_commands(self, ctx)) |
| 89 | + rv.update(self._get_indico_plugin_commands(ctx)) |
| 90 | + return sorted(rv) |
| 91 | + |
| 92 | + |
| 93 | +class LazyGroup(click.Group): |
| 94 | + |
| 95 | + def __init__(self, import_name, **kwargs): |
| 96 | + self._import_name = import_name |
| 97 | + super(LazyGroup, self).__init__(**kwargs) |
| 98 | + |
| 99 | + @cached_property |
| 100 | + def _impl(self): |
| 101 | + module, name = self._import_name.split(':', 1) |
| 102 | + return getattr(import_module(module), name) |
| 103 | + |
| 104 | + def get_command(self, ctx, cmd_name): |
| 105 | + return self._impl.get_command(ctx, cmd_name) |
| 106 | + |
| 107 | + |
| 108 | + |
| 109 | +## ... source file continues with no further AppGroup examples... |
| 110 | + |
| 111 | +``` |
| 112 | + |
0 commit comments