import requests import json import logging import time from fastapi import FastAPI, Header, Request, Query, HTTPException from fastapi.responses import JSONResponse app = FastAPI() logging.basicConfig(level=logging.INFO) cache = {} @app.get("/") def ip( request: Request, X_Forwarded_For: str = Header(None), User_Agent: str = Header("Mozilla/5.0"), Accept: str = Header("text/plain"), Accept_Language: str = Header("en-us"), lookup: str = Query(None), ): if lookup: ip = lookup elif X_Forwarded_For: ip = X_Forwarded_For else: ip = request.client.host if ip in cache: data, timestamp = cache[ip] if time.time() - timestamp < 3600: logging.info("cache hit for %s", ip) return JSONResponse(data) logging.info("cache expired for %s", ip) logging.info("looking up IP info for %s", ip) try: response = requests.get( "https://ip.shronk.tech/lookup?ip=" + ip, headers={ "User-Agent": User_Agent, "Accept": Accept, "Accept-Language": Accept_Language, "Dnt": "1", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1", "Sec-Gpc": "1", "Upgrade-Insecure-Requests": "1" } ) response.raise_for_status() except Exception as e: logging.error("Failed to get data for %s: %s", ip, e, exc_info=True) raise HTTPException(500, "Failed to get upstream data.") try: data = response.json() except json.JSONDecodeError as e: logging.error("Failed to parse data for %s: %s", ip, e, exc_info=True) raise HTTPException(500, "Failed to parse upstream response.") logging.info("%s -> %r", ip, data) data["ip"] = ip data.pop("legalese", None) data.pop("source", None) data.pop("brexitRequired", None) if response.status_code == 200: cache[ip] = [data, time.time()] return JSONResponse(data, response.status_code)