from pathlib import Path import os from urllib.parse import quote from fastapi import FastAPI from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles BASE_DIR = Path(__file__).resolve().parent STATIC_DIR = BASE_DIR / "static" APP_DIR = BASE_DIR.parent ANIME_RIG_DIR = Path( os.getenv("ANIME_RIG_DIR", str(APP_DIR / "data" / "Anime2.5DRig")) ).resolve() AVATAR_DATA_DIR = Path( os.getenv("AVATAR_DATA_DIR", "/buckets/Anime2.5DRig/avatar_data") ).resolve() app = FastAPI(title="ChatGPT Live Avatar Test") app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") if ANIME_RIG_DIR.is_dir(): app.mount( "/Anime2.5DRig", StaticFiles(directory=ANIME_RIG_DIR, html=True), name="anime2.5drig", ) if AVATAR_DATA_DIR.is_dir(): app.mount( "/AvatarData", StaticFiles(directory=AVATAR_DATA_DIR), name="avatar-data", ) @app.get("/api/status") def status() -> dict[str, object]: index_path = ANIME_RIG_DIR / "index.html" return { "ok": True, "animeRigAvailable": index_path.is_file(), "animeRigUrl": "/Anime2.5DRig/" if index_path.is_file() else None, "samplePsdUrl": "/Anime2.5DRig/sample.psd" if index_path.is_file() else None, "expectedPath": str(ANIME_RIG_DIR), "repositoryPath": "data/Anime2.5DRig", } @app.get("/api/avatars") def avatars() -> dict[str, object]: items: list[dict[str, object]] = [] sample_path = ANIME_RIG_DIR / "sample.psd" if sample_path.is_file(): items.append({ "name": "sample.psd", "label": "sample", "url": "/Anime2.5DRig/sample.psd", "builtin": True, }) if AVATAR_DATA_DIR.is_dir(): for path in sorted(AVATAR_DATA_DIR.glob("*.psd"), key=lambda item: item.name.casefold()): items.append({ "name": path.name, "label": path.stem, "url": f"/AvatarData/{quote(path.name)}", "builtin": False, }) return { "ok": True, "directory": str(AVATAR_DATA_DIR), "bucketPath": "/buckets/Anime2.5DRig/avatar_data", "avatars": items, } @app.get("/healthz") def healthz() -> dict[str, bool]: return {"ok": True} @app.get("/") def index() -> FileResponse: return FileResponse(STATIC_DIR / "index.html")