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
75 lines
2.0 KiB
Python
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()
|