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() |