Source code for dawsonia.cli

"""CLI interface for ``dawsonia`` command"""

from __future__ import annotations

import ast
import sys
from pathlib import Path

import typer
from typer import Typer

from dawsonia import DAWSONIA_DEBUG
from dawsonia._version import __version__

CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])

package = (
    "DAWSONIA: Digitize hAndWritten obServatiONs In weather journAls "
    f"(version {__version__})"
    "This is the main command which provides subcommands for different "
    "stages of the pipeline"
)


app = Typer(
    help=package,
    pretty_exceptions_enable=DAWSONIA_DEBUG,
    context_settings=CONTEXT_SETTINGS,
)
# Sub-commands
# app.add_typer(label.app, name="label")
# app.add_typer(prepare.app, name="prepare")
# app.add_typer(ml.app, name="ml")
# app.add_typer(digitize.app, name="digitize")

# Sub-commands: lazy load
# To get docstrings quickly and to avoid all importing all the dependencies,\
# we can do the following trick


[docs] def get_docstring(module_path, func_name): """Parse a module from the source file and read the docstring of a certain function""" with ( Path(__file__) .parent.joinpath(*module_path.split(".")) .with_suffix(".py") .open(encoding="utf-8") ) as module_code: module = ast.parse(module_code.read()) func_def = next( node for node in module.body if isinstance(node, ast.FunctionDef) and node.name == func_name ) return ast.get_docstring(func_def)
if "label" in sys.argv: from dawsonia import label app.add_typer(label.app, name="label") elif "prepare" in sys.argv: from dawsonia import prepare app.add_typer(prepare.app, name="prepare") elif "ml" in sys.argv: from dawsonia import ml app.add_typer(ml.app, name="ml") elif "digitize" in sys.argv: from dawsonia import digitize app.add_typer(digitize.app, name="digitize") else: for module, func_name in [ ("label", "command"), ("prepare", "command"), ("ml.cli", "command"), ("digitize", "digitize_book"), ]: fake_app = Typer(help=get_docstring(module, func_name)) @fake_app.callback(name=module.split(".")[0], invoke_without_command=True) def fake_command(): pass app.add_typer(fake_app) if __name__ == "__main__": # To quickly check logging level # python -m dawsonia.cli -h import logging logger = logging.getLogger("dawsonia.cli") logger.info(package) level = logger.getEffectiveLevel() logger.log(level, f"Log {level = }") app() elif "sphinx" in sys.modules: # For documentation typer_click_object = typer.main.get_command(app)