All checks were successful
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 9s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 8s
Introduced a front-end mechanism to notify users of available service updates and enhanced the service info page to reflect update status dynamically. Removed backend audit log writes for version checks to streamline operations and improve performance. Updated styling to visually highlight update notifications.
95 lines
3.1 KiB
Python
95 lines
3.1 KiB
Python
import os
|
|
import platform
|
|
from datetime import datetime, timezone
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.config import get_settings
|
|
from app.core.db import get_db
|
|
from app.core.deps import get_current_user
|
|
from app.models.models import ServiceInfoSettings, User
|
|
from app.schemas.service_info import ServiceInfoCheckResult, ServiceInfoOut
|
|
from app.services.service_info import (
|
|
UPSTREAM_REPO_WEB,
|
|
fetch_latest_from_upstream,
|
|
is_update_available,
|
|
utcnow,
|
|
)
|
|
|
|
router = APIRouter()
|
|
settings = get_settings()
|
|
service_started_at = datetime.now(timezone.utc)
|
|
|
|
|
|
async def _get_or_create_service_settings(db: AsyncSession) -> ServiceInfoSettings:
|
|
row = await db.scalar(select(ServiceInfoSettings).limit(1))
|
|
if row:
|
|
return row
|
|
row = ServiceInfoSettings(current_version=settings.app_version)
|
|
db.add(row)
|
|
await db.commit()
|
|
await db.refresh(row)
|
|
return row
|
|
|
|
|
|
def _to_out(row: ServiceInfoSettings) -> ServiceInfoOut:
|
|
uptime_seconds = int((utcnow() - service_started_at).total_seconds())
|
|
return ServiceInfoOut(
|
|
app_name=settings.app_name,
|
|
environment=settings.environment,
|
|
api_prefix=settings.api_v1_prefix,
|
|
app_version=settings.app_version,
|
|
hostname=platform.node() or os.getenv("HOSTNAME", "unknown"),
|
|
python_version=platform.python_version(),
|
|
platform=platform.platform(),
|
|
service_started_at=service_started_at,
|
|
uptime_seconds=max(uptime_seconds, 0),
|
|
update_source=UPSTREAM_REPO_WEB,
|
|
latest_version=row.latest_version,
|
|
latest_ref=(row.release_check_url or None),
|
|
update_available=row.update_available,
|
|
last_checked_at=row.last_checked_at,
|
|
last_check_error=row.last_check_error,
|
|
)
|
|
|
|
|
|
@router.get("/info", response_model=ServiceInfoOut)
|
|
async def get_service_info(
|
|
user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
) -> ServiceInfoOut:
|
|
_ = user
|
|
row = await _get_or_create_service_settings(db)
|
|
return _to_out(row)
|
|
|
|
|
|
@router.post("/info/check", response_model=ServiceInfoCheckResult)
|
|
async def check_service_version(
|
|
user: User = Depends(get_current_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
) -> ServiceInfoCheckResult:
|
|
_ = user
|
|
row = await _get_or_create_service_settings(db)
|
|
check_time = utcnow()
|
|
latest, latest_ref, error = await fetch_latest_from_upstream()
|
|
|
|
row.last_checked_at = check_time
|
|
row.last_check_error = error
|
|
if latest:
|
|
row.latest_version = latest
|
|
row.release_check_url = latest_ref
|
|
row.update_available = is_update_available(settings.app_version, latest)
|
|
else:
|
|
row.update_available = False
|
|
await db.commit()
|
|
await db.refresh(row)
|
|
return ServiceInfoCheckResult(
|
|
latest_version=row.latest_version,
|
|
latest_ref=(row.release_check_url or None),
|
|
update_available=row.update_available,
|
|
last_checked_at=row.last_checked_at or check_time,
|
|
last_check_error=row.last_check_error,
|
|
)
|