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)