1|from fastapi import Depends, FastAPI, HTTPException 2|from pydantic import BaseModel 3|from fastapi.security import HTTPBasic, HTTPBasicCredentials 4|from config import get_settings 5| 6|from challenges.Blogpost import Blogpost 7|from challenges.Carbeat import Carbeat 8|from challenges.CDN import CDN 9|from challenges.Phew import Phew 10|from challenges.Sheesh import Sheesh 11|from challenges.Warmup import Warmup 12| 13|import os 14|import asyncio 15|import logging 16| 17|# Setup logging 18|logging.basicConfig(level=logging.INFO) 19|logger = logging.getLogger(__name__) 20| 21|app = FastAPI() 22|security = HTTPBasic() 23|settings = get_settings() 24| 25|def _ch_port(name: str, default: int) -> int: # read from .env manually (pydantic settings has fixed fields) val = os.environ.get(f"CHALLENGE_PORT_{name.upper()}") if not val: try: with open(os.path.join(os.path.dirname(__file__), ".env")) as f: for line in f: if line.startswith(f"CHALLENGE_PORT_{name.upper()}="): val = line.strip().split("=", 1)[1] except Exception: pass return int(val) if val else default def _ch_container(name: str, default: str) -> str: val = os.environ.get(f"CHALLENGE_CONTAINER_{name.upper()}") if not val: try: with open(os.path.join(os.path.dirname(__file__), ".env")) as f: for line in f: if line.startswith(f"CHALLENGE_CONTAINER_{name.upper()}="): val = line.strip().split("=", 1)[1] except Exception: pass return val or default challenges = { 32| "blogpost": Blogpost(_ch_port("blogpost", 10000)), 33| "carbeat": Carbeat(_ch_port("carbeat", 11000)), 34| "cdn": CDN(_ch_port("cdn", 12000)), 35| "phew": Phew(_ch_port("phew", 13000)), 36| "sheesh": Sheesh(_ch_port("sheesh", 14000)), 37| "warmup": Warmup(_ch_port("warmup", 15000)), 38|} 39| 40|async def run_challenge_checks(): 41|