clipforge / main.py
clove1002's picture
Debug: Test actual HTTP connectivity to candidate instances in health endpoint
35208e1
Raw
History Blame Contribute Delete
3.03 kB
import os
import socket
from dotenv import load_dotenv
load_dotenv()
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from routers import video
from cleanup import start_cleanup_scheduler
def write_cookies_from_secret():
"""Decode YT_COOKIES_B64 secret and write to disk at startup."""
b64 = os.environ.get("YT_COOKIES_B64", "")
if not b64:
return
import base64
cookies_path = os.environ.get("YT_COOKIES_PATH", "/home/user/app/cookies.txt")
with open(cookies_path, "wb") as f:
f.write(base64.b64decode(b64))
print(f"[startup] cookies.txt written to {cookies_path}")
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Start background cleanup on startup, cleanup on shutdown."""
write_cookies_from_secret()
start_cleanup_scheduler()
yield
app = FastAPI(
title="ClipForge API",
version="2.0.0",
description="AI-powered video clip generator. Turns long videos into short viral clips with karaoke-style captions.",
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=False,
allow_methods=["*"],
allow_headers=["*"],
)
# API routes
app.include_router(video.router, prefix="/api/video", tags=["video"])
# Create working directories
os.makedirs("uploads", exist_ok=True)
os.makedirs("outputs", exist_ok=True)
# Serve output clips as static files
app.mount("/outputs", StaticFiles(directory="outputs"), name="outputs")
@app.get("/", tags=["root"])
def root():
return {
"app": "ClipForge API",
"version": "2.0.0",
"docs": "/docs",
"health": "/health",
}
@app.get("/health", tags=["health"])
def health_check():
import requests as req
def http_check(url):
try:
r = req.get(url, timeout=8, headers={"User-Agent": "Mozilla/5.0"}, allow_redirects=True)
return r.status_code
except Exception as e:
return str(e)[:60]
candidates = {
"cobalt.privacyredirect.com": "https://cobalt.privacyredirect.com/",
"inv.nadeko.net": "https://inv.nadeko.net/api/v1/videos/dQw4w9WgXcQ",
"yewtu.be": "https://yewtu.be/api/v1/videos/dQw4w9WgXcQ",
"invidious.fdn.fr": "https://invidious.fdn.fr/api/v1/videos/dQw4w9WgXcQ",
"iv.datura.network": "https://iv.datura.network/api/v1/videos/dQw4w9WgXcQ",
"pipedapi.kavin.rocks": "https://pipedapi.kavin.rocks/streams/dQw4w9WgXcQ",
"piped-api.garudalinux.org": "https://piped-api.garudalinux.org/streams/dQw4w9WgXcQ",
}
return {
"status": "ok",
"connectivity": {name: http_check(url) for name, url in candidates.items()},
"cookies": "present" if os.path.exists(os.environ.get("YT_COOKIES_PATH", "/home/user/app/cookies.txt")) else "missing",
"environment": "huggingface"
}