Spaces:
Running
Running
Upload 33 files
Browse files- backend/__pycache__/main.cpython-312.pyc +0 -0
- backend/main.py +116 -4
- backend/modules/__pycache__/data_visualization.cpython-312.pyc +0 -0
- backend/modules/__pycache__/question_answering.cpython-312.pyc +0 -0
- backend/modules/__pycache__/translator.cpython-312.pyc +0 -0
- backend/modules/data_visualization.py +49 -0
- backend/modules/question_answering.py +32 -0
- backend/modules/translator.py +35 -0
- backend/requirements.txt +4 -1
backend/__pycache__/main.cpython-312.pyc
CHANGED
Binary files a/backend/__pycache__/main.cpython-312.pyc and b/backend/__pycache__/main.cpython-312.pyc differ
|
|
backend/main.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
from fastapi import FastAPI, File, UploadFile, Form, HTTPException
|
2 |
from fastapi.staticfiles import StaticFiles
|
3 |
-
from fastapi.responses import JSONResponse
|
4 |
import uvicorn
|
5 |
import os
|
6 |
from typing import List, Optional
|
@@ -11,6 +11,9 @@ import uuid
|
|
11 |
# Import AI functionality modules
|
12 |
from modules.document_processor import process_document
|
13 |
from modules.image_processor import process_image
|
|
|
|
|
|
|
14 |
|
15 |
# Create FastAPI app
|
16 |
app = FastAPI(title="AI Document Analysis API")
|
@@ -19,12 +22,13 @@ app = FastAPI(title="AI Document Analysis API")
|
|
19 |
UPLOAD_DIR = Path("uploads")
|
20 |
UPLOAD_DIR.mkdir(exist_ok=True)
|
21 |
|
22 |
-
# Mount static files
|
23 |
app.mount("/static", StaticFiles(directory="frontend"), name="static")
|
24 |
|
|
|
25 |
@app.get("/")
|
26 |
-
def read_root():
|
27 |
-
return
|
28 |
|
29 |
@app.post("/api/analyze-document")
|
30 |
async def analyze_document(
|
@@ -104,6 +108,114 @@ async def analyze_image(
|
|
104 |
os.remove(file_path)
|
105 |
raise HTTPException(status_code=500, detail=str(e))
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
# Add health check endpoint
|
108 |
@app.get("/health")
|
109 |
def health_check():
|
|
|
1 |
from fastapi import FastAPI, File, UploadFile, Form, HTTPException
|
2 |
from fastapi.staticfiles import StaticFiles
|
3 |
+
from fastapi.responses import JSONResponse, FileResponse
|
4 |
import uvicorn
|
5 |
import os
|
6 |
from typing import List, Optional
|
|
|
11 |
# Import AI functionality modules
|
12 |
from modules.document_processor import process_document
|
13 |
from modules.image_processor import process_image
|
14 |
+
from modules.question_answering import process_question
|
15 |
+
from modules.data_visualization import generate_visualization
|
16 |
+
from modules.translator import translate_document
|
17 |
|
18 |
# Create FastAPI app
|
19 |
app = FastAPI(title="AI Document Analysis API")
|
|
|
22 |
UPLOAD_DIR = Path("uploads")
|
23 |
UPLOAD_DIR.mkdir(exist_ok=True)
|
24 |
|
25 |
+
# Mount static files
|
26 |
app.mount("/static", StaticFiles(directory="frontend"), name="static")
|
27 |
|
28 |
+
# Serve index.html at root
|
29 |
@app.get("/")
|
30 |
+
async def read_root():
|
31 |
+
return FileResponse("frontend/index.html")
|
32 |
|
33 |
@app.post("/api/analyze-document")
|
34 |
async def analyze_document(
|
|
|
108 |
os.remove(file_path)
|
109 |
raise HTTPException(status_code=500, detail=str(e))
|
110 |
|
111 |
+
@app.post("/api/question-answering")
|
112 |
+
async def question_answering(
|
113 |
+
file: UploadFile = File(...),
|
114 |
+
question: str = Form(...)
|
115 |
+
):
|
116 |
+
# Validate file type
|
117 |
+
allowed_extensions = [".pdf", ".docx", ".pptx", ".xlsx", ".xls", ".jpg", ".jpeg", ".png"]
|
118 |
+
file_ext = os.path.splitext(file.filename)[1].lower()
|
119 |
+
|
120 |
+
if file_ext not in allowed_extensions:
|
121 |
+
raise HTTPException(status_code=400, detail=f"File type not supported. Allowed types: {', '.join(allowed_extensions)}")
|
122 |
+
|
123 |
+
# Create unique filename
|
124 |
+
unique_filename = f"{uuid.uuid4()}{file_ext}"
|
125 |
+
file_path = UPLOAD_DIR / unique_filename
|
126 |
+
|
127 |
+
# Save uploaded file
|
128 |
+
with open(file_path, "wb") as buffer:
|
129 |
+
shutil.copyfileobj(file.file, buffer)
|
130 |
+
|
131 |
+
try:
|
132 |
+
# Process question
|
133 |
+
result = process_question(str(file_path), question)
|
134 |
+
|
135 |
+
# Return results
|
136 |
+
return {
|
137 |
+
"filename": file.filename,
|
138 |
+
"question": question,
|
139 |
+
"answer": result
|
140 |
+
}
|
141 |
+
except Exception as e:
|
142 |
+
# Clean up file on error
|
143 |
+
if file_path.exists():
|
144 |
+
os.remove(file_path)
|
145 |
+
raise HTTPException(status_code=500, detail=str(e))
|
146 |
+
|
147 |
+
@app.post("/api/visualize-data")
|
148 |
+
async def visualize_data(
|
149 |
+
file: UploadFile = File(...),
|
150 |
+
request: str = Form(...)
|
151 |
+
):
|
152 |
+
# Validate file type
|
153 |
+
allowed_extensions = [".xlsx", ".xls"]
|
154 |
+
file_ext = os.path.splitext(file.filename)[1].lower()
|
155 |
+
|
156 |
+
if file_ext not in allowed_extensions:
|
157 |
+
raise HTTPException(status_code=400, detail=f"File type not supported. Allowed types: {', '.join(allowed_extensions)}")
|
158 |
+
|
159 |
+
# Create unique filename
|
160 |
+
unique_filename = f"{uuid.uuid4()}{file_ext}"
|
161 |
+
file_path = UPLOAD_DIR / unique_filename
|
162 |
+
|
163 |
+
# Save uploaded file
|
164 |
+
with open(file_path, "wb") as buffer:
|
165 |
+
shutil.copyfileobj(file.file, buffer)
|
166 |
+
|
167 |
+
try:
|
168 |
+
# Generate visualization
|
169 |
+
result = generate_visualization(str(file_path), request)
|
170 |
+
|
171 |
+
# Return results
|
172 |
+
return {
|
173 |
+
"filename": file.filename,
|
174 |
+
"request": request,
|
175 |
+
"visualization": result
|
176 |
+
}
|
177 |
+
except Exception as e:
|
178 |
+
# Clean up file on error
|
179 |
+
if file_path.exists():
|
180 |
+
os.remove(file_path)
|
181 |
+
raise HTTPException(status_code=500, detail=str(e))
|
182 |
+
|
183 |
+
@app.post("/api/translate-document")
|
184 |
+
async def translate_document_endpoint(
|
185 |
+
file: UploadFile = File(...),
|
186 |
+
target_language: str = Form(...)
|
187 |
+
):
|
188 |
+
# Validate file type
|
189 |
+
allowed_extensions = [".pdf", ".docx", ".pptx", ".xlsx", ".xls"]
|
190 |
+
file_ext = os.path.splitext(file.filename)[1].lower()
|
191 |
+
|
192 |
+
if file_ext not in allowed_extensions:
|
193 |
+
raise HTTPException(status_code=400, detail=f"File type not supported. Allowed types: {', '.join(allowed_extensions)}")
|
194 |
+
|
195 |
+
# Create unique filename
|
196 |
+
unique_filename = f"{uuid.uuid4()}{file_ext}"
|
197 |
+
file_path = UPLOAD_DIR / unique_filename
|
198 |
+
|
199 |
+
# Save uploaded file
|
200 |
+
with open(file_path, "wb") as buffer:
|
201 |
+
shutil.copyfileobj(file.file, buffer)
|
202 |
+
|
203 |
+
try:
|
204 |
+
# Translate document
|
205 |
+
result = translate_document(str(file_path), target_language)
|
206 |
+
|
207 |
+
# Return results
|
208 |
+
return {
|
209 |
+
"filename": file.filename,
|
210 |
+
"target_language": target_language,
|
211 |
+
"translation": result
|
212 |
+
}
|
213 |
+
except Exception as e:
|
214 |
+
# Clean up file on error
|
215 |
+
if file_path.exists():
|
216 |
+
os.remove(file_path)
|
217 |
+
raise HTTPException(status_code=500, detail=str(e))
|
218 |
+
|
219 |
# Add health check endpoint
|
220 |
@app.get("/health")
|
221 |
def health_check():
|
backend/modules/__pycache__/data_visualization.cpython-312.pyc
ADDED
Binary file (1.77 kB). View file
|
|
backend/modules/__pycache__/question_answering.cpython-312.pyc
ADDED
Binary file (1.61 kB). View file
|
|
backend/modules/__pycache__/translator.cpython-312.pyc
ADDED
Binary file (1.7 kB). View file
|
|
backend/modules/data_visualization.py
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from pathlib import Path
|
3 |
+
import json
|
4 |
+
|
5 |
+
# Configure logging
|
6 |
+
logging.basicConfig(level=logging.INFO)
|
7 |
+
logger = logging.getLogger(__name__)
|
8 |
+
|
9 |
+
def generate_visualization(file_path: str, request: str) -> dict:
|
10 |
+
"""
|
11 |
+
Generate visualization code for Excel data using Hugging Face models.
|
12 |
+
|
13 |
+
Args:
|
14 |
+
file_path (str): Path to the Excel file
|
15 |
+
request (str): Natural language visualization request
|
16 |
+
|
17 |
+
Returns:
|
18 |
+
dict: Generated code and visualization description
|
19 |
+
"""
|
20 |
+
logger.info(f"Generating visualization for {file_path}: {request}")
|
21 |
+
|
22 |
+
# Mock implementation - would use actual Hugging Face models in production
|
23 |
+
# Would actually read Excel data and generate real matplotlib/seaborn code
|
24 |
+
|
25 |
+
# Example mock visualization code
|
26 |
+
mock_code = """
|
27 |
+
import pandas as pd
|
28 |
+
import matplotlib.pyplot as plt
|
29 |
+
import seaborn as sns
|
30 |
+
|
31 |
+
# Read the Excel file
|
32 |
+
df = pd.read_excel('data.xlsx')
|
33 |
+
|
34 |
+
# Create the visualization
|
35 |
+
plt.figure(figsize=(10, 6))
|
36 |
+
sns.barplot(data=df, x='Category', y='Values')
|
37 |
+
plt.title('Data Visualization')
|
38 |
+
plt.xlabel('Categories')
|
39 |
+
plt.ylabel('Values')
|
40 |
+
plt.xticks(rotation=45)
|
41 |
+
plt.tight_layout()
|
42 |
+
plt.show()
|
43 |
+
"""
|
44 |
+
|
45 |
+
return {
|
46 |
+
"code": mock_code,
|
47 |
+
"description": "This code generates a bar plot showing the relationship between categories and their corresponding values from your Excel data.",
|
48 |
+
"note": "This is a mock response. In production, the code would be generated based on actual Excel data analysis and user requirements."
|
49 |
+
}
|
backend/modules/question_answering.py
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from pathlib import Path
|
3 |
+
|
4 |
+
# Configure logging
|
5 |
+
logging.basicConfig(level=logging.INFO)
|
6 |
+
logger = logging.getLogger(__name__)
|
7 |
+
|
8 |
+
def process_question(file_path: str, question: str) -> str:
|
9 |
+
"""
|
10 |
+
Process a question about a document or image using Hugging Face models.
|
11 |
+
|
12 |
+
Args:
|
13 |
+
file_path (str): Path to the document or image
|
14 |
+
question (str): User's question
|
15 |
+
|
16 |
+
Returns:
|
17 |
+
str: Answer to the question
|
18 |
+
"""
|
19 |
+
logger.info(f"Processing question for {file_path}: {question}")
|
20 |
+
|
21 |
+
# Mock implementation - would use actual Hugging Face models in production
|
22 |
+
# Example models: deepseek-ai/DeepSeek-V2-Chat or meta-llama/Llama-2-70b-chat-hf
|
23 |
+
|
24 |
+
file_ext = Path(file_path).suffix.lower()
|
25 |
+
|
26 |
+
# Generate mock response based on file type
|
27 |
+
if file_ext in ['.pdf', '.docx', '.pptx', '.xlsx', '.xls']:
|
28 |
+
return f"Based on the document content, the answer to '{question}' is: This is a mock response that would be generated by an actual language model in production."
|
29 |
+
elif file_ext in ['.jpg', '.jpeg', '.png']:
|
30 |
+
return f"Looking at the image, in response to '{question}': This is a mock response that would be generated by a vision-language model in production."
|
31 |
+
else:
|
32 |
+
return "Unsupported file type for question answering."
|
backend/modules/translator.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from pathlib import Path
|
3 |
+
|
4 |
+
# Configure logging
|
5 |
+
logging.basicConfig(level=logging.INFO)
|
6 |
+
logger = logging.getLogger(__name__)
|
7 |
+
|
8 |
+
def translate_document(file_path: str, target_language: str) -> str:
|
9 |
+
"""
|
10 |
+
Translate document content using Hugging Face models.
|
11 |
+
|
12 |
+
Args:
|
13 |
+
file_path (str): Path to the document
|
14 |
+
target_language (str): Target language code (e.g., 'fr', 'es', 'de')
|
15 |
+
|
16 |
+
Returns:
|
17 |
+
str: Translated content
|
18 |
+
"""
|
19 |
+
logger.info(f"Translating document {file_path} to {target_language}")
|
20 |
+
|
21 |
+
# Mock implementation - would use actual Hugging Face models in production
|
22 |
+
|
23 |
+
file_ext = Path(file_path).suffix.lower()
|
24 |
+
|
25 |
+
# Mock translation based on file type
|
26 |
+
if file_ext == '.pdf':
|
27 |
+
return f"This is a mock translation of a PDF document to {target_language}. In production, this would be actual translated content."
|
28 |
+
elif file_ext == '.docx':
|
29 |
+
return f"This is a mock translation of a Word document to {target_language}. In production, this would be actual translated content."
|
30 |
+
elif file_ext == '.pptx':
|
31 |
+
return f"This is a mock translation of a PowerPoint presentation to {target_language}. In production, this would be actual translated content."
|
32 |
+
elif file_ext in ['.xlsx', '.xls']:
|
33 |
+
return f"This is a mock translation of Excel content to {target_language}. In production, this would be actual translated content."
|
34 |
+
else:
|
35 |
+
return "Unsupported file type for translation."
|
backend/requirements.txt
CHANGED
@@ -4,4 +4,7 @@ python-multipart==0.0.6
|
|
4 |
aiofiles==23.2.1
|
5 |
Pillow==10.0.1
|
6 |
pydantic==2.4.2
|
7 |
-
python-dotenv==1.0.0
|
|
|
|
|
|
|
|
4 |
aiofiles==23.2.1
|
5 |
Pillow==10.0.1
|
6 |
pydantic==2.4.2
|
7 |
+
python-dotenv==1.0.0
|
8 |
+
pandas==2.1.1
|
9 |
+
matplotlib==3.8.0
|
10 |
+
seaborn==0.13.0
|