Enhance API response handling and implement unified API standard across multiple modules. Added feature flags for unified exception handling and debug throttling in settings. Updated pagination and response formats in various viewsets to align with the new standard. Improved error handling and response validation in frontend components for better user feedback.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
"""
|
||||
ViewSets for Billing API
|
||||
Unified API Standard v1.0 compliant
|
||||
"""
|
||||
from rest_framework import viewsets, status, permissions
|
||||
from rest_framework.decorators import action
|
||||
@@ -10,6 +11,8 @@ from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
from igny8_core.api.base import AccountModelViewSet
|
||||
from igny8_core.api.pagination import CustomPageNumberPagination
|
||||
from igny8_core.api.response import success_response, error_response
|
||||
from igny8_core.api.throttles import DebugScopedRateThrottle
|
||||
from igny8_core.api.authentication import JWTAuthentication, CSRFExemptSessionAuthentication
|
||||
from .models import CreditTransaction, CreditUsageLog
|
||||
from .serializers import (
|
||||
@@ -23,9 +26,12 @@ from .exceptions import InsufficientCreditsError
|
||||
class CreditBalanceViewSet(viewsets.ViewSet):
|
||||
"""
|
||||
ViewSet for credit balance operations
|
||||
Unified API Standard v1.0 compliant
|
||||
"""
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
|
||||
throttle_scope = 'billing'
|
||||
throttle_classes = [DebugScopedRateThrottle]
|
||||
|
||||
@action(detail=False, methods=['get'])
|
||||
def balance(self, request):
|
||||
@@ -37,9 +43,10 @@ class CreditBalanceViewSet(viewsets.ViewSet):
|
||||
account = getattr(user, 'account', None)
|
||||
|
||||
if not account:
|
||||
return Response(
|
||||
{'error': 'Account not found'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
return error_response(
|
||||
error='Account not found',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Get plan credits per month
|
||||
@@ -63,18 +70,21 @@ class CreditBalanceViewSet(viewsets.ViewSet):
|
||||
}
|
||||
|
||||
serializer = CreditBalanceSerializer(data)
|
||||
return Response(serializer.data)
|
||||
return success_response(data=serializer.data, request=request)
|
||||
|
||||
|
||||
class CreditUsageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""
|
||||
ViewSet for credit usage logs
|
||||
Unified API Standard v1.0 compliant
|
||||
"""
|
||||
queryset = CreditUsageLog.objects.all()
|
||||
serializer_class = CreditUsageLogSerializer
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
|
||||
pagination_class = CustomPageNumberPagination
|
||||
throttle_scope = 'billing'
|
||||
throttle_classes = [DebugScopedRateThrottle]
|
||||
|
||||
filter_backends = []
|
||||
|
||||
@@ -116,9 +126,10 @@ class CreditUsageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
account = getattr(user, 'account', None)
|
||||
|
||||
if not account:
|
||||
return Response(
|
||||
{'error': 'Account not found'},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
return error_response(
|
||||
error='Account not found',
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
request=request
|
||||
)
|
||||
|
||||
# Get date range from query params
|
||||
@@ -192,7 +203,7 @@ class CreditUsageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
}
|
||||
|
||||
serializer = UsageSummarySerializer(data)
|
||||
return Response(serializer.data)
|
||||
return success_response(data=serializer.data, request=request)
|
||||
|
||||
@action(detail=False, methods=['get'], url_path='limits', url_name='limits')
|
||||
def limits(self, request):
|
||||
@@ -222,12 +233,12 @@ class CreditUsageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
if not account:
|
||||
logger.warning(f'No account found in limits endpoint')
|
||||
# Return empty limits instead of error - frontend will show "no data" message
|
||||
return Response({'limits': []})
|
||||
return success_response(data={'limits': []}, request=request)
|
||||
|
||||
plan = account.plan
|
||||
if not plan:
|
||||
# Return empty limits instead of error - allows frontend to show "no plan" message
|
||||
return Response({'limits': []})
|
||||
return success_response(data={'limits': []}, request=request)
|
||||
|
||||
# Import models
|
||||
from igny8_core.modules.planner.models import Keywords, Clusters, ContentIdeas
|
||||
@@ -430,18 +441,21 @@ class CreditUsageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
])
|
||||
|
||||
# Return data directly - serializer validation not needed for read-only endpoint
|
||||
return Response({'limits': limits_data})
|
||||
return success_response(data={'limits': limits_data}, request=request)
|
||||
|
||||
|
||||
class CreditTransactionViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""
|
||||
ViewSet for credit transaction history
|
||||
Unified API Standard v1.0 compliant
|
||||
"""
|
||||
queryset = CreditTransaction.objects.all()
|
||||
serializer_class = CreditTransactionSerializer
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
authentication_classes = [JWTAuthentication, CSRFExemptSessionAuthentication]
|
||||
pagination_class = CustomPageNumberPagination
|
||||
throttle_scope = 'billing'
|
||||
throttle_classes = [DebugScopedRateThrottle]
|
||||
|
||||
def get_queryset(self):
|
||||
"""Get transactions for current account"""
|
||||
|
||||
Reference in New Issue
Block a user