Sandipan Haldar commited on
Commit
ac246b3
ยท
1 Parent(s): 770544d

feat: Add OpenAI API key input option in UI

Browse files

- Add API key configuration section in Settings accordion
- Implement password-protected OpenAI API key input field
- Add real-time API status display and connection testing
- Enable users to use personal OpenAI quota instead of shared limits
- Add dynamic API key validation and error handling
- Implement custom autocomplete instance creation for user keys
- Update AutoCompleteApp class with API key management methods
- Modify main function to allow startup without pre-configured keys
- Add comprehensive user documentation for API key feature
- Enhance user experience with real-time status updates

This allows users to enter their own OpenAI API key directly in the interface,
avoiding rate limits and using their personal quota while maintaining security
by not storing keys permanently.

Files changed (1) hide show
  1. app.py +133 -13
app.py CHANGED
@@ -24,6 +24,8 @@ class AutoCompleteApp:
24
  def __init__(self):
25
  self.last_request_time = 0
26
  self.current_suggestions = []
 
 
27
 
28
  def get_suggestions(
29
  self, text: str, context: str, output_tokens: int = 150, user_context: str = ""
@@ -87,8 +89,13 @@ class AutoCompleteApp:
87
  f"โš ๏ธ Text too long (max {settings.MAX_INPUT_LENGTH} characters)",
88
  )
89
 
 
 
 
90
  # Create a temporary autocomplete instance with custom prompts
91
- temp_autocomplete = SmartAutoComplete(settings)
 
 
92
  if custom_prompts:
93
  temp_autocomplete.CONTEXT_PROMPTS = custom_prompts
94
 
@@ -134,6 +141,68 @@ class AutoCompleteApp:
134
  logger.error(f"Error inserting suggestion: {str(e)}")
135
  return current_text
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
  def create_interface():
139
  """Create and configure the Gradio interface"""
@@ -175,6 +244,8 @@ def create_interface():
175
  **Intelligent text completion powered by AI**
176
 
177
  Choose your context, enter your text, and click submit to get AI-powered completions! โœจ
 
 
178
  """)
179
 
180
  with gr.Row():
@@ -214,6 +285,31 @@ def create_interface():
214
 
215
  # Settings
216
  with gr.Accordion("โš™๏ธ Settings", open=False):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  output_length = gr.Slider(
218
  minimum=50,
219
  maximum=500,
@@ -341,6 +437,16 @@ def create_interface():
341
  )
342
 
343
  # Event handlers
 
 
 
 
 
 
 
 
 
 
344
  def update_suggestions(
345
  text,
346
  context,
@@ -394,6 +500,15 @@ def create_interface():
394
  copy_update = gr.update(visible=copy_visible, value=copy_text)
395
  return status, copy_update
396
 
 
 
 
 
 
 
 
 
 
397
  # Submit button handler
398
  submit_btn.click(
399
  fn=update_suggestions,
@@ -417,15 +532,17 @@ def create_interface():
417
  ---
418
 
419
  ### ๐ŸŽฎ How to Use:
420
- 1. **Select your context** (Email, Creative, or LinkedIn)
421
- 2. **Add context information** (optional) - background info, references, or previous context
422
- 3. **Enter your text** in the main text area
423
- 4. **Adjust output length** (50-500 tokens) in settings
424
- 5. **Customize prompts** (optional) - edit AI prompts in "Edit Context Prompts" section
425
- 6. **Click "Get Suggestions"** to generate completions
426
- 7. **Copy from the generated text box** (Select All + Ctrl+C/Cmd+C)
 
427
 
428
  ### ๐ŸŒŸ Pro Tips:
 
429
  - **Context Window**: Add background info, previous conversations, or references to improve suggestions
430
  - **Email**: Try starting with "Dear..." or "I hope..." + add meeting context
431
  - **Creative**: Start with "Once upon a time..." + add story background
@@ -450,12 +567,15 @@ def create_interface():
450
  def main():
451
  """Main function to run the application"""
452
  try:
453
- # Check API configuration
454
  if not settings.validate_api_keys():
455
- logger.error("No valid API keys found. Please configure your API keys.")
456
- print("โŒ Error: No valid API keys configured!")
457
- print("Please set OPENAI_API_KEY or ANTHROPIC_API_KEY in your .env file")
458
- return
 
 
 
459
 
460
  logger.info("Starting Smart Auto-Complete application...")
461
 
 
24
  def __init__(self):
25
  self.last_request_time = 0
26
  self.current_suggestions = []
27
+ self.user_api_key = None
28
+ self.custom_autocomplete = None
29
 
30
  def get_suggestions(
31
  self, text: str, context: str, output_tokens: int = 150, user_context: str = ""
 
89
  f"โš ๏ธ Text too long (max {settings.MAX_INPUT_LENGTH} characters)",
90
  )
91
 
92
+ # Use the active autocomplete instance (user's custom or default)
93
+ active_autocomplete = self.get_active_autocomplete()
94
+
95
  # Create a temporary autocomplete instance with custom prompts
96
+ temp_autocomplete = SmartAutoComplete(
97
+ active_autocomplete.settings if active_autocomplete else settings
98
+ )
99
  if custom_prompts:
100
  temp_autocomplete.CONTEXT_PROMPTS = custom_prompts
101
 
 
141
  logger.error(f"Error inserting suggestion: {str(e)}")
142
  return current_text
143
 
144
+ def update_api_key(self, api_key: str) -> str:
145
+ """Update the OpenAI API key and reinitialize the autocomplete engine"""
146
+ try:
147
+ if not api_key or not api_key.strip():
148
+ self.user_api_key = None
149
+ self.custom_autocomplete = None
150
+ return "๐Ÿ”„ Reverted to default configuration"
151
+
152
+ # Validate the API key format
153
+ if not api_key.startswith("sk-"):
154
+ return "โŒ Invalid API key format. OpenAI keys start with 'sk-'"
155
+
156
+ # Create a custom settings object with the user's API key
157
+ from config.settings import AppSettings
158
+
159
+ custom_settings = AppSettings()
160
+ custom_settings.OPENAI_API_KEY = api_key.strip()
161
+
162
+ # Create a new autocomplete instance with the custom settings
163
+ self.custom_autocomplete = SmartAutoComplete(custom_settings)
164
+ self.user_api_key = api_key.strip()
165
+
166
+ return "โœ… API key updated successfully! Using your personal quota."
167
+
168
+ except Exception as e:
169
+ logger.error(f"Error updating API key: {str(e)}")
170
+ return f"โŒ Error updating API key: {str(e)}"
171
+
172
+ def test_api_connection(self, api_key: str = None) -> str:
173
+ """Test the API connection with the current or provided key"""
174
+ try:
175
+ # Use custom autocomplete if user has provided a key, otherwise use default
176
+ test_autocomplete = (
177
+ self.custom_autocomplete if self.user_api_key else autocomplete
178
+ )
179
+
180
+ if api_key and api_key.strip():
181
+ # Test with the provided key
182
+ from config.settings import AppSettings
183
+
184
+ test_settings = AppSettings()
185
+ test_settings.OPENAI_API_KEY = api_key.strip()
186
+ test_autocomplete = SmartAutoComplete(test_settings)
187
+
188
+ # Test with a simple completion
189
+ test_result = test_autocomplete.get_suggestions(
190
+ text="Hello, this is a test", context="linkedin", max_tokens=10
191
+ )
192
+
193
+ if test_result and len(test_result) > 0:
194
+ return "โœ… API connection successful!"
195
+ else:
196
+ return "โŒ API connection failed - no response received"
197
+
198
+ except Exception as e:
199
+ logger.error(f"API connection test failed: {str(e)}")
200
+ return f"โŒ API connection test failed: {str(e)}"
201
+
202
+ def get_active_autocomplete(self):
203
+ """Get the currently active autocomplete instance"""
204
+ return self.custom_autocomplete if self.user_api_key else autocomplete
205
+
206
 
207
  def create_interface():
208
  """Create and configure the Gradio interface"""
 
244
  **Intelligent text completion powered by AI**
245
 
246
  Choose your context, enter your text, and click submit to get AI-powered completions! โœจ
247
+
248
+ ๐Ÿ’ก **Tip**: Add your own OpenAI API key in Settings to use your personal quota and avoid rate limits.
249
  """)
250
 
251
  with gr.Row():
 
285
 
286
  # Settings
287
  with gr.Accordion("โš™๏ธ Settings", open=False):
288
+ # API Key Configuration
289
+ with gr.Group():
290
+ gr.Markdown("### ๐Ÿ”‘ API Configuration")
291
+ openai_key_input = gr.Textbox(
292
+ label="OpenAI API Key (Optional)",
293
+ placeholder="sk-... (Enter your OpenAI API key to use your own quota)",
294
+ type="password",
295
+ value="",
296
+ info="Your API key is only used for this session and not stored permanently.",
297
+ )
298
+
299
+ api_status = gr.Textbox(
300
+ label="API Status",
301
+ value="Using default configuration"
302
+ if settings.OPENAI_API_KEY
303
+ else "No API key configured",
304
+ interactive=False,
305
+ lines=1,
306
+ )
307
+
308
+ test_api_btn = gr.Button("๐Ÿงช Test API Connection", size="sm")
309
+
310
+ gr.Markdown("---")
311
+
312
+ # Output Settings
313
  output_length = gr.Slider(
314
  minimum=50,
315
  maximum=500,
 
437
  )
438
 
439
  # Event handlers
440
+ def update_api_key(api_key):
441
+ """Handle API key updates"""
442
+ status = app_instance.update_api_key(api_key)
443
+ return status
444
+
445
+ def test_api_connection(api_key):
446
+ """Handle API connection testing"""
447
+ status = app_instance.test_api_connection(api_key)
448
+ return status
449
+
450
  def update_suggestions(
451
  text,
452
  context,
 
500
  copy_update = gr.update(visible=copy_visible, value=copy_text)
501
  return status, copy_update
502
 
503
+ # API Key event handlers
504
+ openai_key_input.change(
505
+ fn=update_api_key, inputs=[openai_key_input], outputs=[api_status]
506
+ )
507
+
508
+ test_api_btn.click(
509
+ fn=test_api_connection, inputs=[openai_key_input], outputs=[api_status]
510
+ )
511
+
512
  # Submit button handler
513
  submit_btn.click(
514
  fn=update_suggestions,
 
532
  ---
533
 
534
  ### ๐ŸŽฎ How to Use:
535
+ 1. **Add your API key** (optional) - Enter your OpenAI API key in Settings to use your own quota
536
+ 2. **Select your context** (Email, Creative, or LinkedIn)
537
+ 3. **Add context information** (optional) - background info, references, or previous context
538
+ 4. **Enter your text** in the main text area
539
+ 5. **Adjust output length** (50-500 tokens) in settings
540
+ 6. **Customize prompts** (optional) - edit AI prompts in "Edit Context Prompts" section
541
+ 7. **Click "Get Suggestions"** to generate completions
542
+ 8. **Copy from the generated text box** (Select All + Ctrl+C/Cmd+C)
543
 
544
  ### ๐ŸŒŸ Pro Tips:
545
+ - **API Key**: Add your own OpenAI API key to use your personal quota and avoid rate limits
546
  - **Context Window**: Add background info, previous conversations, or references to improve suggestions
547
  - **Email**: Try starting with "Dear..." or "I hope..." + add meeting context
548
  - **Creative**: Start with "Once upon a time..." + add story background
 
567
  def main():
568
  """Main function to run the application"""
569
  try:
570
+ # Check API configuration - now optional since users can provide their own keys
571
  if not settings.validate_api_keys():
572
+ logger.warning(
573
+ "No default API keys found. Users can provide their own keys in the UI."
574
+ )
575
+ print("โš ๏ธ No default API keys configured.")
576
+ print("Users can enter their own OpenAI API key in the Settings section.")
577
+ else:
578
+ logger.info("Default API keys found and validated.")
579
 
580
  logger.info("Starting Smart Auto-Complete application...")
581