Files
polygon/site/routes/mock_routes.py
T

119 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
routes/mock_routes.py — служебные эндпоинты /_mock/*.
Blueprint "mock" с префиксом /api/v1/svc/_mock.
POST /reset — полный сброс состояния (для тестов)
GET /state — отладочный дамп instances + operations
GET /services — отладочный список загруженных сервисов
POST /delay/<s> — изменить MOCK_OP_DELAY на лету (не перезапуская сервер)
"""
import os
from flask import Blueprint, jsonify, request, abort
import mock_state
import config.loader as _cfg # для чтения/записи модульных переменных DELAY, SERVICES
bp = Blueprint("mock", __name__, url_prefix="/api/v1/svc/_mock")
# Токен для защиты _mock/* эндпоинтов (из env, опционально).
# Если не задан — эндпоинты открыты (dev/локально).
# Если задан — требуется заголовок X-Mock-Auth: <токен>.
_MOCK_TOKEN = os.getenv("MOCK_AUTH_TOKEN", "")
@bp.before_request
def _check_mock_auth():
"""Проверка X-Mock-Auth заголовка если MOCK_AUTH_TOKEN задан.
Вызывается Flask перед КАЖДЫМ обработчиком в этом blueprint'е.
Если токен не задан в env — пропускаем всех (dev-режим).
Если задан — требуем совпадения с заголовком."""
if _MOCK_TOKEN and request.headers.get("X-Mock-Auth") != _MOCK_TOKEN:
abort(403)
@bp.route("/reset", methods=["POST"])
def mock_reset():
"""POST /api/v1/svc/_mock/reset — полный сброс состояния.
Удаляет ВСЕ инстансы, операции и параметры из MockState.
Используется в тестах (autouse fixture) для изоляции тестов друг от друга.
"""
mock_state.state.reset()
return jsonify({"reset": "ok"})
@bp.route("/state", methods=["GET"])
def mock_state_view():
"""GET /api/v1/svc/_mock/state — отладочный дамп состояния.
Возвращает {instances: {uid: {instanceUid, displayName, status, serviceId}},
operations: {uid: {instanceOperationUid, instanceUid, operation,
dtFinish, isSuccessful}}}.
Полезно для отладки тестов: «какие инстансы сейчас живы?», «завершилась ли
операция?». НЕ для production-использования.
"""
st = mock_state.state
return jsonify({
"instances": {
uid: {
"instanceUid": inst["instanceUid"],
"displayName": inst["displayName"],
"status": inst["status"],
"serviceId": inst["serviceId"],
}
for uid, inst in st.instances.items()
},
"operations": {
uid: {
"instanceOperationUid": op["instanceOperationUid"],
"instanceUid": op["instanceUid"],
"operation": op["operation"],
"dtFinish": op["dtFinish"],
"isSuccessful": op["isSuccessful"],
}
for uid, op in st.operations.items()
},
})
@bp.route("/services", methods=["GET"])
def mock_services():
"""GET /api/v1/svc/_mock/services — отладочный список сервисов.
Возвращает {count: N, services: {svcId: {name, displayName, operations, params}}}.
Полезно чтобы быстро проверить что все 37+ сервисов загрузились,
не дёргая реальный /api/v1/svc/services.
"""
result = {}
for svc_id, svc_def in _cfg.SERVICES.items():
result[str(svc_id)] = {
"name": svc_def.get("name", ""),
"displayName": svc_def.get("service_display_name", ""),
"operations": len(svc_def.get("operations", [])),
"params": len(svc_def.get("cfsParams", [])),
}
return jsonify({"count": len(result), "services": result})
@bp.route("/delay/<string:seconds>", methods=["POST"])
def mock_set_delay(seconds):
"""POST /api/v1/svc/_mock/delay/{s} — изменить задержку операции.
Меняет config.loader.DELAY «на лету», без перезапуска сервера.
Полезно в тестах: установить delay=0 для мгновенных операций,
или delay=5 чтобы проверить таймауты поллинга.
ВАЖНО: меняет модульную переменную config.loader.DELAY, которую читает
routes/run.py при каждом вызове /run.
Принимает строку и конвертирует в float — Flask <float:> не матчит
целые числа без десятичной точки (0, 2).
"""
_cfg.DELAY = float(seconds)
return jsonify({"delay": _cfg.DELAY})