Arivara commited on
Commit
bbf5dc5
Β·
verified Β·
1 Parent(s): 6776c39

Upload 3 files

Browse files
Files changed (3) hide show
  1. RAG_AGENT.py +82 -0
  2. gradio_app.py +174 -0
  3. requirements.txt +8 -0
RAG_AGENT.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+ from PIL import Image
3
+ import pdfplumber
4
+ import re
5
+ import os
6
+ from dotenv import load_dotenv
7
+ from google import genai
8
+ from google.genai import types
9
+
10
+ # Load environment variables
11
+ load_dotenv()
12
+
13
+ # Get API key and model name from environment variables
14
+ GEMINI_API_KEY = os.getenv('GEMINI_API_KEY')
15
+ GEMINI_MODEL_NAME = os.getenv('GEMINI_MODEL_NAME', 'gemini-2.5-flash')
16
+
17
+ # Configure Gemini
18
+ if GEMINI_API_KEY:
19
+ client = genai.Client(api_key=GEMINI_API_KEY)
20
+ else:
21
+ client = None
22
+
23
+ # Constants
24
+ PDF_TEXT_LIMIT = 10000 # Limit PDF text to 10k characters
25
+
26
+ # Initialize Gemini model (you'll need to set up your API key)
27
+ # from google.generativeai import GenerativeModel
28
+ # gemini_model = GenerativeModel('gemini-pro-vision')
29
+
30
+ def extract_clean_pdf_text(pdf_path: str) -> str:
31
+ """
32
+ Extracts and cleans text from a PDF file.
33
+ Args:
34
+ pdf_path (str): Path to the PDF file.
35
+ Returns:
36
+ str: Cleaned text extracted from the PDF.
37
+ """
38
+ text = []
39
+ with pdfplumber.open(pdf_path) as pdf:
40
+ for page in pdf.pages:
41
+ page_text = page.extract_text() or ""
42
+ text.append(page_text)
43
+ full_text = "\n".join(text)
44
+ # Clean up: remove excessive whitespace and newlines
45
+ cleaned_text = re.sub(r'\s+', ' ', full_text).strip()
46
+ return cleaned_text
47
+
48
+ def gemini_explain_file(file, question: Optional[str] = None) -> str:
49
+ if not file: return "⚠️ No file uploaded."
50
+ if not client:
51
+ return "⚠️ Gemini API not configured. Please set GEMINI_API_KEY environment variable."
52
+
53
+ try:
54
+ file_path = file if isinstance(file, str) else file.name
55
+
56
+ if file_path.lower().endswith((".png", ".jpg", ".jpeg")):
57
+ img = Image.open(file_path)
58
+ prompt = f"Explain the science in this image. If there's a specific question, address it: {question}" if question else "Explain the science in this image."
59
+ response = client.models.generate_content(
60
+ model=GEMINI_MODEL_NAME,
61
+ contents=[prompt, img],
62
+ config=types.GenerateContentConfig(
63
+ thinking_config=types.ThinkingConfig(thinking_budget=0)
64
+ )
65
+ )
66
+ return response.text or "No response generated"
67
+ elif file_path.lower().endswith(".pdf"):
68
+ with pdfplumber.open(file_path) as pdf:
69
+ text = "\n".join(page.extract_text() or "" for page in pdf.pages)
70
+ prompt = f"Explain the science in this PDF, focusing on this question: {question}\n\nPDF Content:\n{text[:PDF_TEXT_LIMIT]}" if question else f"Summarize and explain the science in this PDF:\n\n{text[:PDF_TEXT_LIMIT]}"
71
+ response = client.models.generate_content(
72
+ model=GEMINI_MODEL_NAME,
73
+ contents=prompt,
74
+ config=types.GenerateContentConfig(
75
+ thinking_config=types.ThinkingConfig(thinking_budget=0)
76
+ )
77
+ )
78
+ return response.text or "No response generated"
79
+ else:
80
+ return "⚠️ Unsupported file type."
81
+ except Exception as e:
82
+ return f"❌ Gemini Error: {e}"
gradio_app.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from RAG_AGENT import gemini_explain_file, extract_clean_pdf_text
3
+ import os
4
+
5
+ # Custom CSS for minimalist design and better alignment
6
+ css = """
7
+ .gradio-container {
8
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
9
+ max-width: 800px !important;
10
+ margin: 0 auto !important;
11
+ }
12
+
13
+ .main-header {
14
+ text-align: center;
15
+ margin-bottom: 2rem;
16
+ color: #1a1a1a;
17
+ }
18
+
19
+ .main-header h1 {
20
+ font-size: 2.5rem;
21
+ font-weight: 700;
22
+ margin-bottom: 0.5rem;
23
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
24
+ -webkit-background-clip: text;
25
+ -webkit-text-fill-color: transparent;
26
+ background-clip: text;
27
+ }
28
+
29
+ .main-header p {
30
+ font-size: 1.1rem;
31
+ color: #666;
32
+ margin: 0;
33
+ }
34
+
35
+ .upload-area {
36
+ border: 2px dashed #e0e0e0 !important;
37
+ border-radius: 12px !important;
38
+ background: #fafafa !important;
39
+ transition: all 0.3s ease;
40
+ }
41
+
42
+ .upload-area:hover {
43
+ border-color: #667eea !important;
44
+ background: #f8f9ff !important;
45
+ }
46
+
47
+ .btn-primary {
48
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
49
+ border: none !important;
50
+ border-radius: 8px !important;
51
+ padding: 12px 24px !important;
52
+ font-weight: 600 !important;
53
+ transition: all 0.3s ease !important;
54
+ }
55
+
56
+ .btn-primary:hover {
57
+ transform: translateY(-2px);
58
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
59
+ }
60
+
61
+ .output-box {
62
+ border-radius: 12px !important;
63
+ border: 1px solid #e0e0e0 !important;
64
+ background: #fafafa !important;
65
+ padding: 1.5rem !important;
66
+ margin-top: 1rem !important;
67
+ min-height: 200px;
68
+ font-size: 1.1rem;
69
+ }
70
+
71
+ .footer {
72
+ text-align: center;
73
+ margin-top: 2rem;
74
+ color: #999;
75
+ font-size: 0.9rem;
76
+ }
77
+ """
78
+
79
+ def analyze_file(file, question, analysis_type):
80
+ """Main function to handle file analysis"""
81
+ if not file:
82
+ return "⚠️ Please upload a file first."
83
+
84
+ if analysis_type == "Extract PDF Text":
85
+ if not file.name.lower().endswith('.pdf'):
86
+ return "⚠️ This option only works with PDF files."
87
+ try:
88
+ text = extract_clean_pdf_text(file.name)
89
+ return f"πŸ“„ **Extracted Text:**\n\n{text}"
90
+ except Exception as e:
91
+ return f"❌ Error extracting text: {e}"
92
+
93
+ elif analysis_type == "AI Analysis":
94
+ if not os.getenv('GEMINI_API_KEY'):
95
+ return "⚠️ Gemini API key not configured. Please set GEMINI_API_KEY environment variable."
96
+
97
+ result = gemini_explain_file(file, question)
98
+ return result
99
+
100
+ else:
101
+ return "⚠️ Please select an analysis type."
102
+
103
+ # Create the Gradio interface
104
+ with gr.Blocks(css=css, title="Science File Analyzer", theme=gr.themes.Soft()) as demo:
105
+ gr.HTML("""
106
+ <div class="main-header">
107
+ <h1>Science File Analyzer</h1>
108
+ <p>Upload scientific documents and images for AI-powered analysis</p>
109
+ </div>
110
+ """)
111
+
112
+ with gr.Row():
113
+ with gr.Column(scale=1):
114
+ # File upload
115
+ file_input = gr.File(
116
+ label="πŸ“ Upload File",
117
+ file_types=[".pdf", ".png", ".jpg", ".jpeg"],
118
+ file_count="single",
119
+ elem_classes=["upload-area"]
120
+ )
121
+
122
+ # Analysis type selection
123
+ analysis_type = gr.Radio(
124
+ choices=["AI Analysis", "Extract PDF Text"],
125
+ value="AI Analysis",
126
+ label="πŸ” Analysis Type",
127
+ info="Choose how to process your file"
128
+ )
129
+
130
+ # Question input (optional)
131
+ question_input = gr.Textbox(
132
+ label="❓ Optional Question",
133
+ placeholder="Ask a specific question about the content...",
134
+ lines=2,
135
+ info="Leave empty for general analysis"
136
+ )
137
+
138
+ # Analyze button
139
+ analyze_btn = gr.Button(
140
+ "πŸš€ Analyze File",
141
+ variant="primary",
142
+ size="lg"
143
+ )
144
+
145
+ with gr.Column(scale=1):
146
+ # Output area (separate component)
147
+ output_box = gr.Markdown(
148
+ label="πŸ“Š Analysis Results",
149
+ value="Upload a file and click 'Analyze File' to get started.",
150
+ elem_classes=["output-box"]
151
+ )
152
+
153
+ # Footer
154
+ gr.HTML("""
155
+ <div class="footer">
156
+ <p>Powered by Google Gemini AI β€’ Built with Gradio</p>
157
+ </div>
158
+ """)
159
+
160
+ # Event handlers
161
+ analyze_btn.click(
162
+ fn=analyze_file,
163
+ inputs=[file_input, question_input, analysis_type],
164
+ outputs=output_box
165
+ )
166
+
167
+ # Auto-analyze when file is uploaded
168
+ file_input.change(
169
+ fn=lambda: "File uploaded! Click 'Analyze File' to process.",
170
+ outputs=output_box
171
+ )
172
+
173
+ if __name__ == "__main__":
174
+ demo.launch(show_error=True)
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ phidata
2
+ openai
3
+ gemini-ai
4
+ pdfplumber
5
+ Pillow
6
+ python-dotenv
7
+ google-genai
8
+ gradio>=3.50.2