"""Сборка FastAPI-приложения мок-контрол-плейна (контракт ``docs/openapi.yaml``).""" from __future__ import annotations import os from typing import Any from fastapi import FastAPI from awg_api import __version__ from awg_api.contract import load_spec from awg_api.errors import install_error_handlers from awg_api.routers import auth, config, devices, ops, routing, status from awg_api.state import DEV_TOKEN, MockState from awg_api.ws import metrics TOKEN_ENV_VAR = "AWG_API_TOKEN" # noqa: S105 — имя переменной окружения, не секрет class ContractFastAPI(FastAPI): """FastAPI, отдающий ``/openapi.json`` из контрактной спецификации, не из кода.""" def openapi(self) -> dict[str, Any]: return load_spec() def create_app(state: MockState | None = None, token: str | None = None) -> FastAPI: """Создаёт приложение мок-сервера; ``state``/``token`` подменяются в тестах.""" resolved_token = token or os.environ.get(TOKEN_ENV_VAR) or DEV_TOKEN mock_state = state if state is not None else MockState() mock_state.token = resolved_token app = ContractFastAPI( title="awg-dash API", version=__version__, description="Мок-контрол-плейн по контракту docs/openapi.yaml (задача #19)", ) app.state.mock_state = mock_state app.state.api_token = resolved_token install_error_handlers(app) app.include_router(ops.router) app.include_router(auth.router) app.include_router(status.router) app.include_router(config.router) app.include_router(routing.router) app.include_router(devices.router) app.include_router(metrics.router) return app