benkada commited on
Commit
794b7d6
·
verified ·
1 Parent(s): 1234eb6

Upload 2 files

Browse files
Files changed (2) hide show
  1. index.html +171 -0
  2. main.py +213 -0
index.html ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>AI-Powered Web App</title>
7
+ <style>
8
+ :root {
9
+ --primary-color: #4A90E2;
10
+ --secondary-color: #f4f6f8;
11
+ --text-color: #333;
12
+ --btn-color: #4A90E2;
13
+ --btn-hover: #357ABD;
14
+ --card-bg: #fff;
15
+ --card-shadow: rgba(0, 0, 0, 0.1);
16
+ --border-radius: 8px;
17
+ --transition: 0.3s;
18
+ --max-width: 900px;
19
+ }
20
+ * {
21
+ box-sizing: border-box;
22
+ }
23
+ body {
24
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
25
+ color: var(--text-color);
26
+ background: var(--secondary-color);
27
+ margin: 0;
28
+ padding: 20px;
29
+ display: flex;
30
+ justify-content: center;
31
+ }
32
+ .container {
33
+ width: 100%;
34
+ max-width: var(--max-width);
35
+ }
36
+ h1 {
37
+ text-align: center;
38
+ color: var(--primary-color);
39
+ margin-bottom: 40px;
40
+ }
41
+ .section {
42
+ background: var(--card-bg);
43
+ padding: 20px;
44
+ margin-bottom: 30px;
45
+ border-radius: var(--border-radius);
46
+ box-shadow: 0 2px 8px var(--card-shadow);
47
+ transition: transform var(--transition);
48
+ }
49
+ .section:hover {
50
+ transform: translateY(-3px);
51
+ }
52
+ h2 {
53
+ margin-top: 0;
54
+ color: var(--primary-color);
55
+ border-bottom: 2px solid var(--secondary-color);
56
+ padding-bottom: 5px;
57
+ }
58
+ label {
59
+ display: block;
60
+ margin-top: 15px;
61
+ font-weight: bold;
62
+ }
63
+ input[type="file"], input[type="text"], button, textarea {
64
+ width: 100%;
65
+ padding: 10px;
66
+ margin-top: 8px;
67
+ border: 1px solid #ccc;
68
+ border-radius: var(--border-radius);
69
+ font-size: 1rem;
70
+ }
71
+ button {
72
+ background: var(--btn-color);
73
+ color: #fff;
74
+ border: none;
75
+ margin-top: 20px;
76
+ padding: 12px;
77
+ font-size: 1rem;
78
+ border-radius: var(--border-radius);
79
+ cursor: pointer;
80
+ transition: background var(--transition);
81
+ }
82
+ button:hover {
83
+ background: var(--btn-hover);
84
+ }
85
+ .results {
86
+ margin-top: 20px;
87
+ padding: 15px;
88
+ background: var(--secondary-color);
89
+ border-radius: var(--border-radius);
90
+ border: 1px solid #ddd;
91
+ min-height: 60px;
92
+ }
93
+ @media (min-width: 768px) {
94
+ .grid {
95
+ display: flex;
96
+ gap: 20px;
97
+ }
98
+ .grid > div {
99
+ flex: 1;
100
+ }
101
+ }
102
+ </style>
103
+ </head>
104
+ <body>
105
+ <div class="container">
106
+ <h1>AI-Powered Web Application</h1>
107
+
108
+ <!-- Function 1 & 2 in grid on larger screens -->
109
+ <div class="grid">
110
+ <!-- Function 1: Document & Image Analysis -->
111
+ <div class="section" id="analysis-section">
112
+ <h2>1. Document & Image Analysis</h2>
113
+ <!-- Text Summarization -->
114
+ <label for="doc-input-summarize">Upload Document (PDF, DOCX, PPTX, XLSX):</label>
115
+ <input type="file" id="doc-input-summarize" accept=".pdf,.docx,.pptx,.xlsx" />
116
+ <button id="summarize-btn">Summarize Document</button>
117
+ <div class="results" id="summary-result">Your summary will appear here.</div>
118
+
119
+ <!-- Image Captioning -->
120
+ <label for="img-input-caption">Upload Image (JPG, PNG):</label>
121
+ <input type="file" id="img-input-caption" accept="image/*" />
122
+ <button id="caption-btn">Generate Caption</button>
123
+ <div class="results" id="caption-result">Image caption will appear here.</div>
124
+ </div>
125
+
126
+ <!-- Function 2: Intelligent Question Answering -->
127
+ <div class="section" id="qa-section">
128
+ <h2>2. Intelligent Question Answering</h2>
129
+ <label for="file-input-qa">Upload Document or Image:</label>
130
+ <input type="file" id="file-input-qa" accept=".pdf,.docx,.pptx,.xlsx,image/*" />
131
+ <label for="question-input">Enter Your Question:</label>
132
+ <input type="text" id="question-input" placeholder="Type your question here..." />
133
+ <button id="qa-btn">Ask Question</button>
134
+ <div class="results" id="qa-result">Answer will appear here.</div>
135
+ </div>
136
+ </div>
137
+
138
+ <script>
139
+ async function sendData(url, fileInput, extraData, resultContainer) {
140
+ const file = fileInput.files[0];
141
+ if (!file) {
142
+ resultContainer.textContent = 'Please select a file.';
143
+ return;
144
+ }
145
+ const formData = new FormData();
146
+ formData.append('file', file);
147
+ if (extraData) Object.keys(extraData).forEach(key => formData.append(key, extraData[key]));
148
+ resultContainer.textContent = 'Processing...';
149
+ try {
150
+ const res = await fetch(url, { method: 'POST', body: formData });
151
+ const data = await res.json();
152
+ resultContainer.textContent = data.result || JSON.stringify(data);
153
+ } catch (err) {
154
+ resultContainer.textContent = 'Error: ' + err.message;
155
+ }
156
+ }
157
+ document.getElementById('summarize-btn').addEventListener('click', () => {
158
+ sendData('/api/summarize', document.getElementById('doc-input-summarize'), null, document.getElementById('summary-result'));
159
+ });
160
+ document.getElementById('caption-btn').addEventListener('click', () => {
161
+ sendData('/api/caption', document.getElementById('img-input-caption'), null, document.getElementById('caption-result'));
162
+ });
163
+ document.getElementById('qa-btn').addEventListener('click', () => {
164
+ const q = document.getElementById('question-input').value.trim();
165
+ if (!q) { document.getElementById('qa-result').textContent = 'Please enter a question.'; return; }
166
+ sendData('/api/qa', document.getElementById('file-input-qa'), { question: q }, document.getElementById('qa-result'));
167
+ });
168
+ </script>
169
+ </div>
170
+ </body>
171
+ </html>
main.py ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, Form, HTTPException
2
+ from fastapi.responses import JSONResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from pydantic import BaseModel
5
+ from typing import Optional
6
+ import os
7
+ import tempfile
8
+ from transformers import pipeline
9
+ import torch
10
+ from PIL import Image
11
+ import pytesseract
12
+ from langchain.chains import LLMChain
13
+ from langchain.prompts import PromptTemplate
14
+ from langchain_community.llms import HuggingFaceHub
15
+
16
+ # Initialize FastAPI app
17
+ app = FastAPI(
18
+ title="AI-Powered Web Application API",
19
+ description="API for document analysis, image captioning, and question answering",
20
+ version="1.0.0"
21
+ )
22
+
23
+ # CORS configuration
24
+ app.add_middleware(
25
+ CORSMiddleware,
26
+ allow_origins=["*"],
27
+ allow_credentials=True,
28
+ allow_methods=["*"],
29
+ allow_headers=["*"],
30
+ )
31
+
32
+ # Initialize AI models (lazy loading)
33
+ summarizer = None
34
+ image_captioner = None
35
+ qa_chain = None
36
+
37
+ class SummaryRequest(BaseModel):
38
+ file: UploadFile = File(...)
39
+
40
+ class CaptionRequest(BaseModel):
41
+ file: UploadFile = File(...)
42
+
43
+ class QARequest(BaseModel):
44
+ file: UploadFile = File(...)
45
+ question: str = Form(...)
46
+
47
+ def initialize_models():
48
+ """Initialize AI models with optimized prompts"""
49
+ global summarizer, image_captioner, qa_chain
50
+
51
+ # Document summarization model
52
+ if summarizer is None:
53
+ summarizer = pipeline(
54
+ "summarization",
55
+ model="facebook/bart-large-cnn",
56
+ device=0 if torch.cuda.is_available() else -1
57
+ )
58
+
59
+ # Image captioning model
60
+ if image_captioner is None:
61
+ image_captioner = pipeline(
62
+ "image-to-text",
63
+ model="nlpconnect/vit-gpt2-image-captioning",
64
+ device=0 if torch.cuda.is_available() else -1
65
+ )
66
+
67
+ # Question answering chain
68
+ if qa_chain is None:
69
+ llm = HuggingFaceHub(
70
+ repo_id="google/flan-t5-large",
71
+ model_kwargs={"temperature": 0.1, "max_length": 512}
72
+ )
73
+
74
+ qa_prompt = PromptTemplate(
75
+ input_variables=["document", "question"],
76
+ template="""
77
+ Using the provided document, answer the following question precisely.
78
+ If the answer cannot be determined from the document, respond with
79
+ 'The answer cannot be determined from the provided document.'
80
+
81
+ Question: {question}
82
+
83
+ Rules:
84
+ 1. Provide a concise answer (1-3 sentences maximum)
85
+ 2. When possible, reference the specific section of the document that supports your answer
86
+ 3. Maintain numerical precision when answering quantitative questions
87
+ 4. For comparison questions, highlight both items being compared
88
+
89
+ Document: {document}
90
+ """
91
+ )
92
+ qa_chain = LLMChain(llm=llm, prompt=qa_prompt)
93
+
94
+ def extract_text_from_file(file: UploadFile) -> str:
95
+ """Extract text from various file formats"""
96
+ # Create a temporary file
97
+ with tempfile.NamedTemporaryFile(delete=False) as temp_file:
98
+ temp_file.write(file.file.read())
99
+ temp_path = temp_file.name
100
+
101
+ try:
102
+ # PDF, DOCX, PPTX, XLSX would need appropriate libraries here
103
+ # For simplicity, we'll just read text files in this example
104
+ if file.filename.endswith('.txt'):
105
+ with open(temp_path, 'r', encoding='utf-8') as f:
106
+ return f.read()
107
+ else:
108
+ # In a real implementation, use libraries like PyPDF2, python-docx, etc.
109
+ raise HTTPException(
110
+ status_code=415,
111
+ detail="File type not supported in this example implementation"
112
+ )
113
+ finally:
114
+ os.unlink(temp_path)
115
+
116
+ @app.post("/api/summarize")
117
+ async def summarize_document(file: UploadFile = File(...)):
118
+ """Summarize a document"""
119
+ initialize_models()
120
+
121
+ try:
122
+ # Extract text from the document
123
+ document_text = extract_text_from_file(file)
124
+
125
+ # Generate summary with optimized prompt
126
+ summary = summarizer(
127
+ document_text,
128
+ max_length=150,
129
+ min_length=30,
130
+ do_sample=False,
131
+ truncation=True
132
+ )
133
+
134
+ return JSONResponse(
135
+ content={"status": "success", "result": summary[0]['summary_text']},
136
+ status_code=200
137
+ )
138
+ except Exception as e:
139
+ raise HTTPException(
140
+ status_code=500,
141
+ detail=f"Error processing document: {str(e)}"
142
+ )
143
+
144
+ @app.post("/api/caption")
145
+ async def generate_image_caption(file: UploadFile = File(...)):
146
+ """Generate caption for an image"""
147
+ initialize_models()
148
+
149
+ try:
150
+ # Save the uploaded image temporarily
151
+ with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as temp_file:
152
+ temp_file.write(file.file.read())
153
+ temp_path = temp_file.name
154
+
155
+ # Open the image
156
+ image = Image.open(temp_path)
157
+
158
+ # Generate caption with optimized prompt
159
+ caption = image_captioner(
160
+ image,
161
+ generate_kwargs={
162
+ "max_length": 50,
163
+ "num_beams": 4,
164
+ "early_stopping": True
165
+ }
166
+ )
167
+
168
+ return JSONResponse(
169
+ content={"status": "success", "result": caption[0]['generated_text']},
170
+ status_code=200
171
+ )
172
+ except Exception as e:
173
+ raise HTTPException(
174
+ status_code=500,
175
+ detail=f"Error processing image: {str(e)}"
176
+ )
177
+ finally:
178
+ if 'temp_path' in locals() and os.path.exists(temp_path):
179
+ os.unlink(temp_path)
180
+
181
+ @app.post("/api/qa")
182
+ async def answer_question(
183
+ file: UploadFile = File(...),
184
+ question: str = Form(...)
185
+ ):
186
+ """Answer questions based on document content"""
187
+ initialize_models()
188
+
189
+ try:
190
+ # Extract text from the document
191
+ document_text = extract_text_from_file(file)
192
+
193
+ # Get answer using the QA chain
194
+ answer = qa_chain.run(document=document_text, question=question)
195
+
196
+ return JSONResponse(
197
+ content={"status": "success", "result": answer},
198
+ status_code=200
199
+ )
200
+ except Exception as e:
201
+ raise HTTPException(
202
+ status_code=500,
203
+ detail=f"Error processing question: {str(e)}"
204
+ )
205
+
206
+ @app.get("/")
207
+ async def health_check():
208
+ """Health check endpoint"""
209
+ return {"status": "healthy", "version": "1.0.0"}
210
+
211
+ if __name__ == "__main__":
212
+ import uvicorn
213
+ uvicorn.run(app, host="0.0.0.0", port=8000)