Files
nas-tools/dashboard/backend/main.py
T
Gan, Jimmy 0519a4b4c6
Deploy Dashboard / deploy (push) Successful in 3m24s
fix: add proxy support to httpx to allow Telegram API requests
2026-02-20 10:36:59 +08:00

59 lines
2.7 KiB
Python

from fastapi import FastAPI, Depends
from fastapi.staticfiles import StaticFiles
from routers import docker_router, gitea, files, terminal, system, auth
import auth as auth_module
import asyncio
import httpx
from config import TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID
app = FastAPI(title="NAS Dashboard")
async def monitor_containers():
import docker
from config import DOCKER_HOST
client = docker.DockerClient(base_url=DOCKER_HOST)
# Store initial states
previous_states = {}
while True:
try:
for c in client.containers.list(all=True):
current_status = c.status
if c.id in previous_states:
prev_status = previous_states[c.id]
# Alert if it transitioned from running to exited or unhealthy
if prev_status == "running" and current_status in ("exited", "dead"):
msg = f"⚠️ *Container Alert* ⚠️\nContainer `{c.name}` just stopped unexpectedly (Status: {current_status})."
# Use httpx directly as system.send_notification expects a FastAPI request object usually
if TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID:
proxy_url = os.environ.get("HTTP_PROXY") or os.environ.get("http_proxy")
async with httpx.AsyncClient(proxy=proxy_url) as hc:
await hc.post(
f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage",
data={"chat_id": TELEGRAM_CHAT_ID, "text": msg, "parse_mode": "Markdown"},
)
previous_states[c.id] = current_status
except Exception as e:
print(f"Error in container monitor: {e}")
await asyncio.sleep(60)
@app.on_event("startup")
async def startup_event():
asyncio.create_task(monitor_containers())
# Public auth endpoints
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
# Protected endpoints
app.include_router(docker_router.router, prefix="/api/docker", dependencies=[Depends(auth_module.get_current_user)])
app.include_router(gitea.router, prefix="/api/gitea", dependencies=[Depends(auth_module.get_current_user)])
app.include_router(files.router, prefix="/api/files", dependencies=[Depends(auth_module.get_current_user)])
app.include_router(system.router, prefix="/api/system", dependencies=[Depends(auth_module.get_current_user)])
# WebSocket endpoint (auth handled inside handler via Query param)
app.add_api_websocket_route("/ws/terminal", terminal.ws_endpoint)
app.mount("/", StaticFiles(directory="/app/static", html=True), name="static")