Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import json | |
| import os | |
| from openai import OpenAI | |
| from datetime import datetime | |
| # Global variables | |
| client = None | |
| conversation_history = [] | |
| def validate_api_key(api_key): | |
| """Validate OpenAI API key by making a test request""" | |
| try: | |
| test_client = OpenAI(api_key=api_key) | |
| # Make a minimal test request | |
| test_client.responses.create( | |
| model="gpt-4o-mini", | |
| input="Hello" | |
| ) | |
| return True, "API key is valid!" | |
| except Exception as e: | |
| return False, f"Invalid API key: {str(e)}" | |
| def save_api_key(api_key): | |
| """Save API key and initialize client""" | |
| global client | |
| is_valid, message = validate_api_key(api_key) | |
| if is_valid: | |
| client = OpenAI(api_key=api_key) | |
| return gr.update(visible=False), gr.update(visible=True), message | |
| else: | |
| return gr.update(visible=True), gr.update(visible=False), message | |
| def chat(message, history, response_id): | |
| """Process chat message and get response""" | |
| global client, conversation_history | |
| if not client: | |
| return history + [[message, "Please enter a valid API key first"]], None | |
| try: | |
| # Add user message to history | |
| conversation_history.append({"role": "user", "content": message}) | |
| # Get response from OpenAI | |
| response = client.responses.create( | |
| model="gpt-4o-mini", | |
| input=message, | |
| previous_response_id=response_id if response_id else None | |
| ) | |
| # Add assistant response to history | |
| conversation_history.append({"role": "assistant", "content": response.output_text}) | |
| return history + [[message, response.output_text]], response.id | |
| except Exception as e: | |
| error_message = f"Error: {str(e)}" | |
| return history + [[message, error_message]], None | |
| def clear_chat(history): | |
| """Clear the chat history""" | |
| global conversation_history | |
| conversation_history = [] | |
| return [], None | |
| # Create Gradio interface | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| gr.HTML(""" | |
| <div style="text-align: center; margin-bottom: 1rem"> | |
| <h1 style="margin-bottom: 0.5rem">Chatbot based on responses API by Pejman Ebrahimi</h1> | |
| <p>Powered by OpenAI's Responses API</p> | |
| </div> | |
| """) | |
| # API key input interface | |
| with gr.Group(visible=True) as api_key_group: | |
| api_key_input = gr.Textbox( | |
| label="Enter your OpenAI API Key", | |
| placeholder="sk-...", | |
| type="password" | |
| ) | |
| api_submit_btn = gr.Button("Submit API Key") | |
| api_message = gr.Textbox(label="Status") | |
| # Chat interface | |
| with gr.Group(visible=False) as chat_group: | |
| chatbot = gr.Chatbot(height=500) | |
| response_id = gr.State(None) | |
| with gr.Row(): | |
| msg = gr.Textbox( | |
| label="Message", | |
| placeholder="Type your message here...", | |
| show_label=False | |
| ) | |
| submit_btn = gr.Button("Send") | |
| with gr.Row(): | |
| clear_btn = gr.Button("Clear Chat") | |
| # Set up event handlers | |
| api_submit_btn.click( | |
| save_api_key, | |
| inputs=[api_key_input], | |
| outputs=[api_key_group, chat_group, api_message] | |
| ) | |
| msg.submit( | |
| chat, | |
| inputs=[msg, chatbot, response_id], | |
| outputs=[chatbot, response_id] | |
| ).then( | |
| lambda: "", | |
| None, | |
| [msg] | |
| ) | |
| submit_btn.click( | |
| chat, | |
| inputs=[msg, chatbot, response_id], | |
| outputs=[chatbot, response_id] | |
| ).then( | |
| lambda: "", | |
| None, | |
| [msg] | |
| ) | |
| clear_btn.click( | |
| clear_chat, | |
| inputs=[chatbot], | |
| outputs=[chatbot, response_id] | |
| ) | |
| # Footer | |
| gr.HTML(""" | |
| <div style="text-align: center; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid #ddd"> | |
| <p>© 2025 Pejman Ebrahimi | Built with Gradio and OpenAI Responses API</p> | |
| <p style="font-size: 0.8rem; color: #666"> | |
| This application securely processes your conversations using OpenAI's technology. | |
| Your API key is used only for authentication and is not stored permanently. | |
| </p> | |
| </div> | |
| """) | |
| # Launch the app | |
| if __name__ == "__main__": | |
| app.launch() |