From b2fe16aeaac68f6c5d11eb738bb24d4005d47609 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 25 Jul 2025 10:16:35 +0530 Subject: [PATCH] Optimize data analyzer agent for PDF-only processing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Restrict file upload to PDF files only in frontend and backend - Add comprehensive PDF MIME type validation - Remove duplicate processing view and URL endpoint - Update model help text and UI labels for PDF-only - Clean up unused imports and code references - Maintain rich results formatting with HTML rendering - Preserve all existing webhook processing functionality 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- data_analyzer/models.py | 6 +- .../templates/data_analyzer/detail.html | 2425 +++++------------ data_analyzer/urls.py | 1 - data_analyzer/views.py | 71 +- 4 files changed, 715 insertions(+), 1788 deletions(-) diff --git a/data_analyzer/models.py b/data_analyzer/models.py index bc5617b..efc23c5 100644 --- a/data_analyzer/models.py +++ b/data_analyzer/models.py @@ -10,7 +10,11 @@ class DataAnalysisAgentRequest(BaseAgentRequest): """Data Analysis Agent request tracking""" # Agent-specific request fields - data_file = models.FileField(upload_to='uploads/data_analyzer/', blank=True) + data_file = models.FileField( + upload_to='uploads/data_analyzer/', + blank=True, + help_text='PDF file for analysis' + ) analysis_type = models.CharField( max_length=50, choices=[ diff --git a/data_analyzer/templates/data_analyzer/detail.html b/data_analyzer/templates/data_analyzer/detail.html index 42d52d6..5f088a3 100644 --- a/data_analyzer/templates/data_analyzer/detail.html +++ b/data_analyzer/templates/data_analyzer/detail.html @@ -4,233 +4,695 @@ {% block title %}Data Analyzer - NetCop AI Hub{% endblock %} {% block extra_css %} - + +{% endblock %} + +{% block content %} + + +
+ + {% include "components/agent_header.html" with agent_title="Data Analyzer" agent_subtitle="AI-powered analysis of your data files with comprehensive insights" %} + + + {% include "components/quick_agents_panel.html" %} + + +
+ +
+
+

+ 📊 + Data Analysis Configuration +

+
+
+
+ {% csrf_token %} + + +
+ +
+
+
📁
+
Click to upload or drag and drop
+
PDF files only
+
+
+ +
Supported format: PDF files only. Max size: 10MB
+
+ + +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+ + +
+ {% if user.is_authenticated %} + {% if user.wallet_balance >= 5.00 %} + + {% else %} +
+ Insufficient balance! You need 5.00 AED. +
+ + 💰 Top Up Wallet + + {% endif %} + {% else %} + + 🔐 Login to Continue + + {% endif %} +
+
+
+
+ + +
+
+

+ â„šī¸ + How It Works +

+
+
+
    +
  1. Upload your PDF file
  2. +
  3. Choose analysis type and preferences
  4. +
  5. Our AI analyzes your data
  6. +
  7. Get comprehensive insights and reports
  8. +
+ + + +
+
+
+ + +
+ + {% include "components/processing_status.html" with status_title="Analyzing Your Data..." status_text="Please wait while our AI processes your file..." %} + + + {% include "components/results_container.html" with results_title="Analysis Results" %} +
+
+ -{% endblock %} - -{% block content %} - -
- - {% include "components/agent_header.html" with agent_title="Data Analyzer" agent_subtitle="Upload your data file and get AI-powered analysis with advanced insights" %} - - - {% include "components/quick_agents_panel.html" %} - - -
- -
-
-

- 📤 - Upload & Analyze -

-
-
-
- {% csrf_token %} - - -
- -
- -
Click to upload or drag and drop
-
Supports PDF, CSV, Excel files (max 10MB)
- -
-
- - -
- -
-
- -
- -
-
- -
- -
-
- -
- -
-
-
- - -
- {% if user.is_authenticated %} - {% if user.wallet_balance >= 5.00 %} - - {% else %} -
- Insufficient balance! You need 5.00 AED. -
- - đŸ’ŗ Top Up Wallet - - {% endif %} - {% else %} - - 🔐 Login to Continue - - {% endif %} -
-
-
-
- - -
-
-

- â„šī¸ - How It Works -

-
-
-
    -
  1. Upload your data file
  2. -
  3. Choose analysis type
  4. -
  5. Get AI-powered insights
  6. -
  7. Copy or download results
  8. -
- - - -
-
-
- - -
- - {% include "components/processing_status.html" %} - - - {% include "components/results_container.html" with results_title="Analysis Results" %} -
-
- - {% endblock %} \ No newline at end of file diff --git a/data_analyzer/urls.py b/data_analyzer/urls.py index a53eafb..2d1fd31 100644 --- a/data_analyzer/urls.py +++ b/data_analyzer/urls.py @@ -5,7 +5,6 @@ app_name = 'data_analyzer' urlpatterns = [ path('', views.data_analyzer_detail, name='detail'), - path('process/', views.DataAnalysisAgentProcessView.as_view(), name='process'), path('status//', views.data_analyzer_status, name='status'), path('result//', views.data_analyzer_result, name='result'), ] \ No newline at end of file diff --git a/data_analyzer/views.py b/data_analyzer/views.py index 2d563f3..aff1921 100644 --- a/data_analyzer/views.py +++ b/data_analyzer/views.py @@ -2,9 +2,6 @@ from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.contrib import messages from django.http import JsonResponse -from django.views.decorators.csrf import csrf_exempt -from django.utils.decorators import method_decorator -from django.views import View from agent_base.models import BaseAgent from .models import DataAnalysisAgentRequest, DataAnalysisAgentResponse from .processor import DataAnalysisAgentProcessor @@ -34,10 +31,17 @@ def data_analyzer_detail(request): if not request.user.has_sufficient_balance(agent.price): return JsonResponse({'error': 'Insufficient wallet balance'}, status=400) - # Validate file upload + # Validate PDF file upload data_file = files.get('file') if not data_file: - return JsonResponse({'error': 'Data file is required'}, status=400) + return JsonResponse({'error': 'PDF file is required'}, status=400) + + # Validate file type + if not data_file.name.lower().endswith('.pdf'): + return JsonResponse({'error': 'Only PDF files are supported'}, status=400) + + if data_file.content_type != 'application/pdf': + return JsonResponse({'error': 'Invalid file type. Only PDF files are allowed'}, status=400) # Create request object (no wallet deduction yet - only after successful processing) agent_request = DataAnalysisAgentRequest.objects.create( @@ -93,63 +97,6 @@ def data_analyzer_detail(request): return render(request, 'data_analyzer/detail.html', context) -@method_decorator(csrf_exempt, name='dispatch') -class DataAnalysisAgentProcessView(View): - """Process Data Analysis Agent requests""" - - def post(self, request): - if not request.user.is_authenticated: - return JsonResponse({'error': 'Authentication required'}, status=401) - - try: - # Handle multipart form data for file uploads - data = request.POST.dict() - files = request.FILES - - # Get agent - agent = BaseAgent.objects.get(slug='data-analyzer') - - # Check wallet balance - if not request.user.has_sufficient_balance(agent.price): - return JsonResponse({'error': 'Insufficient wallet balance'}, status=400) - - # Validate file upload - data_file = files.get('file') - if not data_file: - return JsonResponse({'error': 'PDF file is required'}, status=400) - - # Create request object (no wallet deduction yet - only after successful processing) - agent_request = DataAnalysisAgentRequest.objects.create( - user=request.user, - agent=agent, - cost=agent.price, - data_file=data_file, - analysis_type=data.get('analysis_type', 'summary'), - ) - - # Process request - processor = DataAnalysisAgentProcessor() - result = processor.process_request( - request_obj=agent_request, - user_id=request.user.id, - data_file_url=agent_request.data_file.url if agent_request.data_file else '', - analysis_type=data.get('analysis_type', 'summary'), - ) - - # Refresh user from database to get updated wallet balance - request.user.refresh_from_db() - - return JsonResponse({ - 'success': True, - 'request_id': str(agent_request.id), - 'message': 'Data Analysis Agent request processed successfully', - 'wallet_balance': float(request.user.wallet_balance) - }) - - except BaseAgent.DoesNotExist: - return JsonResponse({'error': 'Data Analysis Agent agent not found'}, status=404) - except Exception as e: - return JsonResponse({'error': str(e)}, status=500) @login_required