101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
"""
|
|
routes/root.py — корневые эндпоинты (/health, /, /swagger).
|
|
|
|
Blueprint "root" регистрируется в app.py БЕЗ url_prefix.
|
|
Отвечает за healthcheck (для Nubes), HTML-страницу с информацией о сервисе,
|
|
и страницу Swagger UI.
|
|
"""
|
|
|
|
import os
|
|
from flask import Blueprint, g, render_template
|
|
from werkzeug.local import LocalProxy
|
|
|
|
import mock_state
|
|
import config.loader as _cfg
|
|
|
|
state = LocalProxy(lambda: mock_state.get_state(g.stand_id))
|
|
SERVICES = LocalProxy(lambda: _cfg.get_services(g.stand_id))
|
|
|
|
VERSION = _cfg.VERSION
|
|
|
|
# Токен для авторизации в Swagger UI (предзаполняется)
|
|
_MOCK_AUTH_TOKEN = os.getenv("MOCK_AUTH_TOKEN", "test-token-123")
|
|
|
|
# URL для OpenAPI-спеке (сервер)
|
|
_POLYGON_ENDPOINT = os.getenv("POLYGON_ENDPOINT", "https://polygon.pythonk8s.dev.nubes.ru")
|
|
|
|
# Blueprint без префикса — роуты /health и / будут на корне домена
|
|
bp = Blueprint("root", __name__)
|
|
|
|
|
|
@bp.route("/health")
|
|
def health():
|
|
"""Healthcheck для Nubes.
|
|
|
|
Платформа периодически дёргает этот эндпоинт. Если вернёт не 200 —
|
|
контейнер будет перезапущен. Возвращаем просто "OK", без JSON.
|
|
"""
|
|
return "OK"
|
|
|
|
|
|
@bp.route("/")
|
|
def index():
|
|
"""Корневая HTML-страница с информацией о сервисе.
|
|
|
|
Показывает: версию, количество загруженных сервисов, количество инстансов,
|
|
текущую задержку операций, список сервисов с операциями.
|
|
Использует Jinja2-шаблон templates/index.html и внешний CSS из static/style.css.
|
|
"""
|
|
svc_count = len(_cfg.SERVICES)
|
|
inst_count = len(state.instances)
|
|
|
|
# Список стендов
|
|
stands_list = []
|
|
for sid in _cfg.list_stands():
|
|
svc = _cfg.get_services(sid)
|
|
stands_list.append({
|
|
"id": sid,
|
|
"count": len(svc),
|
|
})
|
|
current_stand = g.stand_id
|
|
|
|
# Список сервисов для таблицы: name, id, кол-во операций
|
|
svc_list = []
|
|
for sid, svc in sorted(_cfg.SERVICES.items(), key=lambda x: x[1].get("name", x[0])):
|
|
svc_list.append({
|
|
"id": sid,
|
|
"name": svc.get("name", sid),
|
|
"display_name": svc.get("service_display_name", svc.get("name", "")),
|
|
"op_count": len(svc.get("operations", [])),
|
|
"has_cfs": bool(svc.get("cfsParams")),
|
|
"has_state": bool(svc.get("stateParams")),
|
|
"has_out": bool(svc.get("stateOut")),
|
|
})
|
|
|
|
return render_template(
|
|
"index.html",
|
|
version=_cfg.VERSION,
|
|
svc_count=svc_count,
|
|
inst_count=inst_count,
|
|
delay=_cfg.DELAY,
|
|
svc_list=svc_list,
|
|
stands_list=stands_list,
|
|
current_stand=current_stand,
|
|
endpoint=_POLYGON_ENDPOINT,
|
|
)
|
|
|
|
|
|
@bp.route("/swagger")
|
|
def swagger():
|
|
"""Swagger UI — интерактивная документация API.
|
|
|
|
Загружает Swagger UI с CDN, указывает на /api/v1/svc/openapi.json.
|
|
Токен авторизации предзаполняется автоматически (MOCK_AUTH_TOKEN).
|
|
"""
|
|
return render_template(
|
|
"swagger.html",
|
|
version=_cfg.VERSION,
|
|
openapi_url="/api/v1/svc/openapi.json",
|
|
auth_token=_MOCK_AUTH_TOKEN,
|
|
)
|