/
Soldier327
/
API_INTERFACE
Обзор
Документация
Войти
/
Soldier327
/
API_INTERFACE
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
streamlit_app.py
181 строка
8 KB
Soldier-327
Initial commit: add shopping list generator with Streamlit UI
27 май 2026, 18:21
27 май 2026, 18:21
8fa6c09
Код
Авторство
О чём код?
"""Streamlit приложение для генерации списка покупок.""" import streamlit as st from llm import ShoppingListGenerator import os from dotenv import load_dotenv # Загружаем переменные окружения из .env файла load_dotenv() # Конфигурация страницы st.set_page_config( page_title="Генератор списка покупок", page_icon="🛒", layout="wide" ) # Заголовок st.title("🛒 Генератор списка покупок") st.markdown("На основе вашего запроса создам список продуктов для приготовления блюда.") # Инициализация состояния сессии if "api_key" not in st.session_state: # Пытаемся загрузить ключ из переменной окружения env_api_key = os.getenv("API_KEY") st.session_state.api_key = env_api_key if env_api_key else None # Боковая панель для API ключа with st.sidebar: st.header("🔧 Настройки") # Поле ввода API ключа (всегда показываем) api_key_input = st.text_input( "API ключ:", type="password", placeholder="sk-... или ваш ключ", help="Введите API ключ для доступа к модели" ) # Если пользователь ввёл ключ, сохраняем его в сессию if api_key_input: st.session_state.api_key = api_key_input st.success("✅ Ключ сохранён") # Если ключа нет в сессии, но он был в .env elif st.session_state.api_key: st.info("✅ Ключ загружен из .env файла") else: st.warning("🔑 API ключ не найден. Введите ключ или добавьте в .env файл.") st.markdown("---") st.caption("Поддерживаются OpenAI совместимые API") # Дополнительные настройки API default_api_url = os.getenv("API_URL", "https://api.openai.com/v1/chat/completions") api_url = st.text_input( "URL API (опционально):", value=default_api_url, help="Измените, если используете другой API" ) # Основной интерфейс col1, col2 = st.columns([2, 1]) with col1: # Поле ввода блюда dish_input = st.text_area( "📝 Что хотите приготовить?", height=120, placeholder="Примеры:\n• Паста карбонара\n• Овощное рагу с курицей\n• Шоколадный торт" ) # Отображение длины текста if dish_input: st.caption(f"Длина текста: {len(dish_input)} символов") with col2: # Количество персон people_count = st.selectbox( "👥 Количество персон:", options=["1", "2", "3", "4", "5", "6", "7", "8"], index=3 ) # Формат ответа format_type = st.radio( "📋 Формат ответа:", options=["Только список", "Список + шаги"], index=0 ) # Кнопка генерации generate_button = st.button("🛒 Сгенерировать список покупок", type="primary", use_container_width=True) # Обработка нажатия кнопки if generate_button: # ========== ПРОВЕРКА ВВОДА (ДО ВЫЗОВА API) ========== # Проверка 1: пустой ввод if not dish_input or dish_input.strip() == "": st.warning("📝 Напишите, что хотите приготовить.") # Проверка 2: слишком длинный ввод (порог 500 символов) elif len(dish_input) > 500: st.warning("📏 Слишком длинный текст — сократите или разбейте на части.") # Проверка 3: API ключ elif not st.session_state.api_key: st.error("🔑 Добавьте API ключ в боковой панели.") else: # ========== ВЫЗОВ ОБРАБОТЧИКА API ========== try: # Создаём экземпляр генератора generator = ShoppingListGenerator( api_key=st.session_state.api_key, api_url=api_url ) # Вызов с индикатором загрузки with st.spinner("🧠 Генерируем список покупок..."): result = generator.generate_with_retry( dish=dish_input, people=people_count, format_type=format_type, max_retries=1 ) # ========== ВЫВОД РЕЗУЛЬТАТА ========== st.markdown("---") st.subheader("✨ Результат:") # Проверяем, является ли результат ошибкой error_prefixes = ("🔒", "📊", "⚠️", "🔧", "⏰", "🌐", "📄", "❌") if result.startswith(error_prefixes): st.error(result) else: # Успешный результат if format_type == "Только список": st.success("📋 Ваш список покупок:") st.markdown(result) else: st.success("🍳 Рецепт и список покупок:") # Пытаемся разделить список и шаги для красивого отображения if "🍳 Шаги приготовления:" in result: parts = result.split("🍳 Шаги приготовления:") st.markdown("**📋 Список продуктов:**") st.markdown(parts[0].strip()) st.markdown("---") st.markdown("**🍳 Шаги приготовления:**") st.markdown("🍳 " + parts[1].strip()) else: st.markdown(result) except Exception as e: # Последний рубеж: любая непредвиденная ошибка st.error("❌ Произошла ошибка. Попробуйте позже.") # Логируем в консоль для отладки (не показываем пользователю) print(f"Неожиданная ошибка: {e}") # Справка with st.expander("ℹ️ Инструкция и ограничения"): st.markdown(""" ### Как пользоваться: 1. Введите блюдо, которое хотите приготовить 2. Выберите количество персон (пропорции будут скорректированы) 3. Выберите формат ответа: только список продуктов или список + шаги приготовления 4. Введите API ключ в боковой панели 5. Нажмите «Сгенерировать список покупок» ### Ограничения: - **Максимальная длина запроса:** 500 символов - Пустые запросы не обрабатываются - При ошибках API вы увидите понятное сообщение без технических деталей ### Возможные ошибки: - **🔒 Не настроен доступ** — проверьте API ключ - **🔧 Сервис недоступен** — проблема на стороне сервера, попробуйте позже - **⏰ Таймаут** — проверьте интернет-соединение """)