Files
mft/mft/cli.py
omicron b4c84ab7ea Initial project structure added.
The following are in a minimal working state:

- Database schema
- Basic database interaction
- Configuration file parsing
- Command line interface
- Basic route handling for categories, auth and health
- Simple static webapp files
2025-12-24 12:30:09 +01:00

75 lines
2.0 KiB
Python

import os
import sys
import argparse
import uvicorn
import mft.config
from pathlib import Path
def transform_args(args: argparse.Namespace) -> argparse.Namespace:
args.config = args.config.expanduser().absolute()
return args
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="MinimalFinanceTracker - Simple expense tracking"
)
# Global flags
parser.add_argument(
"-c",
"--config",
type=Path,
default=mft.config.get_default_config_path(),
help="Path to config file",
)
# Subcommands
subparsers = parser.add_subparsers(dest="command", required=True)
# run subcommand
run_parser = subparsers.add_parser("run", help="Run the web application")
run_parser.add_argument(
"--debug", action="store_true", help="Run in debug mode with auto-reload"
)
return transform_args(parser.parse_args())
def delayed_import_settings():
# NOTE: Because uvicorn starts new python processes we need some way to
# communicate the config file path to these other processes. This also adds
# some complexity to creating the settings object, because it can't be
# passed around to the child process. The chosen solution is to set
# MFT_CONFIG_PATH in the environment of the cli (parent) and to use this
# value in the mft.settings module to create a global settings singleton.
from mft.settings import settings
return settings
def main():
args = parse_args()
if not args.config.exists():
print(f"Error: Config file `{args.config}` does not exist.", file=sys.stderr)
sys.exit(1)
os.environ["MFT_CONFIG_PATH"] = str(args.config)
settings = delayed_import_settings()
if args.command == "run":
run_command(args, settings)
def run_command(args, settings):
uvicorn.run(
"mft.app:app",
host=settings.host,
port=settings.port,
reload=args.debug,
log_level="debug" if args.debug else "info",
)
if __name__ == "__main__":
main()