import logging from pathlib import Path from typing import Optional import click import typer from flask.cli import FlaskGroup from rich import print from rich.logging import RichHandler import ttfrog.app main_app = typer.Typer() logger = logging.getLogger("ttfrog.cli") @main_app.callback(invoke_without_command=True) def callback( context: typer.Context, verbose: bool = typer.Option(False, help="Enable verbose output."), log_level: str = typer.Option("error", help=" Set the log level."), config_file: Optional[Path] = typer.Option( "~/.dnd/ttfrog/defaults", help="Path to the ttfrog configuration file", ), ): """ Configure the execution environment with global parameters. """ logging.basicConfig( format="%(message)s", level=getattr(logging, log_level.upper()), handlers=[RichHandler(rich_tracebacks=True, tracebacks_suppress=[typer])], ) ttfrog.app.load_config(config_file) ttfrog.app.initialize() ttfrog.app.web.shell_context_processors.append(make_shell_context) if context.invoked_subcommand is None: logger.debug("No command specified; invoking default handler.") run(context) @main_app.command() def init(context: typer.Context, drop: bool = typer.Option(False, help="Drop tabless before initializing.")): """ Initialize the database. """ if drop: ttfrog.app.db.drop_tables() ttfrog.app.db.close() ttfrog.app.initialize(force=True) ttfrog.app.bootstrap() print(ttfrog.app.db) @main_app.command() def run(context: typer.Context): """ The default CLI entrypoint is ttfrog.cli.run(). """ import ttfrog.web ttfrog.app.web.run() def make_shell_context(): return ttfrog.app @click.group(cls=FlaskGroup, create_app=lambda: ttfrog.app.web) @click.pass_context def app(ctx): """ Web Application management functions """ main = typer.main.get_command(main_app) main.add_command(app, "app")