import argparse import os import sys import json from configparser import ConfigParser from healthcheck import ensure_config_exists def configparser_to_dict(cp: ConfigParser) -> dict: d = {} for section in cp.sections(): d[section] = {} for key, val in cp.items(section): d[section][key] = val return d def load_config(config_path=None): if config_path: if not os.path.exists(config_path): print(f"[ERROR] Config file not found: {config_path}") sys.exit(1) try: with open(config_path, "r", encoding="utf-8") as f: data = json.load(f) return data except json.JSONDecodeError: cp = ConfigParser() cp.read(config_path) return configparser_to_dict(cp) except Exception as e: print(f"[ERROR] Failed to read config file: {e}") sys.exit(1) else: cfg = ensure_config_exists() if isinstance(cfg, ConfigParser): return configparser_to_dict(cfg) return cfg def parse_args(): parser = argparse.ArgumentParser( prog="OpenSMN", description="Run the SMN API with custom configuration." ) parser.add_argument( "-c", "--config", type=str, help="Path to a custom configuration file (INI or JSON)." ) parser.add_argument( "-p", "--port", type=int, help="Override the server port defined in config." ) parser.add_argument( "--no-auth", action="store_true", help="Disable authentication even if password is defined in config." ) parser.add_argument( "--show-config", action="store_true", help="Print the loaded configuration and exit." ) parser.add_argument( "--base-path", type=str, help="Override the base API path." ) return parser.parse_args() def main(): args = parse_args() config = load_config(args.config) server_cfg = config.get("server", {}) # apply cli overrides if args.port: server_cfg["port"] = str(args.port) if args.base_path: server_cfg["base_path"] = args.base_path if args.no_auth: server_cfg["password"] = "" if args.show_config: print(json.dumps(config, indent=2, ensure_ascii=False)) sys.exit(0) # run the server import server server.run_from_cli(config) if __name__ == "__main__": main()