Files
FabledCurator/backend/app/api/__init__.py
T
bvandeusenandClaude Opus 5 fe4e0f2b71
CI / lint (push) Successful in 5s
Build images / sign-extension (push) Successful in 5s
Build images / build-agent (push) Successful in 8s
CI / extension-version (push) Successful in 4s
CI / frontend-build (push) Successful in 20s
CI / backend-lint-and-test (push) Successful in 35s
Build images / build-web (push) Successful in 1m1s
Build images / smoke-web (push) Skipped
CI / integration (push) Successful in 1m51s
Build images / build-ml (push) Successful in 1m59s
Build images / promote (push) Skipped
feat: /api/system/health — one verdict for the whole stack (milestone 365 step 3)
The single endpoint the nav indicator and the System page will both read.
Composing a verdict is this module's job, not the UI's.

Two kinds of part, answered differently. LEARNED — celery roles and the GPU
agent, out of service_seen, where the question is "how long since it checked
in" and the answer can be "it has not". PROBED — Postgres and Redis, always
expected, never learned, because a last-seen for them would be actively
misleading: that Redis answered thirty seconds ago says nothing about now.

**The endpoint must never fail because something it checks has failed.** That
inversion is easy to write by accident and it destroys the feature exactly
when it is needed — a 500 when Redis is down instead of `redis: down`. Every
probe is wrapped, every wait carries a deadline (rule 156), and the roster
refresh swallows its own errors. The worst case is a part reported `unknown`,
which is a true statement about the system.

Postgres is probed first and gates the rest, because if it is unreachable
nothing else can be read — and "the database is down" is the most useful
single thing this can ever say.

The staleness thresholds are the design risk, not the code, and they are
deliberately generous: 90s to doubt, 300s to disbelieve. The constraint is a
deploy rather than a crash — `docker compose up -d` rolls start-first, so a
role is briefly served by two containers and then by neither while the old one
drains. Thresholds tight enough to catch a crash in seconds would paint the
page red on every update, and an alarm that cries wolf on every deploy is one
nobody reads. Tune down only after watching a real deploy pass through. The
numbers ship in the response so the UI can explain a `stale` without keeping a
second copy of them.

States are described in sentences rather than left as chips: "Scheduler has
not checked in for 6 min — treat it as stopped" is what someone needs at the
moment they are deciding whether to go and open Portainer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTjbZZ6JirCMSaJzQV1RhA
2026-09-02 17:17:22 -04:00

74 lines
2.1 KiB
Python

"""API blueprint registration.
This module is imported by the Quart app factory; it just exposes the
top-level `api_bp` for backward compatibility with FC-1's health route,
and ALL_BLUEPRINTS for the factory to register sibling blueprints.
"""
from quart import Blueprint
from . import health
api_bp = Blueprint("api", __name__, url_prefix="/api")
api_bp.add_url_rule("/health", view_func=health.get_health, methods=["GET"])
def all_blueprints() -> list[Blueprint]:
from .admin import admin_bp
from .aliases import aliases_bp
from .artist import artist_bp
from .artists import artists_bp
from .attachments import attachments_bp
from .ccip import ccip_bp
from .cleanup import cleanup_bp
from .credentials import credentials_bp
from .downloads import downloads_bp
from .extension import extension_bp
from .gallery import gallery_bp
from .gpu import gpu_bp
from .heads import heads_bp
from .import_admin import import_admin_bp
from .ml_admin import ml_admin_bp
from .platforms import platforms_bp
from .posts import posts_bp
from .provenance import provenance_bp
from .settings import settings_bp
from .showcase import showcase_bp
from .sources import sources_bp
from .suggestions import suggestions_bp
from .system_activity import system_activity_bp
from .system_backup import system_backup_bp
from .system_health import system_health_bp
from .tags import tags_bp
from .thumbnails import thumbnails_bp
return [
api_bp,
attachments_bp,
gallery_bp,
provenance_bp,
tags_bp,
artist_bp,
artists_bp,
showcase_bp,
settings_bp,
system_activity_bp,
system_health_bp,
system_backup_bp,
admin_bp,
cleanup_bp,
import_admin_bp,
suggestions_bp,
aliases_bp,
heads_bp,
gpu_bp,
ccip_bp,
ml_admin_bp,
thumbnails_bp,
sources_bp,
platforms_bp,
posts_bp,
credentials_bp,
extension_bp,
downloads_bp,
]