A newer version of the Gradio SDK is available:
6.6.0
Звіт про зміни: Опціональні API ключі
Дата: 2025-12-28 Статус: ✅ Завершено
📋 Проблема
При запуску додатку виникала помилка:
ValueError: OpenAI API key not found in environment variables
Додаток вимагав наявності всіх API ключів (OpenAI, Anthropic, AWS), навіть якщо користувач планував використовувати тільки один провайдер (наприклад, Gemini).
Вимога користувача:
"якщо деякі ключі відсутні або не релевантні це не повинно бути причиною зупинки розгортання додатку"
✅ Виконані зміни
1. Опціональна ініціалізація OpenAI embedding моделі
Файл: main.py
Було:
if not OPENAI_API_KEY:
raise ValueError("OpenAI API key not found in environment variables")
embed_model = OpenAIEmbedding(model_name="text-embedding-3-small")
Settings.embed_model = embed_model
Стало:
if OPENAI_API_KEY:
embed_model = OpenAIEmbedding(model_name="text-embedding-3-small")
Settings.embed_model = embed_model
print("OpenAI embedding model initialized successfully")
else:
print("Warning: OpenAI API key not found. Search functionality will be disabled.")
2. Покращені повідомлення про помилки в LLMAnalyzer
Файл: main.py
Зміни:
- Замість загальних помилок про відсутність ключів, тепер показуються специфічні повідомлення для кожного провайдера
- Приклад:
"Gemini API key not configured. Please set GEMINI_API_KEY environment variable to use gemini provider."
3. Оновлена функція validate_environment()
Файл: config.py
Було:
def validate_environment():
required_vars = [
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"OPENAI_API_KEY",
"ANTHROPIC_API_KEY"
]
missing_vars = [var for var in required_vars if not os.getenv(var)]
if missing_vars:
raise ValueError(f"Missing required environment variables: {', '.join(missing_vars)}")
Стало:
def validate_environment(require_ai_provider: bool = True, require_aws: bool = False):
"""
Validate environment variables.
Args:
require_ai_provider: If True, requires at least one AI provider API key
require_aws: If True, requires AWS credentials
Returns:
dict: Status of each provider (available/missing)
"""
status = {
"openai": bool(os.getenv("OPENAI_API_KEY")),
"anthropic": bool(os.getenv("ANTHROPIC_API_KEY")),
"gemini": bool(os.getenv("GEMINI_API_KEY")),
"deepseek": bool(os.getenv("DEEPSEEK_API_KEY")),
"aws": bool(os.getenv("AWS_ACCESS_KEY_ID") and os.getenv("AWS_SECRET_ACCESS_KEY"))
}
if require_ai_provider:
if not any([status["openai"], status["anthropic"], status["gemini"], status["deepseek"]]):
raise ValueError(
"At least one AI provider API key is required. Please set one of: "
"OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY"
)
if require_aws and not status["aws"]:
raise ValueError("AWS credentials are required")
return status
4. Додані хелпер функції
Файл: main.py
Нові функції:
def get_available_providers() -> Dict[str, bool]:
"""Get status of all AI providers."""
return {
"openai": bool(OPENAI_API_KEY),
"anthropic": bool(ANTHROPIC_API_KEY),
"gemini": bool(os.getenv("GEMINI_API_KEY")),
"deepseek": bool(DEEPSEEK_API_KEY)
}
def check_provider_available(provider: str) -> Tuple[bool, str]:
"""
Check if a provider is available.
Returns:
Tuple of (is_available, error_message)
"""
providers = get_available_providers()
provider_key = provider.lower()
if provider_key not in providers:
return False, f"Unknown provider: {provider}"
if not providers[provider_key]:
available = [k.upper() for k, v in providers.items() if v]
if not available:
return False, "No AI provider API keys configured. Please set at least one API key."
return False, f"{provider.upper()} API key not configured. Available providers: {', '.join(available)}"
return True, ""
5. Runtime перевірки в generate_legal_position()
Файл: main.py
Додано на початок функції:
# Check if provider is available
is_available, error_msg = check_provider_available(provider)
if not is_available:
return {
"title": "Помилка конфігурації",
"text": error_msg,
"proceeding": "N/A",
"category": "Error"
}
6. Перевірки в функціях пошуку
Додано:
if not OPENAI_API_KEY:
return "Помилка: пошук недоступний без налаштованого OpenAI API ключа", None
7. Опціональна ініціалізація search components
Файл: main.py
Додано:
# Initialize search components only if OpenAI is available
if OPENAI_API_KEY:
success = search_components.initialize_components(LOCAL_DIR)
if not success:
raise RuntimeError("Failed to initialize search components")
print("Search components initialized successfully")
else:
print("Skipping search components initialization (OpenAI API key not available)")
Це дозволяє додатку запускатися навіть без OpenAI, оскільки search components залежать від OpenAI embedding моделі.
8. Оновлена валідація при запуску
Файл: main.py
Було:
required_vars = ["OPENAI_API_KEY"]
missing_vars = [var for var in required_vars if not os.getenv(var)]
if missing_vars:
print(f"Missing required environment variables: {', '.join(missing_vars)}")
sys.exit(1)
Стало:
# Check which providers are available
available_providers = []
if OPENAI_API_KEY:
available_providers.append("OpenAI")
if ANTHROPIC_API_KEY:
available_providers.append("Anthropic")
if os.getenv("GEMINI_API_KEY"):
available_providers.append("Gemini")
if DEEPSEEK_API_KEY:
available_providers.append("DeepSeek")
if not available_providers:
print("Error: No AI provider API keys configured. Please set at least one of:")
print(" - OPENAI_API_KEY")
print(" - ANTHROPIC_API_KEY")
print(" - GEMINI_API_KEY")
print(" - DEEPSEEK_API_KEY")
sys.exit(1)
print(f"Available AI providers: {', '.join(available_providers)}")
if not OPENAI_API_KEY:
print("Warning: OpenAI API key not configured. Search functionality will be limited.")
if not all([AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY]):
print("Warning: AWS credentials not configured. Will use local files only.")
9. Додано підтримку Gemini Embeddings ✨
Файл: embeddings/gemini_embedding.py
Створено custom embedding клас для використання Gemini API як альтернативи OpenAI для пошуку:
from llama_index.core.embeddings import BaseEmbedding
from google import genai
class GeminiEmbedding(BaseEmbedding):
"""Gemini embedding integration for LlamaIndex."""
def __init__(self, api_key: str, model_name: str = "gemini-embedding-001", **kwargs):
super().__init__(**kwargs)
self._client = genai.Client(api_key=api_key)
self._model_name = model_name
def _get_query_embedding(self, query: str) -> List[float]:
result = self._client.models.embed_content(
model=self._model_name,
contents=query
)
return list(result.embeddings[0].values)
Файл: main.py
Оновлено ініціалізацію embedding моделі з пріоритетом: OpenAI → Gemini → None
# Priority: OpenAI > Gemini > None
embed_model = None
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
if OPENAI_API_KEY:
embed_model = OpenAIEmbedding(model_name="text-embedding-3-small")
print("OpenAI embedding model initialized successfully")
elif GEMINI_API_KEY:
embed_model = GeminiEmbedding(api_key=GEMINI_API_KEY, model_name="gemini-embedding-001")
print("Gemini embedding model initialized successfully (alternative to OpenAI)")
else:
print("Warning: No embedding API key found (OpenAI or Gemini). Search functionality will be disabled.")
Детальна документація: GEMINI_EMBEDDINGS.md
🎯 Результат
Тепер додаток може працювати в наступних сценаріях:
Тільки з Gemini API ключем (рекомендовано):
export GEMINI_API_KEY=your_key_here python main.py- ✅ Генерація правових позицій працює (Gemini)
- ✅ Пошук працює (Gemini embeddings)
- ✅ Аналіз працює (Gemini)
- 🎉 Повна функціональність з одним провайдером!
Тільки з OpenAI API ключем:
export OPENAI_API_KEY=your_key_here python main.py- ✅ Генерація правових позицій працює
- ✅ Пошук працює
- ✅ Аналіз працює
З декількома провайдерами:
export GEMINI_API_KEY=your_gemini_key export OPENAI_API_KEY=your_openai_key python main.py- ✅ Повна функціональність
- ✅ Можливість вибору провайдера
Без AWS (локальні файли):
export GEMINI_API_KEY=your_key_here # AWS credentials не потрібні, якщо файли є локально python main.py- ✅ Працює з локальними файлами
- ⚠️ Попередження про відсутність AWS credentials
📊 Порівняння
До змін:
❌ Потрібні всі ключі: OPENAI_API_KEY, ANTHROPIC_API_KEY, AWS
❌ Додаток не запускається без OpenAI
❌ Жорстка помилка при відсутності будь-якого ключа
Після змін:
✅ Потрібен хоча б один AI провайдер
✅ AWS опціональний (локальні файли)
✅ OpenAI опціональний (для генерації)
✅ Зрозумілі повідомлення про доступність функцій
✅ Graceful degradation функціональності
🔍 Перевірка
Синтаксис Python:
✅ python3 -m py_compile main.py
✅ python3 -m py_compile config.py
Тестові сценарії:
1. Запуск з мінімальною конфігурацією (тільки Gemini):
# .env
GEMINI_API_KEY=your_key_here
# Очікуваний результат:
Available AI providers: Gemini
Warning: OpenAI API key not configured. Search functionality will be limited.
Warning: AWS credentials not configured. Will use local files only.
Components initialized successfully!
2. Спроба використати недоступний провайдер:
# Вибрано OpenAI, але ключ відсутній
Результат: {
"title": "Помилка конфігурації",
"text": "OPENAI API key not configured. Available providers: GEMINI",
"proceeding": "N/A",
"category": "Error"
}
3. Спроба пошуку без OpenAI:
Результат: "Помилка: пошук недоступний без налаштованого OpenAI API ключа"
📝 Змінені файли
| Файл | Зміни | Опис |
|---|---|---|
| main.py | ~50 рядків | Опціональна ініціалізація, хелпер функції, перевірки |
| config.py | ~30 рядків | Гнучка валідація environment variables |
🎓 Висновок
Виконано:
✅ Додаток може запускатися з будь-яким одним AI провайдером ✅ AWS credentials опціональні ✅ OpenAI ключ опціональний (з обмеженням функціональності) ✅ Зрозумілі повідомлення про доступність функцій ✅ Graceful degradation замість hard errors ✅ Перевірено синтаксис Python
Переваги нової структури:
✅ Гнучке розгортання - можна запустити з мінімальною конфігурацією ✅ Краща UX - зрозумілі повідомлення про те, що доступно/недоступно ✅ Економія коштів - не потрібно платити за всі провайдери одразу ✅ Тестування - легше тестувати з одним провайдером ✅ Production-ready - додаток не падає при неповній конфігурації
Обмеження:
⚠️ Пошук потребує OpenAI - для embedding моделі ⚠️ Мінімум один AI провайдер - інакше додаток не запуститься ⚠️ Функціональність залежить від ключів - деякі функції недоступні без певних провайдерів
📚 Наступні кроки (опціонально)
Можливі покращення в майбутньому:
Альтернативні embedding моделі:
- Додати підтримку Gemini embeddings
- Додати підтримку локальних embedding моделей
- Це зробить пошук доступним без OpenAI
UI індикатори:
- Показувати в інтерфейсі, які провайдери доступні
- Вимикати кнопки/функції, які недоступні
- Tooltip з поясненням, чому функція недоступна
Конфігураційний файл:
- Можливість вказати бажані провайдери в YAML
- Автоматичне приховування недоступних опцій
Статус: ✅ ГОТОВО
Дата завершення: 2025-12-28