petter2025's picture
Upload folder using huggingface_hub
bc549c5 verified
raw
history blame
3.54 kB
"""
User endpoints – registration, tenant creation, quota information.
"""
import uuid
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Request, Query
from sqlalchemy.orm import Session
from slowapi import Limiter
from slowapi.util import get_remote_address
from app.core.usage_tracker import tracker, enforce_quota, Tier
from app.api.deps import get_db
from app.database.models_intents import TenantDB # <-- NEW
router = APIRouter(prefix="/users", tags=["users"])
# Rate limiter for registration (5 per hour per IP)
limiter = Limiter(key_func=get_remote_address, default_limits=["5/hour"])
@router.post("/register")
@limiter.limit("5/hour")
async def register_user(
request: Request,
db: Session = Depends(get_db),
org_name: str = Query(None, description="Optional organisation name for the new tenant"),
):
"""
Public endpoint to create a new free‑tier API key and a new tenant.
Rate‑limited to 5 requests per hour per IP address.
"""
if tracker is None:
raise HTTPException(status_code=503, detail="Usage tracking service not initialised")
# 1. Create a new tenant in the main database
tenant_id = str(uuid.uuid4())
name = org_name or "Default Organization"
new_tenant = TenantDB(
id=tenant_id,
name=name,
created_at=datetime.utcnow(),
created_by="self_service"
)
db.add(new_tenant)
db.commit()
db.refresh(new_tenant)
# 2. Generate a new API key for this tenant
new_key = f"sk_free_{uuid.uuid4().hex[:24]}"
success = tracker.get_or_create_api_key(api_key=new_key, tenant_id=tenant_id, tier=Tier.FREE)
if not success:
# Rollback tenant creation if key creation fails
db.delete(new_tenant)
db.commit()
raise HTTPException(status_code=500, detail="Failed to create API key")
return {
"api_key": new_key,
"tenant_id": tenant_id,
"tier": "free",
"organization": name,
"message": "API key and tenant created. Store the key securely – you won't see it again."
}
@router.get("/me")
async def get_current_user_info(
request: Request,
quota: dict = Depends(enforce_quota),
db: Session = Depends(get_db),
):
"""
Return information about the current user's tenant and quota.
Requires API key in Authorization header.
"""
tenant_id = quota.get("tenant_id")
if not tenant_id:
raise HTTPException(status_code=403, detail="No tenant associated with this API key")
tenant = db.query(TenantDB).filter(TenantDB.id == tenant_id).first()
if not tenant:
raise HTTPException(status_code=404, detail="Tenant not found")
return {
"tenant_id": tenant_id,
"organization": tenant.name,
"created_at": tenant.created_at.isoformat() if tenant.created_at else None,
"tier": quota["tier"].value,
"remaining": quota["remaining"],
"limit": quota["limit"],
}
@router.get("/quota")
async def get_user_quota(
request: Request,
quota: dict = Depends(enforce_quota),
):
"""
Return the current user's tier, remaining quota, and tenant ID.
Requires API key in Authorization header.
"""
tier = quota["tier"]
remaining = quota["remaining"]
limit = tier.monthly_evaluation_limit if tier else None
tenant_id = quota.get("tenant_id")
return {
"tenant_id": tenant_id,
"tier": tier.value,
"remaining": remaining,
"limit": limit,
}