AQIT 0.1.0
Loading...
Searching...
No Matches
engine_info.py
Go to the documentation of this file.
1# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2# This file is part of the Aquin Engine. Unauthorized copying, modification,
3# distribution, or use of this file, via any medium, is strictly prohibited.
4# Proprietary and confidential. See LICENSE for terms.
5
6"""Single discovery file: ~/.aquin/engine-info.json + AQUIN_ENGINE_PORT."""
7from __future__ import annotations
8
9import json
10import os
11import sys
12from datetime import datetime, timezone
13from pathlib import Path
14from typing import Any
15
16# Product default — uncommon on purpose; never 8002.
17DEFAULT_ENGINE_PORT = 17832
18DEFAULT_ENGINE_HOST = "127.0.0.1"
19ENGINE_INFO_VERSION = "1"
20
22def aquin_home() -> Path:
23 override = (os.environ.get("AQUIN_HOME") or "").strip()
24 if override:
25 return Path(override)
26 return Path.home() / ".aquin"
27
28
29def engine_info_path() -> Path:
30 return aquin_home() / "engine-info.json"
31
32
33def load_engine_info() -> dict[str, Any] | None:
34 path = engine_info_path()
35 if not path.is_file():
36 return None
37 raw = path.read_text(encoding="utf-8-sig")
38 data = json.loads(raw)
39 if not isinstance(data, dict):
40 raise ValueError("engine-info.json is not an object")
41 return data
42
43
44def resolve_engine_port(info: dict[str, Any] | None = None) -> int:
45 env = (os.environ.get("AQUIN_ENGINE_PORT") or "").strip()
46 if env:
47 port = int(env)
48 if port <= 0 or port > 65535:
49 raise ValueError(f"invalid AQUIN_ENGINE_PORT: {env}")
50 return port
51 data = load_engine_info() if info is None else info
52 if data and data.get("port") is not None:
53 port = int(data["port"])
54 if 0 < port <= 65535:
55 return port
56 return DEFAULT_ENGINE_PORT
57
58
59def resolve_engine_host(info: dict[str, Any] | None = None) -> str:
60 data = load_engine_info() if info is None else info
61 if data and isinstance(data.get("host"), str) and data["host"].strip():
62 return data["host"].strip()
63 return DEFAULT_ENGINE_HOST
64
65
66def _utc_now() -> str:
67 return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
68
69
70def write_engine_info(patch: dict[str, Any]) -> dict[str, Any]:
71 """Merge patch into engine-info.json (create parents / defaults as needed)."""
72 home = aquin_home()
73 home.mkdir(parents=True, exist_ok=True)
74 existing: dict[str, Any] = {}
75 try:
76 loaded = load_engine_info()
77 if isinstance(loaded, dict):
78 existing = loaded
79 except Exception:
80 existing = {}
81
82 daemon = dict(existing.get("daemon") or {})
83 if isinstance(patch.get("daemon"), dict):
84 daemon.update(patch["daemon"])
85
86 merged: dict[str, Any] = {
87 "version": ENGINE_INFO_VERSION,
88 "engine_version": patch.get("engine_version", existing.get("engine_version")),
89 "python": patch.get("python") or existing.get("python") or sys.executable,
90 "compute_ready": (
91 int(patch["compute_ready"])
92 if patch.get("compute_ready") is not None
93 else int(existing.get("compute_ready", 0) or 0)
94 ),
95 "port": int(patch["port"]) if patch.get("port") is not None else resolve_engine_port(existing),
96 "host": patch.get("host") or existing.get("host") or DEFAULT_ENGINE_HOST,
97 "bin": patch.get("bin") or existing.get("bin") or str(home / "bin" / ("aquin-engine.cmd" if os.name == "nt" else "aquin-engine")),
98 "lib": patch.get("lib") or existing.get("lib") or str(home / "lib"),
99 "daemon": {
100 "status": daemon.get("status", "stopped"),
101 "pid": daemon.get("pid"),
102 "started_at": daemon.get("started_at"),
103 "model_id": daemon.get("model_id"),
104 },
105 "updated_at": _utc_now(),
106 }
107 path = engine_info_path()
108 path.write_text(json.dumps(merged, indent=2) + "\n", encoding="utf-8")
109 return merged
110
111
113 *,
114 status: str,
115 pid: int | None = None,
116 model_id: str | None = None,
117 port: int | None = None,
118 started_at: str | None = None,
119) -> dict[str, Any]:
120 return write_engine_info(
121 {
122 **({"port": port} if port is not None else {}),
123 "daemon": {
124 "status": status,
125 "pid": pid,
126 "started_at": started_at,
127 "model_id": model_id,
128 },
129 }
130 )
dict[str, Any] set_daemon_state(*, str status, int|None pid=None, str|None model_id=None, int|None port=None, str|None started_at=None)
int resolve_engine_port(dict[str, Any]|None info=None)
dict[str, Any] write_engine_info(dict[str, Any] patch)
str resolve_engine_host(dict[str, Any]|None info=None)
dict[str, Any]|None load_engine_info()