import io import logging from pathlib import Path from typing import Optional import click import typer from dotenv import load_dotenv from flask.cli import FlaskGroup from rich.logging import RichHandler import ttfrog.app CONFIG_DEFAULTS = """ # ttfrog Defaults LOG_LEVEL=INFO """ main_app = typer.Typer() _context = ttfrog.app.initialize() flask_app = _context.app app_state = dict( config_file=Path("~/.config/ttfrog.conf").expanduser(), ) 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( app_state["config_file"], help="Path to the ttfrog configuration file", ), ): """ Configure the execution environment with global parameters. """ app_state["config_file"] = config_file load_dotenv(stream=io.StringIO(CONFIG_DEFAULTS)) load_dotenv(app_state["config_file"]) logging.basicConfig( format="%(message)s", level=getattr(logging, log_level.upper()), handlers=[RichHandler(rich_tracebacks=True, tracebacks_suppress=[typer])], ) app_state["verbose"] = verbose if context.invoked_subcommand is None: logger.debug("No command specified; invoking default handler.") run(context) def run(context: typer.Context): """ The default CLI entrypoint is ttfrog.cli.run(). """ flask_app.run() @flask_app.shell_context_processor def make_shell_context(): return flask_app @click.group(cls=FlaskGroup, create_app=lambda: flask_app) @click.pass_context def app(ctx): """ Application management functions """ main = typer.main.get_command(main_app) main.add_command(app, "app")