fastapi import FastAPI, Request, HTTPException from fastapi.responses import HTMLResponse from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel import sqlite3, os, datetime from jinja2 import Template AUTH_TOKEN = os.environ.get("AUTH_TOKEN", "CHANGE_ME_SECRET") DB_PATH = "data.db" app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=False, allow_methods=["*"], allow_headers=["*"] ) # ----- DB ----- conn = sqlite3.connect(DB_PATH, check_same_thread=False) cur = conn.cursor() cur.execute( """ CREATE TABLE IF NOT EXISTS events ( id INTEGER PRIMARY KEY AUTOINCREMENT, ts TEXT, email TEXT, gaia_id TEXT, device_id TEXT, os TEXT, chrome_version TEXT, event TEXT ) """ ) conn.commit() class Event(BaseModel): timestamp: str email: str | None = None gaia_id: str | None = None device_id: str os: str | None = None chrome_version: str | None = None event: str | None = None # ----- Ingest endpoint ----- @app.post("/ingest") async def ingest(req: Request, ev: Event): auth = req.headers.get("authorization", "") if not auth.startswith("Bearer ") or auth.split(" ", 1)[1] != AUTH_TOKEN: raise HTTPException(status_code=401, detail="Unauthorized") # Validate timestamp is ISO-ish; if bad, replace with server time try: datetime.datetime.fromisoformat(ev.timestamp.replace("Z", "+00:00")) except Exception: ev.timestamp = datetime.datetime.utcnow().isoformat() + "Z" cur.execute( "INSERT INTO events (ts, email, gaia_id, device_id, os, chrome_version, event) VALUES (?,?,?,?,?,?,?)", (ev.timestamp, ev.email, ev.gaia_id, ev.device_id, ev.os, ev.chrome_version, ev.event) ) now=datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + "Z"