Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ jobs:

- name: Smoke test /health endpoint
run: |
docker run -d --name smoke -e PORT=8080 -e OPENAI_API_KEY=test -p 8080:8080 signwriting-description
docker run -d --name smoke -e PORT=8080 -e OPENAI_API_KEY=test -e TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA -p 8080:8080 signwriting-description
sleep 5 # wait for uvicorn cold start
curl -sf http://localhost:8080/health
29 changes: 28 additions & 1 deletion signwriting_description/server.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import os
from datetime import UTC, datetime

import httpx
import uvicorn
from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException, Query
from fastapi import FastAPI, HTTPException, Query, Request
from fastapi.responses import JSONResponse
from signwriting.formats.fsw_to_sign import fsw_to_sign

Expand All @@ -15,9 +16,35 @@
if not OPENAI_API_KEY:
raise RuntimeError("Missing OPENAI_API_KEY environment variable")

TURNSTILE_SECRET_KEY = os.getenv("TURNSTILE_SECRET_KEY")
if not TURNSTILE_SECRET_KEY:
raise RuntimeError("Missing TURNSTILE_SECRET_KEY environment variable")

app = FastAPI(title="Signwriting Description API")



@app.middleware("http")
async def turnstile_verification(request: Request, call_next):
if request.url.path == "/health":
return await call_next(request)

token = request.headers.get("cf-turnstile-response")
if not token:
return JSONResponse(status_code=403, content={"error": "Missing Turnstile token"})

async with httpx.AsyncClient() as client:
result = await client.post(
"https://challenges.cloudflare.com/turnstile/v0/siteverify",
data={"secret": TURNSTILE_SECRET_KEY, "response": token},
)

if not result.json().get("success"):
return JSONResponse(status_code=403, content={"error": "Invalid Turnstile token"})

return await call_next(request)


@app.get("/health")
def health():
return {
Expand Down
Loading