# veqen_dep.py
import os
import httpx
from fastapi import HTTPException, Request
from pydantic import BaseModel, EmailStr
client = httpx.AsyncClient(
base_url="https://veqen-app.com",
headers={"Authorization": f"Bearer {os.environ['VEQEN_API_KEY']}"},
timeout=4,
)
class SignupIn(BaseModel):
email: EmailStr
password: str
phone: str | None = None
async def screen(body: SignupIn, request: Request) -> dict | None:
ip = request.headers.get("x-forwarded-for", "").split(",")[0].strip() or request.client.host
try:
response = await client.post("/v1/signup/check", json={"email": body.email, "ip": ip, "phone": body.phone})
response.raise_for_status()
result = response.json()
except httpx.HTTPError:
return None # fail open
if result["risk"]["verdict"] == "refuse":
raise HTTPException(400, "Please use a permanent email address.")
return result
# main.py
from fastapi import Depends, FastAPI
from veqen_dep import SignupIn, screen
app = FastAPI()
@app.post("/signup", status_code=201)
async def signup(body: SignupIn, check: dict | None = Depends(screen)):
needs_verification = check is None or check["risk"]["verdict"] == "review"
user = await create_user(body, needs_verification=needs_verification)
return {"id": user.id, "verify_email": needs_verification}
Run uvicorn with --proxy-headers --forwarded-allow-ips=<your proxy> so request.client.host is the visitor when you're behind a load balancer.