API Setup Updates and Tweaks
This commit is contained in:
@@ -7,6 +7,8 @@ from ..manager import APIKeyManager
|
||||
from .base import render_navigation_buttons, render_step_indicator, render_tab_style
|
||||
from ..wizard_state import next_step, update_progress
|
||||
from datetime import datetime
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
def validate_api_key(key: str) -> bool:
|
||||
"""Validate if an API key is properly formatted."""
|
||||
@@ -15,10 +17,53 @@ def validate_api_key(key: str) -> bool:
|
||||
# Basic validation - check if key is not empty and has minimum length
|
||||
return len(key.strip()) > 0
|
||||
|
||||
def save_to_env_file(key_name: str, key_value: str) -> bool:
|
||||
"""Save API key to .env file."""
|
||||
try:
|
||||
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))), '.env')
|
||||
|
||||
# Read existing .env file
|
||||
env_contents = []
|
||||
if os.path.exists(env_path):
|
||||
with open(env_path, 'r') as f:
|
||||
env_contents = f.readlines()
|
||||
|
||||
# Check if key already exists
|
||||
key_exists = False
|
||||
for i, line in enumerate(env_contents):
|
||||
if line.startswith(f"{key_name}="):
|
||||
env_contents[i] = f"{key_name}={key_value}\n"
|
||||
key_exists = True
|
||||
break
|
||||
|
||||
# Add new key if it doesn't exist
|
||||
if not key_exists:
|
||||
env_contents.append(f"{key_name}={key_value}\n")
|
||||
|
||||
# Write back to .env file
|
||||
with open(env_path, 'w') as f:
|
||||
f.writelines(env_contents)
|
||||
|
||||
# Reload environment variables to ensure consistency
|
||||
load_dotenv(override=True)
|
||||
|
||||
logger.info(f"[save_to_env_file] Successfully saved {key_name} to .env file")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"[save_to_env_file] Error saving to .env file: {str(e)}")
|
||||
return False
|
||||
|
||||
def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
"""Render the AI providers setup step."""
|
||||
logger.info("[render_ai_providers] Starting AI providers setup")
|
||||
try:
|
||||
# Load environment variables
|
||||
load_dotenv(override=True)
|
||||
|
||||
# Get existing API keys from .env
|
||||
openai_key = os.getenv('OPENAI_API_KEY', '')
|
||||
gemini_key = os.getenv('GEMINI_API_KEY', '')
|
||||
|
||||
# Initialize wizard state if not already initialized
|
||||
if 'wizard_state' not in st.session_state:
|
||||
st.session_state.wizard_state = {
|
||||
@@ -35,10 +80,7 @@ def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
|
||||
# Main content
|
||||
st.markdown("""
|
||||
<div class='setup-header'>
|
||||
<h2>🤖 AI Providers Setup</h2>
|
||||
<p>Configure your AI service providers for content generation</p>
|
||||
</div>
|
||||
<div class='setup-header'><h2>🤖 AI LLM Providers Setup</h2></div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# Create tabs for different AI providers
|
||||
@@ -51,7 +93,6 @@ def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
|
||||
with tabs[0]:
|
||||
st.markdown("### Primary AI Providers")
|
||||
st.markdown("Configure the main AI providers for content creation")
|
||||
|
||||
# Create a grid layout for AI provider cards
|
||||
col1, col2 = st.columns(2)
|
||||
@@ -59,26 +100,19 @@ def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
with col1:
|
||||
# OpenAI Card
|
||||
with st.container():
|
||||
st.markdown("""
|
||||
<div class="ai-provider-card">
|
||||
<div class="ai-provider-header">
|
||||
<div class="ai-provider-icon">🤖</div>
|
||||
<div class="ai-provider-title">OpenAI</div>
|
||||
</div>
|
||||
<div class="ai-provider-content">
|
||||
<p>Power your content with GPT-4 and GPT-3.5 models</p>
|
||||
<div class="ai-provider-input">
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
openai_key = st.text_input(
|
||||
openai_input = st.text_input(
|
||||
"OpenAI API Key",
|
||||
value=openai_key,
|
||||
type="password",
|
||||
key="openai_key",
|
||||
help="Enter your OpenAI API key"
|
||||
help="Enter your OpenAI API key",
|
||||
placeholder="Power your content generation with GPT-4 AI models"
|
||||
)
|
||||
|
||||
if openai_key:
|
||||
if validate_api_key(openai_key):
|
||||
st.success("✅ OpenAI API key found in environment")
|
||||
elif openai_input:
|
||||
if validate_api_key(openai_input):
|
||||
st.markdown("""
|
||||
<div class="ai-provider-status status-valid">
|
||||
✓ API key configured
|
||||
@@ -102,32 +136,23 @@ def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
|
||||
**Note:** Keep your API key secure and never share it publicly.
|
||||
""")
|
||||
|
||||
st.markdown("</div></div></div>", unsafe_allow_html=True)
|
||||
|
||||
with col2:
|
||||
# Google Card
|
||||
with st.container():
|
||||
st.markdown("""
|
||||
<div class="ai-provider-card">
|
||||
<div class="ai-provider-header">
|
||||
<div class="ai-provider-icon">🔍</div>
|
||||
<div class="ai-provider-title">Google Gemini</div>
|
||||
</div>
|
||||
<div class="ai-provider-content">
|
||||
<p>Leverage Google's powerful Gemini models</p>
|
||||
<div class="ai-provider-input">
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
google_key = st.text_input(
|
||||
"Google API Key",
|
||||
gemini_input = st.text_input(
|
||||
"Google Gemini API Key",
|
||||
value=gemini_key,
|
||||
type="password",
|
||||
key="google_key",
|
||||
help="Enter your Google API key"
|
||||
help="Enter your Google API key",
|
||||
placeholder="Power your content generation with Gemini AI models"
|
||||
)
|
||||
|
||||
if google_key:
|
||||
if validate_api_key(google_key):
|
||||
if gemini_key:
|
||||
st.success("✅ Gemini API key found in environment")
|
||||
elif gemini_input:
|
||||
if validate_api_key(gemini_input):
|
||||
st.markdown("""
|
||||
<div class="ai-provider-status status-valid">
|
||||
✓ API key configured
|
||||
@@ -150,8 +175,6 @@ def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
|
||||
**Note:** Make sure to enable the Gemini API in your Google Cloud Console.
|
||||
""")
|
||||
|
||||
st.markdown("</div></div></div>", unsafe_allow_html=True)
|
||||
|
||||
with tabs[1]:
|
||||
st.markdown("### Additional AI Providers")
|
||||
@@ -193,10 +216,10 @@ def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
st.info("Mistral integration will be available in the next update")
|
||||
|
||||
# Track changes and validate keys
|
||||
if any([openai_key, google_key]):
|
||||
if any([openai_input, gemini_input]):
|
||||
changes_made = True
|
||||
# Check if at least one valid API key is provided
|
||||
if validate_api_key(openai_key) or validate_api_key(google_key):
|
||||
if validate_api_key(openai_input) or validate_api_key(gemini_input):
|
||||
has_valid_key = True
|
||||
validation_message = "✅ At least one AI provider configured successfully"
|
||||
else:
|
||||
@@ -214,20 +237,33 @@ def render_ai_providers(api_key_manager: APIKeyManager) -> Dict[str, Any]:
|
||||
# Navigation buttons
|
||||
if render_navigation_buttons(1, 6, changes_made):
|
||||
if has_valid_key:
|
||||
# Store the API keys in a separate session state key
|
||||
st.session_state['api_keys'] = {
|
||||
'openai': openai_key if validate_api_key(openai_key) else None,
|
||||
'google': google_key if validate_api_key(google_key) else None
|
||||
}
|
||||
|
||||
# Save API keys to .env file
|
||||
if validate_api_key(openai_key):
|
||||
api_key_manager.save_api_key("openai", openai_key)
|
||||
logger.info("[render_ai_providers] OpenAI API key saved to .env file")
|
||||
if validate_api_key(openai_input):
|
||||
if save_to_env_file("OPENAI_API_KEY", openai_input):
|
||||
logger.info("[render_ai_providers] OpenAI API key saved to .env file")
|
||||
else:
|
||||
st.error("Failed to save OpenAI API key to .env file")
|
||||
return {"current_step": 1, "error": "Failed to save OpenAI API key"}
|
||||
|
||||
if validate_api_key(google_key):
|
||||
api_key_manager.save_api_key("gemini", google_key)
|
||||
logger.info("[render_ai_providers] Google Gemini API key saved to .env file")
|
||||
if validate_api_key(gemini_input):
|
||||
if save_to_env_file("GEMINI_API_KEY", gemini_input):
|
||||
logger.info("[render_ai_providers] Google Gemini API key saved to .env file")
|
||||
else:
|
||||
st.error("Failed to save Gemini API key to .env file")
|
||||
return {"current_step": 1, "error": "Failed to save Gemini API key"}
|
||||
|
||||
# Reload environment variables to ensure consistency
|
||||
load_dotenv(override=True)
|
||||
|
||||
# Get updated API keys from environment
|
||||
updated_openai_key = os.getenv('OPENAI_API_KEY', '')
|
||||
updated_gemini_key = os.getenv('GEMINI_API_KEY', '')
|
||||
|
||||
# Store the API keys in session state
|
||||
st.session_state['api_keys'] = {
|
||||
'openai': updated_openai_key,
|
||||
'google': updated_gemini_key
|
||||
}
|
||||
|
||||
# Update progress and move to next step
|
||||
st.session_state['current_step'] = 2 # Set the next step explicitly
|
||||
|
||||
Reference in New Issue
Block a user