Files
polygon/site/app.py
T
naeel ef593101a3 feat: Swagger UI + OpenAPI 3.1.0 спека (v0.4.0)
- /swagger — Swagger UI (CDN, без pip-зависимостей)
- /api/v1/svc/openapi.json — динамическая OpenAPI 3.1.0 спека
- Nubes-брендированный topbar (лого + версия)
- Bearer-токен предзаполняется автоматически
- 17 эндпоинтов с полными схемами, примерами, описаниями
- Ссылка «Swagger» на главной странице
2026-08-01 09:41:55 +04:00

59 lines
3.0 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.
"""
polygon v0.2.2 — Mock Nubes API.
Эмулятор REST API облачной платформы Nubes для интеграционных тестов.
Blueprint'ы (каждый — отдельный файл в routes/):
- root_bp → /health, / (HTML-страница)
- services_bp → /api/v1/svc/services, /services/<id>
- instances_bp → /api/v1/svc/instances (GET list, GET detail, POST create)
- operations_bp → /api/v1/svc/instanceOperations/* (create, default, status, params, validate)
- run_bp → /api/v1/svc/instanceOperations/<uid>/run
- mock_bp → /api/v1/svc/_mock/* (reset, state, services, delay)
Деплой: Nubes pythonk8s (managed service) с gunicorn:
gunicorn app:app --workers 1 --bind 0.0.0.0:8000
⛔ РОВНО 1 ВОРКЕР — состояние в памяти, не shared между процессами.
Переменные окружения:
MOCK_OP_DELAY — задержка операции в секундах (по умолчанию 0.1)
WEB_CONCURRENCY — число gunicorn-воркеров (принудительно 1)
"""
import os
from flask import Flask
# ⛔ Принудительно 1 воркер — состояние в памяти, иначе инстансы теряются.
# setdefault не перезапишет если Nubes/Procfile уже выставил WEB_CONCURRENCY=1.
os.environ.setdefault("WEB_CONCURRENCY", "1")
# Импорт blueprint'ов — каждый отвечает за свою группу маршрутов
from routes.root import bp as root_bp
from routes.services_routes import bp as services_bp
from routes.instances_routes import bp as instances_bp
from routes.operations_routes import bp as operations_bp
from routes.run import bp as run_bp
from routes.mock_routes import bp as mock_bp
from routes.openapi import bp as openapi_bp
# Версия — единый источник правды в config/loader.py
from config.loader import VERSION
# Flask-приложение с Jinja2-шаблонами и статикой
app = Flask(__name__, template_folder="templates", static_folder="static")
# Регистрируем blueprint'ы.
# Префиксы уже заданы в url_prefix каждого blueprint'а (кроме root — он без префикса).
app.register_blueprint(root_bp) # /health, /
app.register_blueprint(services_bp) # /api/v1/svc/services
app.register_blueprint(instances_bp) # /api/v1/svc/instances
app.register_blueprint(operations_bp) # /api/v1/svc/instanceOperations + /instanceOperationCfsParams
app.register_blueprint(run_bp) # /api/v1/svc/instanceOperations/<uid>/run
app.register_blueprint(mock_bp) # /api/v1/svc/_mock/*
app.register_blueprint(openapi_bp) # /api/v1/svc/openapi.json
# Локальный запуск (без gunicorn) — только для разработки
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5000)