File size: 4,362 Bytes
6c9b654
a61d9a2
563ecd1
a61d9a2
563ecd1
a32e403
a61d9a2
 
563ecd1
0f51a21
563ecd1
 
a32e403
563ecd1
 
 
a61d9a2
 
 
 
 
 
a32e403
563ecd1
 
 
 
 
a61d9a2
 
 
a32e403
a61d9a2
a32e403
563ecd1
 
 
a61d9a2
 
563ecd1
a61d9a2
 
9f92924
563ecd1
a61d9a2
563ecd1
 
 
 
 
 
a61d9a2
9f92924
563ecd1
a61d9a2
563ecd1
a61d9a2
9f92924
563ecd1
a32e403
563ecd1
 
 
 
 
a32e403
563ecd1
 
 
 
 
 
 
 
a61d9a2
563ecd1
 
 
 
 
 
a61d9a2
563ecd1
 
 
 
 
 
 
a61d9a2
563ecd1
 
 
 
 
 
 
a61d9a2
563ecd1
 
a61d9a2
563ecd1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a61d9a2
563ecd1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a32e403
563ecd1
a32e403
0f51a21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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()