You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kmftools/delfland/webhooktest/app/routes.py

86 lines
2.4 KiB

from fastapi import APIRouter, Request, Form, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi.security import APIKeyHeader
from dotenv import load_dotenv
import os
import logging
from .storage import store_message, get_all_messages
load_dotenv()
API_KEY = os.getenv("API_KEY")
api_key_header = APIKeyHeader(name="x-api-key", auto_error=False)
router = APIRouter()
templates = Jinja2Templates(directory="app/templates")
# Live WebSocket connecties
active_connections = []
async def validate_api_key(api_key: str = None):
if api_key != API_KEY:
raise Exception("Unauthorized")
async def broadcast(msg: str):
for connection in active_connections:
try:
await connection.send_text(msg)
except:
continue
@router.api_route("/webhook", methods=["GET", "POST"])
async def webhook(request: Request, api_key: str = api_key_header):
await validate_api_key(api_key)
body = await request.body()
log_entry = {
"method": request.method,
"headers": dict(request.headers),
"body": body.decode()
}
logging.info(f"Webhook received: {log_entry}")
store_message(log_entry)
await broadcast(str(log_entry)) # stuur live update via websocket
return {"status": "ok"}
@router.get("/trace", response_class=HTMLResponse)
async def trace_page(request: Request):
return templates.TemplateResponse("trace.html", {
"request": request,
"messages": get_all_messages()
})
@router.websocket("/ws/trace")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
active_connections.append(websocket)
try:
while True:
await websocket.receive_text() # optioneel: keep-alive ping
except WebSocketDisconnect:
active_connections.remove(websocket)
@router.get("/send", response_class=HTMLResponse)
async def send_form(request: Request):
return templates.TemplateResponse("send.html", {"request": request})
@router.post("/send")
async def send_post(request: Request, url: str = Form(...), body: str = Form(...), key: str = Form(...)):
import httpx
headers = {"x-api-key": key}
try:
response = httpx.post(url, content=body, headers=headers)
return {
"status_code": response.status_code,
"response": response.text
}
except Exception as e:
return {"error": str(e)}