Coverage for apps / ai / api_quotas.py: 97%
34 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-12 10:49 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-12 10:49 +0000
1"""
2AI quota management API endpoints.
3"""
5from ninja import Router, Schema, Status
7from apps.core.auth import AdminAuth, SessionAuth
8from apps.core.models import AppSettings
10from .services.quota import get_usage, _next_midnight_utc_iso, ALL_FEATURES, FEATURE_LIMIT_FIELDS
12router = Router(tags=["ai"])
15# Schemas
18class QuotaLimitsIn(Schema):
19 remix: int
20 remix_suggestions: int
21 scale: int
22 tips: int
23 discover: int
24 timer: int
27class QuotaLimitsOut(Schema):
28 remix: int
29 remix_suggestions: int
30 scale: int
31 tips: int
32 discover: int
33 timer: int
36class QuotaResponse(Schema):
37 limits: QuotaLimitsOut
38 usage: QuotaLimitsOut
39 unlimited: bool
40 resets_at: str
43class ErrorOut(Schema):
44 error: str
45 message: str
46 action: str | None = None
49# Helpers
52def _build_quota_response(profile, app_settings):
53 """Build a QuotaResponse dict for the given profile."""
54 limits = {feature: getattr(app_settings, FEATURE_LIMIT_FIELDS[feature]) for feature in ALL_FEATURES}
55 usage = get_usage(profile.pk)
56 unlimited = profile.unlimited_ai or (profile.user and profile.user.is_staff)
57 return {
58 "limits": limits,
59 "usage": usage,
60 "unlimited": unlimited,
61 "resets_at": _next_midnight_utc_iso(),
62 }
65# Endpoints
68@router.get("/quotas", response={200: QuotaResponse, 404: ErrorOut}, auth=SessionAuth())
69def get_quotas(request):
70 """Get current AI quota limits, usage, and reset time for the requesting user."""
71 from django.conf import settings as django_settings
73 if getattr(django_settings, "AUTH_MODE", "home") == "home":
74 return Status(404, {"error": "not_found", "message": "Quotas are not available in home mode"})
76 profile = request.auth
77 app_settings = AppSettings.get()
78 return _build_quota_response(profile, app_settings)
81@router.put("/quotas", response={200: QuotaResponse, 404: ErrorOut}, auth=AdminAuth())
82def update_quotas(request, data: QuotaLimitsIn):
83 """Update AI quota limits (admin only)."""
84 from django.conf import settings as django_settings
86 if getattr(django_settings, "AUTH_MODE", "home") == "home":
87 return Status(404, {"error": "not_found", "message": "Quotas are not available in home mode"})
89 app_settings = AppSettings.get()
90 for feature in ALL_FEATURES:
91 setattr(app_settings, FEATURE_LIMIT_FIELDS[feature], getattr(data, feature))
92 app_settings.save()
94 profile = request.auth
95 return _build_quota_response(profile, app_settings)