/
Hodeika
/
intro-practice
Обзор
Документация
Войти
/
Hodeika
/
intro-practice
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
app.py
312 строк
12 KB
Michael Khodeev
Финальная версия: 3 сервиса, кэш SQLite, дизайн с AI-баннером
08 июл 2026, 13:43
08 июл 2026, 13:43
6f43059
Код
Авторство
О чём код?
from flask import Flask, request, session, render_template import importlib.util from pathlib import Path app = Flask(__name__) app.secret_key = "instacart-demo-secret-key" BASE_DIR = Path(__file__).parent def load_business_rules(): py_path = BASE_DIR / "business-rules.py" if not py_path.exists(): raise FileNotFoundError("Не найден business-rules.py.") spec = importlib.util.spec_from_file_location("business-rules", py_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module # ========== ГЛАВНАЯ СТРАНИЦА ========== @app.route("/", methods=["GET"]) def index(): startup_error = None if not (BASE_DIR / "business-rules.py").exists(): startup_error = "Файл business-rules.py не найден." return render_template( "index.html", user_id=session.get("user_id"), products=None, prompt_text=None, recommendation=None, from_cache=False, error=startup_error, ) # ========== АВТОРИЗАЦИЯ ========== @app.route("/login", methods=["POST"]) def login(): user_id = request.form.get("user_id", "").strip() if not user_id.isdigit(): return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error="user_id должен быть целым числом", ) user_id_int = int(user_id) if user_id_int <= 0 or user_id_int > 1000000: return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error="user_id должен быть числом от 1 до 1000000", ) try: rules = load_business_rules() if not rules.check_user_exists(user_id_int): return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error=f"Пользователь с user_id={user_id_int} не найден в базе.", ) except Exception as e: return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error=f"Ошибка при проверке пользователя: {e}", ) session["user_id"] = user_id_int return render_template( "index.html", user_id=session.get("user_id"), products=None, prompt_text=None, recommendation=None, from_cache=False, error=None, ) # ========== ВЫХОД ========== @app.route("/logout", methods=["GET", "POST"]) def logout(): session.clear() return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error=None, ) # ========== ИСТОРИЯ ПОКУПОК ========== @app.route("/history", methods=["POST"]) def history(): user_id = session.get("user_id") if not user_id: return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error="Сначала авторизуйтесь по user_id", ) try: rules = load_business_rules() rows = rules.get_user_history(user_id) products_text = rules.build_products_text(rows) prompt_text, recommendation = rules.ask_gigachat(user_id, products_text) # Проверяем, был ли ответ взят из кэша from_cache = rules.get_cached_response(user_id, "history") is not None and recommendation == rules.get_cached_response(user_id, "history") return render_template( "index.html", user_id=user_id, products=rows, prompt_text=prompt_text, recommendation=recommendation, from_cache=from_cache, error=None, ) except Exception as e: return render_template( "index.html", user_id=user_id, products=None, prompt_text=None, recommendation=None, from_cache=False, error=f"Ошибка: {e}", ) # ========== СТРАНИЦА АНАЛИТИКИ ========== @app.route("/insights", methods=["GET"]) def insights(): user_id = session.get("user_id") if not user_id: return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error="Сначала авторизуйтесь по user_id", ) return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=False, error=None, ) # ========== СЕРВИС 1: ЗАБЫТЫЕ ТОВАРЫ ========== @app.route("/forgotten", methods=["POST"]) def forgotten(): user_id = session.get("user_id") if not user_id: return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error="Сначала авторизуйтесь по user_id", ) try: rules = load_business_rules() rows = rules.get_forgotten_products(user_id) if not rows: return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=False, error="Нет забытых товаров для этого пользователя", ) products_text = rules.build_forgotten_text(rows) prompt_text, recommendation = rules.ask_gigachat_forgotten(user_id, products_text) from_cache = rules.get_cached_response(user_id, "forgotten") is not None return render_template( "insights.html", user_id=user_id, forgotten_products=rows, forgotten_recommendation=recommendation, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=from_cache, error=None, ) except Exception as e: return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=False, error=f"Ошибка при получении забытых товаров: {e}", ) # ========== СЕРВИС 2: ЛЮБИМЫЕ КАТЕГОРИИ ========== @app.route("/categories", methods=["POST"]) def categories(): user_id = session.get("user_id") if not user_id: return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error="Сначала авторизуйтесь по user_id", ) try: rules = load_business_rules() rows = rules.get_favorite_categories(user_id) if not rows: return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=False, error="Нет данных о категориях для этого пользователя", ) categories_text = rules.build_categories_text(rows) prompt_text, recommendation = rules.ask_gigachat_categories(user_id, categories_text) categories = [row["department_rus"] for row in rows] counts = [row["purchase_count"] for row in rows] from_cache = rules.get_cached_response(user_id, "categories") is not None return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=categories, counts=counts, categories_recommendation=recommendation, level_text=None, loyalty_recommendation=None, from_cache=from_cache, error=None, ) except Exception as e: return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=False, error=f"Ошибка при получении категорий: {e}", ) # ========== СЕРВИС 3: УРОВЕНЬ ЛОЯЛЬНОСТИ ========== @app.route("/loyalty", methods=["POST"]) def loyalty(): user_id = session.get("user_id") if not user_id: return render_template( "index.html", user_id=None, products=None, prompt_text=None, recommendation=None, from_cache=False, error="Сначала авторизуйтесь по user_id", ) try: rules = load_business_rules() rows = rules.get_customer_level(user_id) if not rows: return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=False, error="Нет данных о лояльности для этого пользователя", ) level_text = rules.build_customer_level_text(rows) prompt_text, recommendation = rules.ask_gigachat_loyalty(user_id, level_text) from_cache = rules.get_cached_response(user_id, "loyalty") is not None return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=level_text, loyalty_recommendation=recommendation, from_cache=from_cache, error=None, ) except Exception as e: return render_template( "insights.html", user_id=user_id, forgotten_products=None, forgotten_recommendation=None, categories=None, counts=None, categories_recommendation=None, level_text=None, loyalty_recommendation=None, from_cache=False, error=f"Ошибка при получении уровня лояльности: {e}", ) # ========== ЗАПУСК ПРИЛОЖЕНИЯ ========== if __name__ == "__main__": import os port = int(os.environ.get("PORT", 8000)) app.run(host="0.0.0.0", port=port)