1"""Command line: llm-api serve | scan | create-admin | create-key | status."""23from __future__ import annotations45import argparse6import asyncio7import json8import sys91011def main(argv: list[str] | None = None) -> None:12 ap = argparse.ArgumentParser(prog="llm-api")13 sub = ap.add_subparsers(dest="cmd", required=True)14 s = sub.add_parser("serve", help="run the API server")15 s.add_argument("--host")16 s.add_argument("--port", type=int)17 s.add_argument("--reload", action="store_true")18 sub.add_parser("scan", help="scan the model directory and print the registry")19 a = sub.add_parser("create-admin", help="create the admin user")20 a.add_argument("email")21 a.add_argument("password")22 k = sub.add_parser("create-key", help="create an API key")23 k.add_argument("name")24 k.add_argument("--admin", action="store_true")25 sub.add_parser("status", help="print hardware and registry summary")26 args = ap.parse_args(argv)2728 from .config import get_settings29 settings = get_settings()3031 if args.cmd == "serve":32 import uvicorn33 uvicorn.run("llm_api.main:app", host=args.host or settings.host, port=args.port or settings.port,34 reload=args.reload, log_level="info", access_log=False, timeout_keep_alive=75)35 return3637 async def _run():38 from .auth import Auth39 from .db import Database40 from .models.registry import Registry41 settings.ensure_dirs()42 db = Database(settings.db_path)43 await db.connect()44 try:45 if args.cmd == "scan":46 reg = Registry(db, settings)47 print(json.dumps(await reg.rescan(), indent=2))48 for m in await reg.list_models():49 print(f"{m['id']:50s} {m['runtime']:8s} {m['quantization'] or '':10s} "50 f"{(m['estimated_ram_gb'] or 0):6.1f} GB ctx {m['recommended_context']} {m['compatibility_status']}")51 elif args.cmd == "create-admin":52 auth = Auth(db, settings)53 uid = await auth.create_user(args.email, args.password)54 print(f"admin user #{uid} created")55 elif args.cmd == "create-key":56 auth = Auth(db, settings)57 raw, row = await auth.create_key(args.name, ["inference", "admin"] if args.admin else ["inference"])58 print(raw)59 elif args.cmd == "status":60 from .hardware import detect_hardware, sample_telemetry61 print(json.dumps(detect_hardware(settings.models_dir).to_dict(), indent=2))62 print(json.dumps(sample_telemetry(settings.models_dir).to_dict(), indent=2))63 n = await db.scalar("SELECT COUNT(*) FROM models WHERE installed=1")64 print(f"installed models: {n}")65 finally:66 await db.close()6768 asyncio.run(_run())697071if __name__ == "__main__":72 main(sys.argv[1:])73