import os import sys import time import threading from fastapi import FastAPI from fastapi.responses import PlainTextResponse import uvicorn PORT = int(os.getenv("PORT", "7860")) # Spaces typically routes to app_port; PORT may or may not be set. app = FastAPI() def _heartbeat(): i = 0 while True: i += 1 print(f"HEARTBEAT_STDERR i={i} ts={time.time()}", file=sys.stderr, flush=True) time.sleep(15) @app.on_event("startup") def on_startup(): # Force both stdout and stderr output at container startup. print(f"BOOT_STDOUT pid={os.getpid()} ts={time.time()}", flush=True) print(f"BOOT_STDERR pid={os.getpid()} ts={time.time()}", file=sys.stderr, flush=True) t = threading.Thread(target=_heartbeat, daemon=True) t.start() @app.get("/", response_class=PlainTextResponse) def root(): print("REQ / (stdout)", flush=True) print("REQ / (stderr)", file=sys.stderr, flush=True) return "ok\n" @app.get("/health") def health(): print("REQ /health (stderr)", file=sys.stderr, flush=True) return {"status": "ok", "ts": time.time()} @app.get("/crash") def crash(): print("REQ /crash about to raise (stderr)", file=sys.stderr, flush=True) raise RuntimeError("Intentional crash for log testing") if __name__ == "__main__": # Important for Spaces: bind to 0.0.0.0, and use the configured port (default 7860). uvicorn.run( "app:app", host="0.0.0.0", port=PORT, log_level="info", access_log=True, )