| import gradio as gr | |
| import requests | |
| import mimetypes | |
| import os | |
| import threading | |
| import uvicorn | |
| import re | |
| def sanitize(text): | |
| if isinstance(text, str): | |
| text = re.sub(r'[\uD800-\uDFFF]', '', text) | |
| return text.encode("utf-8", "ignore").decode("utf-8") | |
| return text | |
| def run_fastapi(): | |
| uvicorn.run("main:app", host="0.0.0.0", port=8000) | |
| threading.Thread(target=run_fastapi, daemon=True).start() | |
| API_URLS = { | |
| "file": "http://127.0.0.1:8000/chat-with-file", | |
| "url": "http://127.0.0.1:8000/chat-with-url", | |
| "image": "http://127.0.0.1:8000/extract-text-from-image", | |
| "audio": "http://127.0.0.1:8000/transcribe-audio" | |
| } | |
| chat_sessions = {"file": [], "url": []} | |
| def format_chat(history): | |
| return "\n\n".join([f"π€ {sanitize(q)}\nπ€ {sanitize(a)}" for q, a in history]) | |
| def ask_from_file(file_obj, question, session_id): | |
| if not file_obj or not question.strip(): | |
| return "β οΈ Upload a file and enter a question.", chat_sessions["file"] | |
| if os.path.getsize(file_obj.name) > 10 * 1024 * 1024: | |
| return "β File too large. Max 10MB.", chat_sessions["file"] | |
| try: | |
| mime, _ = mimetypes.guess_type(file_obj.name) | |
| with open(file_obj.name, "rb") as f: | |
| files = {"file": (file_obj.name, f, mime or "application/octet-stream")} | |
| history = chat_sessions["file"] | |
| context = "\n".join([f"Q: {q}\nA: {a}" for q, a in history]) + f"\nQ: {question}" | |
| res = requests.post(API_URLS["file"], files=files, data={"question": context}) | |
| answer = sanitize(res.json().get("answer", "β οΈ No answer.")) | |
| chat_sessions["file"].append((question, answer)) | |
| return format_chat(chat_sessions["file"]), chat_sessions["file"] | |
| except Exception as e: | |
| return f"β Error: {e}", chat_sessions["file"] | |
| def ask_from_url(url, question, session_id): | |
| if not url.strip() or not question.strip(): | |
| return "β οΈ URL and question required.", chat_sessions["url"] | |
| try: | |
| history = chat_sessions["url"] | |
| context = "\n".join([f"Q: {q}\nA: {a}" for q, a in history]) + f"\nQ: {question}" | |
| res = requests.post(API_URLS["url"], json={"url": url, "question": context}) | |
| answer = sanitize(res.json().get("answer", "β οΈ No answer.")) | |
| chat_sessions["url"].append((question, answer)) | |
| return format_chat(chat_sessions["url"]), chat_sessions["url"] | |
| except Exception as e: | |
| return f"β Error: {e}", chat_sessions["url"] | |
| def extract_text_from_image(image_path): | |
| try: | |
| with open(image_path, "rb") as f: | |
| files = {"file": ("image.png", f, "image/png")} | |
| res = requests.post(API_URLS["image"], files=files) | |
| return sanitize(res.json().get("answer", "β οΈ No text extracted.")) | |
| except Exception as e: | |
| return f"β Error: {e}" | |
| def transcribe_audio(audio_path): | |
| try: | |
| with open(audio_path, "rb") as f: | |
| files = {"file": ("audio.wav", f, "audio/wav")} | |
| res = requests.post(API_URLS["audio"], files=files) | |
| return sanitize(res.json().get("answer", "β οΈ No transcript returned.")) | |
| except Exception as e: | |
| return f"β Error: {e}" | |
| def clear_file_chat(): chat_sessions["file"] = []; return "", chat_sessions["file"] | |
| def clear_url_chat(): chat_sessions["url"] = []; return "", chat_sessions["url"] | |
| with gr.Blocks(css="") as demo: | |
| gr.Markdown("# π€ AI Chatbot with File, Web, Image, Audio") | |
| with gr.Tab("π File"): | |
| file = gr.File(file_types=[".txt", ".csv", ".docx", ".pdf"]) | |
| q1 = gr.Textbox(label="Question") | |
| b1 = gr.Button("Ask from File") | |
| out1 = gr.Textbox(label="Chat", lines=10) | |
| clr1 = gr.Button("Clear") | |
| b1.click(fn=ask_from_file, inputs=[file, q1, gr.State("file")], outputs=[out1, gr.State("file")]) | |
| clr1.click(fn=clear_file_chat, outputs=[out1, gr.State("file")]) | |
| with gr.Tab("π URL"): | |
| url = gr.Textbox(label="Website URL") | |
| q2 = gr.Textbox(label="Question") | |
| b2 = gr.Button("Ask from URL") | |
| out2 = gr.Textbox(label="Chat", lines=10) | |
| clr2 = gr.Button("Clear") | |
| b2.click(fn=ask_from_url, inputs=[url, q2, gr.State("url")], outputs=[out2, gr.State("url")]) | |
| clr2.click(fn=clear_url_chat, outputs=[out2, gr.State("url")]) | |
| with gr.Tab("πΌοΈ Image OCR"): | |
| img = gr.Image(type="filepath") | |
| b3 = gr.Button("Extract Text") | |
| out3 = gr.Textbox(label="Text", lines=8) | |
| b3.click(fn=extract_text_from_image, inputs=img, outputs=out3) | |
| with gr.Tab("π€ Audio"): | |
| aud = gr.Audio(type="filepath") | |
| b4 = gr.Button("Transcribe") | |
| out4 = gr.Textbox(label="Transcript", lines=8) | |
| b4.click(fn=transcribe_audio, inputs=aud, outputs=out4) | |
| demo.launch(share=False) | |