Ali Abdullah commited on
Commit
0812f0d
·
verified ·
1 Parent(s): 4adcefb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -109
app.py CHANGED
@@ -2,20 +2,27 @@ import gradio as gr
2
  import requests
3
  import mimetypes
4
  import os
 
 
5
  import re
6
 
7
- # === Fix surrogate character issue ===
8
  def sanitize(text):
9
  if isinstance(text, str):
10
  text = re.sub(r'[\uD800-\uDFFF]', '', text)
11
  return text.encode("utf-8", "ignore").decode("utf-8")
12
  return text
13
 
14
- # API endpoints (your FastAPI runs in main.py separately)
15
- FILE_API_URL = "/chat-with-file"
16
- URL_API_URL = "/chat-with-url"
17
- IMAGE_API_URL = "/extract-text-from-image"
18
- AUDIO_API_URL = "/transcribe-audio"
 
 
 
 
 
 
19
 
20
  chat_sessions = {"file": [], "url": []}
21
 
@@ -24,137 +31,86 @@ def format_chat(history):
24
 
25
  def ask_from_file(file_obj, question, session_id):
26
  if not file_obj or not question.strip():
27
- return "⚠️ Please upload a file and enter a question.", chat_sessions["file"]
28
  if os.path.getsize(file_obj.name) > 10 * 1024 * 1024:
29
- return "❌ File too large. Please upload files under 10MB.", chat_sessions["file"]
30
-
31
  try:
32
- mime_type, _ = mimetypes.guess_type(file_obj.name)
33
  with open(file_obj.name, "rb") as f:
34
- files = {"file": (file_obj.name, f, mime_type or "application/octet-stream")}
35
  history = chat_sessions["file"]
36
  context = "\n".join([f"Q: {q}\nA: {a}" for q, a in history]) + f"\nQ: {question}"
37
- data = {"question": context}
38
- response = requests.post(FILE_API_URL, files=files, data=data)
39
- answer = sanitize(response.json().get("answer", "⚠️ No answer returned."))
40
  chat_sessions["file"].append((question, answer))
41
  return format_chat(chat_sessions["file"]), chat_sessions["file"]
42
  except Exception as e:
43
- return f"❌ Error: {str(e)}", chat_sessions["file"]
44
 
45
  def ask_from_url(url, question, session_id):
46
  if not url.strip() or not question.strip():
47
- return "⚠️ Please enter both a valid URL and a question.", chat_sessions["url"]
48
  try:
49
  history = chat_sessions["url"]
50
  context = "\n".join([f"Q: {q}\nA: {a}" for q, a in history]) + f"\nQ: {question}"
51
- response = requests.post(URL_API_URL, json={"url": url, "question": context})
52
- answer = sanitize(response.json().get("answer", "⚠️ No answer returned."))
53
  chat_sessions["url"].append((question, answer))
54
  return format_chat(chat_sessions["url"]), chat_sessions["url"]
55
  except Exception as e:
56
- return f"❌ Error: {str(e)}", chat_sessions["url"]
57
 
58
  def extract_text_from_image(image_path):
59
  try:
60
  with open(image_path, "rb") as f:
61
  files = {"file": ("image.png", f, "image/png")}
62
- response = requests.post(IMAGE_API_URL, files=files)
63
- return sanitize(response.json().get("answer", "⚠️ No text extracted."))
64
  except Exception as e:
65
- return f"❌ Error: {str(e)}"
66
 
67
  def transcribe_audio(audio_path):
68
  try:
69
  with open(audio_path, "rb") as f:
70
  files = {"file": ("audio.wav", f, "audio/wav")}
71
- response = requests.post(AUDIO_API_URL, files=files)
72
- return sanitize(response.json().get("answer", "⚠️ No transcript returned."))
73
  except Exception as e:
74
- return f"❌ Error: {str(e)}"
75
-
76
- def clear_file_chat():
77
- chat_sessions["file"] = []
78
- return "", chat_sessions["file"]
79
-
80
- def clear_url_chat():
81
- chat_sessions["url"] = []
82
- return "", chat_sessions["url"]
83
-
84
- # 💅 CSS
85
- custom_css = """
86
- body, .gradio-container {
87
- background-color: #111111 !important;
88
- color: white !important;
89
- }
90
- footer { display: none !important; }
91
- h1 {
92
- font-size: 2.2em;
93
- font-weight: bold;
94
- text-align: center;
95
- color: white;
96
- margin-bottom: 20px;
97
- }
98
- .gr-button {
99
- background-color: #00FF88;
100
- color: black;
101
- border: none;
102
- border-radius: 6px;
103
- font-weight: bold;
104
- }
105
- .gr-button:hover {
106
- background-color: #00cc70;
107
- }
108
- .gr-input, .gr-textbox, .gr-file, textarea, input {
109
- background-color: #1e1e1e !important;
110
- color: white !important;
111
- border: 1px solid #00FF88 !important;
112
- border-radius: 6px !important;
113
- }
114
- .gr-tabitem[data-selected="true"] > button {
115
- background-color: #00FF88 !important;
116
- color: black !important;
117
- }
118
- .gr-tabitem > button {
119
- background-color: transparent !important;
120
- color: white !important;
121
- }
122
- """
123
-
124
- # UI
125
- with gr.Blocks(css=custom_css) as demo:
126
- gr.Markdown("# 🤖 AI Chatbot with File, Web, Image, Audio & Chat History")
127
-
128
- with gr.Tab("📂 Chat with File"):
129
- file_input = gr.File(label="Upload File (.txt, .csv, .docx, .pdf)", file_types=[".txt", ".csv", ".docx", ".pdf"])
130
- file_question = gr.Textbox(label="Your Question", placeholder="Ask something based on file")
131
- file_button = gr.Button("Ask from File")
132
- file_output = gr.Textbox(label="Chat History", lines=10)
133
- clear_file = gr.Button("New File Chat")
134
-
135
- file_button.click(fn=ask_from_file, inputs=[file_input, file_question, gr.State("file")], outputs=[file_output, gr.State("file")])
136
- clear_file.click(fn=clear_file_chat, inputs=[], outputs=[file_output, gr.State("file")])
137
-
138
- with gr.Tab("🌐 Chat with Website"):
139
- url_input = gr.Textbox(label="Website URL", placeholder="https://example.com")
140
- url_question = gr.Textbox(label="Your Question", placeholder="Ask something based on webpage")
141
- url_button = gr.Button("Ask from URL")
142
- url_output = gr.Textbox(label="Chat History", lines=10)
143
- clear_url = gr.Button("New URL Chat")
144
-
145
- url_button.click(fn=ask_from_url, inputs=[url_input, url_question, gr.State("url")], outputs=[url_output, gr.State("url")])
146
- clear_url.click(fn=clear_url_chat, inputs=[], outputs=[url_output, gr.State("url")])
147
-
148
- with gr.Tab("🖼️ Extract Text from Image"):
149
- image_input = gr.Image(label="Upload Image", type="filepath")
150
- image_button = gr.Button("Extract Text")
151
- image_output = gr.Textbox(label="Extracted Text", lines=8)
152
- image_button.click(fn=extract_text_from_image, inputs=image_input, outputs=image_output)
153
-
154
- with gr.Tab("🎤 Transcribe Audio"):
155
- audio_input = gr.Audio(label="Upload Audio", type="filepath")
156
- audio_button = gr.Button("Transcribe Audio")
157
- audio_output = gr.Textbox(label="Transcript", lines=8)
158
- audio_button.click(fn=transcribe_audio, inputs=audio_input, outputs=audio_output)
159
 
160
  demo.launch(share=False)
 
2
  import requests
3
  import mimetypes
4
  import os
5
+ import threading
6
+ import uvicorn
7
  import re
8
 
 
9
  def sanitize(text):
10
  if isinstance(text, str):
11
  text = re.sub(r'[\uD800-\uDFFF]', '', text)
12
  return text.encode("utf-8", "ignore").decode("utf-8")
13
  return text
14
 
15
+ def run_fastapi():
16
+ uvicorn.run("main:app", host="0.0.0.0", port=8000)
17
+
18
+ threading.Thread(target=run_fastapi, daemon=True).start()
19
+
20
+ API_URLS = {
21
+ "file": "http://127.0.0.1:8000/chat-with-file",
22
+ "url": "http://127.0.0.1:8000/chat-with-url",
23
+ "image": "http://127.0.0.1:8000/extract-text-from-image",
24
+ "audio": "http://127.0.0.1:8000/transcribe-audio"
25
+ }
26
 
27
  chat_sessions = {"file": [], "url": []}
28
 
 
31
 
32
  def ask_from_file(file_obj, question, session_id):
33
  if not file_obj or not question.strip():
34
+ return "⚠️ Upload a file and enter a question.", chat_sessions["file"]
35
  if os.path.getsize(file_obj.name) > 10 * 1024 * 1024:
36
+ return "❌ File too large. Max 10MB.", chat_sessions["file"]
 
37
  try:
38
+ mime, _ = mimetypes.guess_type(file_obj.name)
39
  with open(file_obj.name, "rb") as f:
40
+ files = {"file": (file_obj.name, f, mime or "application/octet-stream")}
41
  history = chat_sessions["file"]
42
  context = "\n".join([f"Q: {q}\nA: {a}" for q, a in history]) + f"\nQ: {question}"
43
+ res = requests.post(API_URLS["file"], files=files, data={"question": context})
44
+ answer = sanitize(res.json().get("answer", "⚠️ No answer."))
 
45
  chat_sessions["file"].append((question, answer))
46
  return format_chat(chat_sessions["file"]), chat_sessions["file"]
47
  except Exception as e:
48
+ return f"❌ Error: {e}", chat_sessions["file"]
49
 
50
  def ask_from_url(url, question, session_id):
51
  if not url.strip() or not question.strip():
52
+ return "⚠️ URL and question required.", chat_sessions["url"]
53
  try:
54
  history = chat_sessions["url"]
55
  context = "\n".join([f"Q: {q}\nA: {a}" for q, a in history]) + f"\nQ: {question}"
56
+ res = requests.post(API_URLS["url"], json={"url": url, "question": context})
57
+ answer = sanitize(res.json().get("answer", "⚠️ No answer."))
58
  chat_sessions["url"].append((question, answer))
59
  return format_chat(chat_sessions["url"]), chat_sessions["url"]
60
  except Exception as e:
61
+ return f"❌ Error: {e}", chat_sessions["url"]
62
 
63
  def extract_text_from_image(image_path):
64
  try:
65
  with open(image_path, "rb") as f:
66
  files = {"file": ("image.png", f, "image/png")}
67
+ res = requests.post(API_URLS["image"], files=files)
68
+ return sanitize(res.json().get("answer", "⚠️ No text extracted."))
69
  except Exception as e:
70
+ return f"❌ Error: {e}"
71
 
72
  def transcribe_audio(audio_path):
73
  try:
74
  with open(audio_path, "rb") as f:
75
  files = {"file": ("audio.wav", f, "audio/wav")}
76
+ res = requests.post(API_URLS["audio"], files=files)
77
+ return sanitize(res.json().get("answer", "⚠️ No transcript returned."))
78
  except Exception as e:
79
+ return f"❌ Error: {e}"
80
+
81
+ def clear_file_chat(): chat_sessions["file"] = []; return "", chat_sessions["file"]
82
+ def clear_url_chat(): chat_sessions["url"] = []; return "", chat_sessions["url"]
83
+
84
+ with gr.Blocks(css="") as demo:
85
+ gr.Markdown("# 🤖 AI Chatbot with File, Web, Image, Audio")
86
+ with gr.Tab("📂 File"):
87
+ file = gr.File(file_types=[".txt", ".csv", ".docx", ".pdf"])
88
+ q1 = gr.Textbox(label="Question")
89
+ b1 = gr.Button("Ask from File")
90
+ out1 = gr.Textbox(label="Chat", lines=10)
91
+ clr1 = gr.Button("Clear")
92
+ b1.click(fn=ask_from_file, inputs=[file, q1, gr.State("file")], outputs=[out1, gr.State("file")])
93
+ clr1.click(fn=clear_file_chat, outputs=[out1, gr.State("file")])
94
+
95
+ with gr.Tab("🌐 URL"):
96
+ url = gr.Textbox(label="Website URL")
97
+ q2 = gr.Textbox(label="Question")
98
+ b2 = gr.Button("Ask from URL")
99
+ out2 = gr.Textbox(label="Chat", lines=10)
100
+ clr2 = gr.Button("Clear")
101
+ b2.click(fn=ask_from_url, inputs=[url, q2, gr.State("url")], outputs=[out2, gr.State("url")])
102
+ clr2.click(fn=clear_url_chat, outputs=[out2, gr.State("url")])
103
+
104
+ with gr.Tab("🖼️ Image OCR"):
105
+ img = gr.Image(type="filepath")
106
+ b3 = gr.Button("Extract Text")
107
+ out3 = gr.Textbox(label="Text", lines=8)
108
+ b3.click(fn=extract_text_from_image, inputs=img, outputs=out3)
109
+
110
+ with gr.Tab("🎤 Audio"):
111
+ aud = gr.Audio(type="filepath")
112
+ b4 = gr.Button("Transcribe")
113
+ out4 = gr.Textbox(label="Transcript", lines=8)
114
+ b4.click(fn=transcribe_audio, inputs=aud, outputs=out4)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  demo.launch(share=False)