import warnings warnings.filterwarnings("ignore") import gradio as gr import pandas as pd import numpy as np import os import json from sentence_transformers import SentenceTransformer from sklearn.linear_model import LogisticRegression from huggingface_hub import InferenceClient, hf_hub_download # ============================================ # 1. Load Dataset from HuggingFace # ============================================ print("Loading dataset from HuggingFace...") csv_path = hf_hub_download( repo_id="adigabay2003/smartchef-recipes", filename="smartchef_dataset.csv", repo_type="dataset" ) df = pd.read_csv(csv_path) df = df.dropna(subset=["text"]) df = df[df["text"].str.strip() != ""] df = df.reset_index(drop=True) print(f"Loaded {len(df)} recipes") # ============================================ # 2. Load Optimal Model from JSON # ============================================ with open("optimal_model.json", "r") as f: optimal = json.load(f) MODEL_NAME = optimal["model_name"] print(f"Using embedding model: {MODEL_NAME}") # ============================================ # 3. Load Precomputed Embeddings # ============================================ print("Loading precomputed embeddings...") X = np.load("best_embeddings.npy") y = df["vibe"].tolist() print(f"Embeddings shape: {X.shape}") # ============================================ # 4. Train Classifier on Embeddings # ============================================ print("Training classifier...") embedder = SentenceTransformer(MODEL_NAME) clf = LogisticRegression(max_iter=1000) clf.fit(X, y) print("Classifier ready!") # ============================================ # 5. Prediction Function # ============================================ def get_recipe_vibe(title, ingredients): text = f"{title}. Ingredients: {ingredients}" embedding = embedder.encode([text]) vibe = clf.predict(embedding)[0] return vibe # ============================================ # 6. Image Generation # ============================================ def generate_food_image(title, vibe): token = os.getenv("HF_TOKEN") if not token: return None client = InferenceClient( model="stabilityai/stable-diffusion-xl-base-1.0", token=token ) prompt = ( f"Professional food photography of {title}, " f"{vibe} style, 4k, highly detailed, " f"appetizing, dramatic lighting, vibrant colors" ) try: return client.text_to_image(prompt) except: return None # ============================================ # 7. Main App Function # ============================================ def smart_chef_app(title, ingredients): vibe = get_recipe_vibe(title, ingredients) messages = { "Romantic": "🌹 Love is in the air!", "Quick Lunch": "⚡ Fast & Delicious!", "Comfort Food": "🧸 Warm & Cozy.", "Party Snack": "🎉 Party Time!", "Healthy Boost":"🥗 Feel Good Food.", "Fancy Dinner": "🍷 Chef's Kiss!" } msg = messages.get(vibe, "Yum!") img = generate_food_image(title, vibe) return vibe, msg, img # ============================================ # 8. CSS & Theme # ============================================ ultra_css = """ @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;500;800&display=swap'); .gradio-container { background: linear-gradient(-45deg, #0f0c29, #302b63, #24243e, #4a1c1c); background-size: 400% 400%; animation: gradientBG 15s ease infinite; font-family: 'Montserrat', sans-serif !important; } @keyframes gradientBG { 0% {background-position: 0% 50%;} 50% {background-position: 100% 50%;} 100% {background-position: 0% 50%;} } h1 { background: linear-gradient(to right, #ffcc00, #ff6600, #ff3300); -webkit-background-clip: text; -webkit-text-fill-color: transparent; text-shadow: 0px 0px 15px rgba(255, 102, 0, 0.6); font-weight: 800 !important; text-align: center; font-size: 3.5em !important; margin-bottom: 10px !important; } h3 { color: #e0e0e0 !important; text-align: center; font-weight: 300; } .group-container { background: rgba(255, 255, 255, 0.03); backdrop-filter: blur(20px); border-radius: 25px; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.5); padding: 30px !important; transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } .group-container:hover { transform: translateY(-10px) scale(1.02); border: 1px solid rgba(255, 204, 0, 0.4); box-shadow: 0 20px 50px rgba(255, 102, 0, 0.3); } button.primary-btn { background: linear-gradient(135deg, #ffcc00, #ff6600) !important; border: none !important; color: #000 !important; font-weight: 800 !important; font-size: 1.3em !important; padding: 15px 30px !important; animation: pulse 2s infinite; } @keyframes pulse { 0% {box-shadow: 0 0 0 0 rgba(255, 102, 0, 0.7);} 70% {box-shadow: 0 0 0 15px rgba(255, 102, 0, 0);} 100% {box-shadow: 0 0 0 0 rgba(255, 102, 0, 0);} } label { color: #ffcc00 !important; font-weight: 600 !important; } span { color: #e0e0e0 !important; } textarea, input { background-color: rgba(0,0,0,0.4) !important; border: 1px solid rgba(255,255,255,0.1) !important; color: white !important; } .gradio-container > * { animation: fadeUp 0.8s ease-out forwards; opacity: 0; } @keyframes fadeUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } """ theme = gr.themes.Soft(primary_hue="orange", neutral_hue="slate").set( body_background_fill="#000000", block_background_fill="#121212", block_border_width="0px" ) # ============================================ # 9. Gradio UI # ============================================ with gr.Blocks(css=ultra_css, theme=theme) as demo: gr.Markdown("# ✨ SMARTCHEF AI ✨") gr.Markdown("### Experience the future of culinary magic.") with gr.Row(): with gr.Column(elem_classes="group-container"): gr.Markdown("#### 📝 CREATE YOUR DISH") t_in = gr.Textbox( label="Dish Name", placeholder="e.g., Mystical Truffle Risotto" ) i_in = gr.Textbox( label="Ingredients", placeholder="e.g., Arborio rice, black truffle dust, parmesan...", lines=4 ) btn = gr.Button("✨ UNLEASH MAGIC ✨", elem_classes="primary-btn") with gr.Column(elem_classes="group-container"): gr.Markdown("#### 🔮 THE REVELATION") v_out = gr.Textbox( label="Vibe Detected", interactive=False ) m_out = gr.Markdown() im_out = gr.Image( label="AI Visualization", type="pil", interactive=False ) gr.Markdown("### ⚡ Instant Inspirations (Click to try):") gr.Examples( examples=[ ["Midnight Burger", "Black bun, wagyu beef, spicy aioli, caramelized onions"], ["Neon Sushi Roll", "Tuna, salmon, avocado, glowing tobiko, eel sauce"], ["Enchanted Forest Salad", "Kale, edible flowers, berries, nuts, fairy dust dressing"] ], inputs=[t_in, i_in], elem_id="examples-table" ) btn.click(smart_chef_app, [t_in, i_in], [v_out, m_out, im_out]) if __name__ == "__main__": demo.launch()