Spaces:
Build error
Build error
| import gradio as gr | |
| import openai | |
| import base64 #Image to base64 convert | |
| from PIL import Image | |
| import io | |
| import fitz #PDF to text extract | |
| #For text extractipn from pdf | |
| def extract_text_from_pdf(pdf_file): | |
| try: | |
| text = "" | |
| pdf_document = fitz.open(pdf_file) #to open the pdf | |
| for page_num in range(len(pdf_document)): | |
| page = pdf_document[page_num] | |
| text += page.get_text() | |
| #this for loop will go through every pages of the pdf and extract the texts of that pdf and keep them into text += page.get_text() | |
| pdf_document.close() | |
| return text | |
| except Exception as e: | |
| return f"Error extracting text from PDF: {str(e)}" | |
| #For generating quiz | |
| def generate_mcq_quiz(pdf_content,openai_api_key,model_choice): | |
| if not openai_api_key: | |
| return "Error: No API key provided." | |
| openai_api_key = openai_api_key | |
| limited_content = pdf_content[:8000] if len(pdf_content)>8000 else pdf_content | |
| prompt = f"""Based on the following document content, generate {num_questions} multiple-choice quiz questions. | |
| For each question: | |
| 1. Create a clear question based on key concepts in the document | |
| 2. Provide 4 possible answers (A, B, C, D) | |
| 3. Indicate the correct answer | |
| 4. Briefly explain why the answer is correct | |
| Format the output clearly with each question numbered and separated. | |
| Document content: | |
| {limited_content} | |
| """ | |
| try: | |
| response = openai.ChatCompletion.create( | |
| model=model_choice, | |
| messages=[{"role": "user", "content": prompt}] | |
| ) | |
| return response.choices[0].message.content | |
| except Exception as e: | |
| return f"Error generating quiz: {str(e)}" | |
| # Function to handle image inputs | |
| def generate_image_response(input_text, image, openai_api_key, model_choice): | |
| if not openai_api_key: | |
| return "Error: No API key provided." | |
| openai.api_key = openai_api_key | |
| # Convert image to base64 | |
| buffered = io.BytesIO() | |
| image.save(buffered, format="PNG") | |
| base64_str = base64.b64encode(buffered.getvalue()).decode("utf-8") | |
| try: | |
| response = openai.ChatCompletion.create( | |
| model=model_choice, | |
| messages=[ | |
| { | |
| "role": "user", | |
| "content": [ | |
| {"type": "text", "text": input_text}, #what user asked | |
| {"type": "image_url", | |
| "image_url": {"url": f"data:image/png;base64,{base64_str}"} #Image to url format | |
| } | |
| ] | |
| } | |
| ], | |
| max_completion_tokens=2000 #Ami je kono question korlei sheta 2000 words er moddhe answer dibe | |
| ) | |
| return response.choices[0].message.content | |
| except Exception as e: | |
| return f"Error processing image: {str(e)}" | |
| # Main chatbot function | |
| def chatbot(input_text, image, pdf_file, openai_api_key, model_choice, pdf_content, num_quiz_questions, pdf_quiz_mode, history): | |
| if history is None: | |
| history = [] | |
| new_pdf_content = pdf_content | |
| if pdf_file is not None: | |
| new_pdf_content = extract_text_from_pdf(pdf_file) | |
| if pdf_quiz_mode: | |
| if new_pdf_content: | |
| quiz_response = generate_mcq_quiz(new_pdf_content, int(num_quiz_questions), openai_api_key, model_choice) | |
| history.append((f"π€: [PDF Quiz - {num_quiz_questions} questions]", f"π€: {quiz_response}")) | |
| else: | |
| history.append(("π€: [PDF Quiz]", "π€: Please upload a PDF file to generate questions.")) | |
| else: | |
| if image is not None: | |
| response = generate_image_response(input_text, image, openai_api_key, model_choice) | |
| if input_text.strip(): | |
| history.append((f"π€: {input_text}", f"π€: {response}")) | |
| else: | |
| history.append((f"π€: [Image]", f"π€: {response}")) | |
| return "", None, None, new_pdf_content, history | |
| def clear_history(): | |
| return "", None, None, "", [] | |
| def update_input_type(choice): | |
| if choice == "Image": | |
| return ( | |
| gr.update(visible=True), #question box | |
| gr.update(visible=True), #upload image | |
| gr.update(visible=False), #no upload pdf | |
| gr.update(visible=False), #no number of questions | |
| gr.update(value=False) #no quiz mode | |
| ) | |
| elif choice == "PDF(QUIZ)": | |
| return ( | |
| gr.update(visible=False), #question box | |
| gr.update(visible=False), #no upload image | |
| gr.update(visible=True), #upload pdf | |
| gr.update(visible=True), #number of questions | |
| gr.update(value=True) #quiz mode | |
| ) | |
| # Custom CSS styling | |
| custom_css = """ | |
| .gradio-container { | |
| font-family: 'Arial', sans-serif; | |
| background-color: #f0f4f8; | |
| } | |
| .gradio-header { | |
| background: linear-gradient(135deg, #4a00e0 0%, #8e2de2 100%); | |
| color: white; | |
| padding: 20px; | |
| border-radius: 8px; | |
| text-align: center; | |
| } | |
| .gradio-chatbot { | |
| background-color: white; | |
| border-radius: 10px; | |
| padding: 20px; | |
| box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1); | |
| } | |
| #submit-btn { | |
| background: linear-gradient(135deg, #4a00e0 0%, #8e2de2 100%); | |
| color: white; | |
| border-radius: 8px; | |
| } | |
| #clear-history { | |
| background: linear-gradient(135deg, #e53e3e 0%, #f56565 100%); | |
| color: white; | |
| border-radius: 8px; | |
| } | |
| """ | |
| def create_interface(): | |
| with gr.Blocks(css=custom_css) as demo: | |
| gr.Markdown(""" | |
| <div class="gradio-header"> | |
| <h1>Multimodal Chatbot (Image + PDF Quiz)</h1> | |
| <h3>Analyze images or generate quizzes from PDFs</h3> | |
| </div> | |
| """) | |
| with gr.Accordion("Instructions", open=False): | |
| gr.Markdown(""" | |
| - **Image Chat**: Upload an image and ask questions about it | |
| - **PDF Quiz**: Upload a PDF and generate multiple-choice questions | |
| - Always provide your OpenAI API key | |
| - Choose appropriate model (o1 for images, o3-mini for text) | |
| """) | |
| pdf_content = gr.State("") | |
| with gr.Row(): | |
| openai_api_key = gr.Textbox(label="OpenAI API Key", type="password", placeholder="sk-...") | |
| with gr.Row(): | |
| input_type = gr.Radio(["Image", "PDF(QUIZ)"], label="Input Type", value="Image") | |
| with gr.Row(): | |
| input_text = gr.Textbox(label="Question (for images)", visible=True) | |
| image_input = gr.Image(label="Upload Image", type="pil", visible=True) | |
| pdf_input = gr.File(label="Upload PDF", visible=False) | |
| quiz_slider = gr.Slider(1, 20, value=5, step=1, label="Number of Questions", visible=False) | |
| quiz_mode = gr.Checkbox(visible=False) | |
| with gr.Row(): | |
| model_choice = gr.Dropdown(["o1", "o3-mini"], label="Model", value="o1") | |
| submit_btn = gr.Button("Submit", elem_id="submit-btn") | |
| clear_btn = gr.Button("Clear History", elem_id="clear-history") | |
| chat_history = gr.Chatbot() | |
| input_type.change( | |
| update_input_type, | |
| inputs=[input_type], | |
| outputs=[input_text, image_input, pdf_input, quiz_slider, quiz_mode] | |
| ) | |
| submit_btn.click( | |
| chatbot, | |
| inputs=[input_text, image_input, pdf_input, openai_api_key, model_choice, pdf_content, quiz_slider, quiz_mode, chat_history], | |
| outputs=[input_text, image_input, pdf_input, pdf_content, chat_history] | |
| ) | |
| clear_btn.click( | |
| clear_history, | |
| outputs=[input_text, image_input, pdf_input, pdf_content, chat_history] | |
| ) | |
| return demo | |
| if __name__ == "__main__": | |
| demo = create_interface() | |
| demo.launch() | |