exwiseapi / api /views.py
devnamdev2003
Deploy Django API with Docker Build Caching
dd4466b
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import UserData, AIKey, AppVersion, Contact
from django.shortcuts import get_object_or_404
from .serializers import ContactSerializer, ExpenseRequestSerializer
from rest_framework.generics import CreateAPIView, GenericAPIView
import uuid
from .models import ExpenseLog
from django.apps import apps
import re
class UserDataPostView(APIView):
def post(self, request):
user_id = request.data.get("user_id")
if not user_id:
return Response(
{"error": "user_id is required"},
status=status.HTTP_400_BAD_REQUEST,
)
obj, created = UserData.objects.get_or_create(user_id=user_id)
# Always regenerate backup key
obj.data_backup_key = str(uuid.uuid4())
updated = False
for key in ["expenses", "salary", "category", "user_data"]:
if key in request.data and getattr(obj, key) != request.data[key]:
setattr(obj, key, request.data[key])
updated = True
obj.save() # Save once after changes
# AI key logic
if obj.has_ai_access:
AI_KEY = get_object_or_404(AIKey, isActive=True).aikey
else:
AI_KEY = None
return Response(
{
"message": (
"Data created successfully"
if created
else "Data updated successfully" if updated else "No changes made"
),
"app_version": get_object_or_404(AppVersion, isActive=True).version,
"has_music_url_access": obj.has_music_url_access,
"has_ai_access": obj.has_ai_access,
"ai_key": AI_KEY,
"data_backup_key": obj.data_backup_key,
},
status=status.HTTP_201_CREATED if created else status.HTTP_200_OK,
)
class GetFieldView(APIView):
def get(self, request, field, identifier):
# identifier can be user_id OR data_backup_key
obj = (
UserData.objects.filter(user_id=identifier).first()
or UserData.objects.filter(data_backup_key=identifier).first()
)
if not obj:
return Response({"error": "User not found"}, status=404)
if field == "all":
data = {
"userData": obj.user_data,
"expenseData": obj.expenses,
"categoryData": obj.category,
"salaryData": obj.salary,
}
return Response(data)
if hasattr(obj, field):
return Response({field: getattr(obj, field)})
return Response({"error": "Invalid field"}, status=status.HTTP_400_BAD_REQUEST)
class ContactList1(CreateAPIView):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(
{"message": "Contact saved successfully"},
status=status.HTTP_201_CREATED,
)
return Response(
{"message": "Validation failed", "errors": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
class CategorizeExpenseView(GenericAPIView):
# 2. Assign the serializer class to automatically populate the Swagger schema
serializer_class = ExpenseRequestSerializer
def post(self, request):
# 3. Validate input using the serializer
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
return Response(serializer.errors, status=400)
expense_text = serializer.validated_data["text"]
# 4. Extract Amount using Regex
# Matches formats like 150, 1,500, 150.50, 1,500.50
amount_match = re.search(r"\d+(?:,\d+)*(?:\.\d+)?", expense_text)
extracted_amount = (
float(amount_match.group().replace(",", "")) if amount_match else None
)
# 5. Use the safe Django app registry to fetch the pre-loaded AI model
api_config = apps.get_app_config("api")
result = api_config.classifier(
expense_text,
candidate_labels=api_config.categories,
hypothesis_template="This expense is for {}.",
)
top_category = result["labels"][0]
confidence_score = result["scores"][0]
# 6. Save to database
ExpenseLog.objects.create(
text=expense_text,
amount=extracted_amount,
predicted_category=top_category,
confidence_score=confidence_score,
)
return Response(
{
"expense": expense_text,
"amount": extracted_amount,
"category": top_category,
"confidence": round(confidence_score * 100, 2),
}
)