- Implemented custom form widgets for date, time, and datetime fields with DaisyUI styling. - Created utility functions for formatting dates, times, and numbers according to user preferences. - Developed views for profile settings, API key management, and notifications, including health check endpoints. - Added URL configurations for Themis tests and main application routes. - Established test cases for custom widgets to ensure proper functionality and integration. - Defined project metadata and dependencies in pyproject.toml for package management.
101 lines
3.3 KiB
Python
101 lines
3.3 KiB
Python
"""
|
|
DRF API views for LLM Manager — FBVs per Red Panda Standards.
|
|
"""
|
|
|
|
from rest_framework import status
|
|
from rest_framework.decorators import api_view, permission_classes
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
|
|
from ..models import LLMApi, LLMModel, LLMUsage
|
|
from .serializers import LLMApiSerializer, LLMModelSerializer, LLMUsageSerializer
|
|
|
|
|
|
@api_view(["GET"])
|
|
@permission_classes([IsAuthenticated])
|
|
def api_list(request):
|
|
"""List all LLM APIs."""
|
|
apis = LLMApi.objects.all().order_by("name")
|
|
serializer = LLMApiSerializer(apis, many=True)
|
|
return Response(serializer.data)
|
|
|
|
|
|
@api_view(["GET"])
|
|
@permission_classes([IsAuthenticated])
|
|
def api_detail(request, pk):
|
|
"""Get a specific LLM API."""
|
|
try:
|
|
api = LLMApi.objects.get(pk=pk)
|
|
except LLMApi.DoesNotExist:
|
|
return Response({"error": "Not found"}, status=status.HTTP_404_NOT_FOUND)
|
|
serializer = LLMApiSerializer(api)
|
|
return Response(serializer.data)
|
|
|
|
|
|
@api_view(["GET"])
|
|
@permission_classes([IsAuthenticated])
|
|
def model_list(request):
|
|
"""List all LLM Models, optionally filtered by API or type."""
|
|
qs = LLMModel.objects.select_related("api").order_by("api__name", "name")
|
|
api_id = request.query_params.get("api")
|
|
model_type = request.query_params.get("type")
|
|
active_only = request.query_params.get("active", "").lower() in ("1", "true")
|
|
if api_id:
|
|
qs = qs.filter(api_id=api_id)
|
|
if model_type:
|
|
qs = qs.filter(model_type=model_type)
|
|
if active_only:
|
|
qs = qs.filter(is_active=True)
|
|
serializer = LLMModelSerializer(qs, many=True)
|
|
return Response(serializer.data)
|
|
|
|
|
|
@api_view(["GET"])
|
|
@permission_classes([IsAuthenticated])
|
|
def model_detail(request, pk):
|
|
"""Get a specific LLM Model."""
|
|
try:
|
|
model = LLMModel.objects.select_related("api").get(pk=pk)
|
|
except LLMModel.DoesNotExist:
|
|
return Response({"error": "Not found"}, status=status.HTTP_404_NOT_FOUND)
|
|
serializer = LLMModelSerializer(model)
|
|
return Response(serializer.data)
|
|
|
|
|
|
@api_view(["GET"])
|
|
@permission_classes([IsAuthenticated])
|
|
def system_models(request):
|
|
"""Get the current system default models."""
|
|
data = {}
|
|
embed = LLMModel.get_system_embedding_model()
|
|
chat = LLMModel.get_system_chat_model()
|
|
reranker = LLMModel.get_system_reranker_model()
|
|
if embed:
|
|
data["embedding"] = LLMModelSerializer(embed).data
|
|
if chat:
|
|
data["chat"] = LLMModelSerializer(chat).data
|
|
if reranker:
|
|
data["reranker"] = LLMModelSerializer(reranker).data
|
|
return Response(data)
|
|
|
|
|
|
@api_view(["GET", "POST"])
|
|
@permission_classes([IsAuthenticated])
|
|
def usage_list(request):
|
|
"""List usage records for current user, or create a new usage record."""
|
|
if request.method == "GET":
|
|
qs = (
|
|
LLMUsage.objects.filter(user=request.user)
|
|
.select_related("model", "model__api")
|
|
.order_by("-timestamp")[:100]
|
|
)
|
|
serializer = LLMUsageSerializer(qs, many=True)
|
|
return Response(serializer.data)
|
|
|
|
# POST — create a usage record
|
|
serializer = LLMUsageSerializer(data=request.data)
|
|
if serializer.is_valid():
|
|
serializer.save(user=request.user)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|