66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
"""Platform health probes (P0.4).
|
|
|
|
Exposes unauthenticated ``/api/health`` (quick liveness) and ``/api/health/ready``
|
|
(deep readiness: DB + JWT secret + OpenAI key). Designed to be consumed by
|
|
uptime monitors, load-balancer health checks and container orchestrators.
|
|
"""
|
|
|
|
import logging
|
|
import time
|
|
|
|
from odoo import http
|
|
from odoo.http import request
|
|
from odoo.release import version as odoo_version
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
_STARTED_AT = time.time()
|
|
|
|
|
|
class HealthController(http.Controller):
|
|
"""Platform health probes — safe to expose publicly."""
|
|
|
|
@http.route("/api/health", type="http", auth="none", methods=["GET"], csrf=False)
|
|
def health(self, **_kw):
|
|
"""Liveness probe: the process is up and able to handle HTTP."""
|
|
return request.make_json_response({
|
|
"status": "ok",
|
|
"service": "encoach-backend",
|
|
"odoo_version": odoo_version,
|
|
"uptime_seconds": int(time.time() - _STARTED_AT),
|
|
})
|
|
|
|
@http.route("/api/health/ready", type="http", auth="none", methods=["GET"], csrf=False)
|
|
def ready(self, **_kw):
|
|
"""Readiness probe: DB reachable, JWT secret configured, AI key known."""
|
|
checks = {}
|
|
ok = True
|
|
|
|
try:
|
|
request.env.cr.execute("SELECT 1")
|
|
checks["database"] = "ok"
|
|
except Exception as exc:
|
|
ok = False
|
|
checks["database"] = f"error: {exc}"
|
|
|
|
try:
|
|
IrParam = request.env["ir.config_parameter"].sudo()
|
|
checks["jwt_secret"] = "ok" if IrParam.get_param("encoach.jwt_secret") else "missing"
|
|
if checks["jwt_secret"] == "missing":
|
|
ok = False
|
|
ai_key = IrParam.get_param("encoach_ai.openai_api_key")
|
|
import os
|
|
if not ai_key:
|
|
ai_key = os.environ.get("OPENAI_API_KEY", "")
|
|
checks["openai_key"] = "ok" if ai_key else "missing"
|
|
except Exception as exc:
|
|
ok = False
|
|
checks["config"] = f"error: {exc}"
|
|
|
|
status = 200 if ok else 503
|
|
return request.make_json_response({
|
|
"status": "ok" if ok else "degraded",
|
|
"checks": checks,
|
|
"uptime_seconds": int(time.time() - _STARTED_AT),
|
|
}, status=status)
|