.
This commit is contained in:
@@ -9,12 +9,13 @@ Endpoint-и:
|
||||
GET /api/search — търсене (?q=&prefix=)
|
||||
GET /api/section/{code} — една секция с пълен текст
|
||||
POST /api/keywords/{code} — обновяване на keywords
|
||||
GET /healthz — health + OUTPUT_DIR статус
|
||||
GET /healthz — health + OUTPUT_DIR статус + version/git
|
||||
|
||||
Env:
|
||||
HELP_DB_CONN — libpq Postgres
|
||||
OUTPUT_DIR — локален/mounted път към секциите (default: share)
|
||||
HOME_IMAGE — път към home картинка
|
||||
GIT_SHA / SOURCE_COMMIT / COMMIT_SHA — git SHA (Coolify / Docker build-arg)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -22,6 +23,7 @@ from __future__ import annotations
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
@@ -56,9 +58,56 @@ HOME_IMAGE = os.getenv("HOME_IMAGE") # absolute path or None
|
||||
_IMG_PLACEHOLDER_RE = re.compile(r"\[IMG:\s*([^\]]+?)\s*\]")
|
||||
|
||||
BASE_DIR = Path(__file__).parent
|
||||
APP_VERSION = "0.3.0"
|
||||
_NO_CACHE = {"Cache-Control": "no-store, no-cache, max-age=0"}
|
||||
|
||||
|
||||
def _short_id(value: str, n: int = 7) -> str:
|
||||
value = value.strip()
|
||||
if not value:
|
||||
return ""
|
||||
return value[:n] if len(value) > n else value
|
||||
|
||||
|
||||
def _resolve_git() -> str:
|
||||
"""Git SHA / build id that changes on each image rebuild.
|
||||
|
||||
Prefers Coolify/runtime env, then /app/BUILD_ID (baked in Docker),
|
||||
then local ``git rev-parse``.
|
||||
"""
|
||||
for key in ("GIT_SHA", "APP_GIT_SHA", "SOURCE_COMMIT", "COMMIT_SHA"):
|
||||
raw = (os.getenv(key) or "").strip()
|
||||
if raw and raw.lower() not in {"unknown", "none", "null"}:
|
||||
return _short_id(raw)
|
||||
build_id = Path("/app/BUILD_ID")
|
||||
if build_id.is_file():
|
||||
try:
|
||||
text = build_id.read_text(encoding="utf-8").strip()
|
||||
if text:
|
||||
return _short_id(text, 7 if len(text) >= 40 else 12)
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
repo = BASE_DIR.parent
|
||||
r = subprocess.run(
|
||||
["git", "rev-parse", "--short=7", "HEAD"],
|
||||
cwd=str(repo),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=1,
|
||||
)
|
||||
if r.returncode == 0 and r.stdout.strip():
|
||||
return r.stdout.strip()
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
pass
|
||||
return "dev"
|
||||
|
||||
|
||||
GIT_SHA = _resolve_git()
|
||||
|
||||
from webapp import rescan as rescan_mod
|
||||
|
||||
app = FastAPI(title="RIP Help System", version="0.3.0")
|
||||
app = FastAPI(title="RIP Help System", version=APP_VERSION)
|
||||
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
|
||||
app.include_router(rescan_mod.router)
|
||||
|
||||
@@ -502,7 +551,7 @@ def api_delete_file_extractions(
|
||||
conn.close()
|
||||
|
||||
|
||||
@app.get("/healthz", summary="Статус на услугата и БД; output_dir_ok, txt_count.")
|
||||
@app.get("/healthz", summary="Статус на услугата и БД; version/git, output_dir_ok, txt_count.")
|
||||
def healthz():
|
||||
db_status = "ok"
|
||||
try:
|
||||
@@ -513,8 +562,16 @@ def healthz():
|
||||
conn.close()
|
||||
except Exception as e:
|
||||
return JSONResponse(
|
||||
{"status": "error", "db": str(e), "output_dir": str(OUTPUT_DIR)},
|
||||
{
|
||||
"ok": False,
|
||||
"status": "error",
|
||||
"version": f"{APP_VERSION}+{GIT_SHA}",
|
||||
"git": GIT_SHA,
|
||||
"db": str(e),
|
||||
"output_dir": str(OUTPUT_DIR),
|
||||
},
|
||||
status_code=503,
|
||||
headers=_NO_CACHE,
|
||||
)
|
||||
|
||||
out_ok = OUTPUT_DIR.is_dir()
|
||||
@@ -528,11 +585,17 @@ def healthz():
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return {
|
||||
"status": "ok",
|
||||
"db": db_status,
|
||||
"output_dir": str(OUTPUT_DIR),
|
||||
"output_dir_ok": out_ok,
|
||||
"txt_count": txt_count,
|
||||
"sample": sample,
|
||||
}
|
||||
return JSONResponse(
|
||||
{
|
||||
"ok": True,
|
||||
"status": "ok",
|
||||
"version": f"{APP_VERSION}+{GIT_SHA}",
|
||||
"git": GIT_SHA,
|
||||
"db": db_status,
|
||||
"output_dir": str(OUTPUT_DIR),
|
||||
"output_dir_ok": out_ok,
|
||||
"txt_count": txt_count,
|
||||
"sample": sample,
|
||||
},
|
||||
headers=_NO_CACHE,
|
||||
)
|
||||
|
||||
@@ -476,7 +476,7 @@
|
||||
<p>JSON API за четене на help секции, търсене и (опционално) rescan. Готово за връзка с външни системи.</p>
|
||||
|
||||
<div class="api-ep"><span class="method">GET</span><code>/healthz</code>
|
||||
<div class="desc">Статус на услугата и БД; <code>output_dir_ok</code>, <code>txt_count</code>.</div></div>
|
||||
<div class="desc">Статус на услугата и БД; <code>version</code>, <code>git</code>, <code>output_dir_ok</code>, <code>txt_count</code>.</div></div>
|
||||
<div class="api-ep"><span class="method">GET</span><code>/api/sections?prefix=RIP</code>
|
||||
<div class="desc">Списък секции (метаданни + preview текст). Филтър по <code>prefix</code>.</div></div>
|
||||
<div class="api-ep"><span class="method">GET</span><code>/api/search?q=…&prefix=RIP</code>
|
||||
|
||||
Reference in New Issue
Block a user