Spaces:
Runtime error
Runtime error
Download app.py from arubaDev/models-with-dataset: direct link, hf CLI and curl.
- Browser
- Download file 19.6 kB
-
https://huggingface.co/spaces/arubaDev/models-with-dataset/resolve/main/app.py
- Command line
-
hf download hf://spaces/arubaDev/models-with-dataset/app.py
-
curl -L -o app.py https://huggingface.co/spaces/arubaDev/models-with-dataset/resolve/main/app.py
19.6 kB
| import os | |
| from datetime import datetime | |
| import gradio as gr | |
| from huggingface_hub import InferenceClient | |
| from datasets import load_dataset | |
| from supabase import create_client | |
| import threading | |
| import time | |
| # =========================== | |
| # Supabase Setup | |
| # =========================== | |
| SUPABASE_URL = os.getenv("SUPABASE_URL") | |
| SUPABASE_KEY = os.getenv("SUPABASE_KEY") | |
| if not SUPABASE_URL or not SUPABASE_KEY: | |
| raise ValueError("SUPABASE_URL and SUPABASE_KEY must be set in HF Secrets") | |
| supabase = create_client(SUPABASE_URL, SUPABASE_KEY) | |
| # =========================== | |
| # Global stop flag | |
| # =========================== | |
| stop_generation = False | |
| # =========================== | |
| # Config | |
| # =========================== | |
| MODELS = { | |
| "Meta LLaMA 3.1 (8B Instruct)": "meta-llama/Llama-3.1-8B-Instruct", | |
| "Mistral 7B Instruct": "mistralai/Mistral-7B-Instruct-v0.2", | |
| } | |
| DATASETS = ["The Stack", "CodeXGLUE"] | |
| HF_TOKEN = os.getenv("HF_TOKEN") | |
| SYSTEM_DEFAULT = ( | |
| "Specializes in databases, APIs, auth, CRUD. " | |
| "Provides complete backend code scaffolds. " | |
| "Declines frontend-heavy requests." | |
| ) | |
| # =========================== | |
| # Database Functions (Supabase) | |
| # =========================== | |
| def init_db(): | |
| pass # Tables must be created in Supabase dashboard | |
| def create_session(title: str = "New chat") -> int: | |
| res = supabase.table("sessions").insert({ | |
| "title": title, | |
| "created_at": datetime.utcnow().isoformat() | |
| }).execute() | |
| return res.data[0]["id"] | |
| def delete_session(session_id: int): | |
| supabase.table("messages").delete().eq("session_id", session_id).execute() | |
| supabase.table("sessions").delete().eq("id", session_id).execute() | |
| def list_sessions(): | |
| res = supabase.table("sessions").select("id,title").order("id", desc=True).execute() | |
| rows = res.data or [] | |
| labels = [f"{r['id']} • {r['title']}" for r in rows] | |
| return labels, rows | |
| def get_messages(session_id: int): | |
| res = supabase.table("messages") \ | |
| .select("role,content") \ | |
| .eq("session_id", session_id) \ | |
| .order("id", desc=False) \ | |
| .execute() | |
| rows = res.data or [] | |
| return [{"role": r["role"], "content": r["content"]} for r in rows] | |
| def add_message(session_id: int, role: str, content: str): | |
| print(f"🔍 ADDING MESSAGE - Session: {session_id}, Role: {role}") | |
| print(f"🔍 Content preview: {content[:50]}..." if len(content) > 50 else f"🔍 Content: {content}") | |
| supabase.table("messages").insert({ | |
| "session_id": session_id, | |
| "role": role, | |
| "content": content, | |
| "created_at": datetime.utcnow().isoformat() | |
| }).execute() | |
| print(f"✅ Message added successfully to session {session_id}") | |
| def update_session_title_if_needed(session_id: int, first_user_text: str): | |
| res = supabase.table("messages") \ | |
| .select("id") \ | |
| .eq("session_id", session_id) \ | |
| .eq("role", "user") \ | |
| .execute() | |
| if len(res.data) == 1: | |
| title = first_user_text.strip().split("\n")[0] | |
| title = (title[:50] + "…") if len(title) > 50 else title | |
| supabase.table("sessions") \ | |
| .update({"title": title or "New chat"}) \ | |
| .eq("id", session_id) \ | |
| .execute() | |
| def label_to_id(label: str | None) -> int | None: | |
| if not label: return None | |
| try: return int(label.split("•", 1)[0].strip()) | |
| except: return None | |
| def build_api_messages(session_id: int, system_message: str): | |
| msgs = [{"role": "system", "content": system_message.strip()}] | |
| msgs.extend(get_messages(session_id)) | |
| return msgs | |
| def get_client(model_choice: str): | |
| return InferenceClient(MODELS.get(model_choice, list(MODELS.values())[0]), token=HF_TOKEN) | |
| def load_dataset_by_name(name: str): | |
| if name == "The Stack": return load_dataset("bigcode/the-stack", split="train") | |
| if name == "CodeXGLUE": return load_dataset("google/code_x_glue_cc_code_to_code_trans", split="train") | |
| return None | |
| FRONTEND_KEYWORDS = ["react", "vue", "angular", "html", "css", "javascript", "tailwind", "recharts", "typescript"] | |
| def is_frontend_request(user_text: str) -> bool: | |
| return any(kw in user_text.lower() for kw in FRONTEND_KEYWORDS) | |
| # =========================== | |
| # Callbacks | |
| # =========================== | |
| def stop_generation_cb(): | |
| """Stop the current generation""" | |
| global stop_generation | |
| stop_generation = True | |
| return gr.update(visible=True), gr.update(visible=False) # Show send, hide stop | |
| def refresh_sessions_cb(): | |
| labels, _ = list_sessions() | |
| selected = labels[0] if labels else None | |
| visible = bool(selected) | |
| return ( | |
| gr.update(choices=labels, value=selected), | |
| gr.update(visible=False), # edit_title_box hidden | |
| gr.update(visible=visible), # rename_btn visible if session exists | |
| gr.update(visible=False), # save_title_btn hidden | |
| gr.update(visible=visible), # del_btn visible if session exists | |
| gr.update(visible=visible), # refresh_btn visible if session exists | |
| ) | |
| def new_chat_cb(): | |
| sid = create_session("New chat") | |
| labels, _ = list_sessions() | |
| selected = next((lbl for lbl in labels if lbl.startswith(f"{sid} ")), None) | |
| return ( | |
| gr.update(choices=labels, value=selected), | |
| [], "", # chatbot cleared, user box cleared | |
| gr.update(visible=False), # edit_title_box hidden | |
| gr.update(visible=True), # rename_btn visible | |
| gr.update(visible=False), # save_title_btn hidden | |
| gr.update(visible=True), # del_btn visible | |
| gr.update(visible=True), # refresh_btn visible | |
| gr.update(visible=True), # send_btn visible | |
| gr.update(visible=False) # stop_btn hidden | |
| ) | |
| def load_session_cb(selected_label): | |
| sid = label_to_id(selected_label) | |
| if not sid: | |
| return [], gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False) | |
| return ( | |
| get_messages(sid), | |
| gr.update(visible=False), # edit_title_box hidden initially | |
| gr.update(visible=True), # rename_btn visible | |
| gr.update(visible=False), # save_title_btn hidden | |
| gr.update(visible=True), # del_btn visible | |
| gr.update(visible=True), # refresh_btn visible | |
| gr.update(visible=True), # send_btn visible | |
| gr.update(visible=False) # stop_btn hidden | |
| ) | |
| def delete_chat_cb(selected_label): | |
| sid = label_to_id(selected_label) | |
| if sid: delete_session(sid) | |
| labels, _ = list_sessions() | |
| selected = labels[0] if labels else None | |
| visible = bool(selected) | |
| return ( | |
| gr.update(choices=labels, value=selected), | |
| [], # chatbot cleared | |
| gr.update(visible=False), # edit_title_box hidden | |
| gr.update(visible=visible), # rename_btn visible if sessions exist | |
| gr.update(visible=False), # save_title_btn hidden | |
| gr.update(visible=visible), # del_btn visible if sessions exist | |
| gr.update(visible=visible), # refresh_btn visible if sessions exist | |
| gr.update(visible=True), # send_btn visible | |
| gr.update(visible=False) # stop_btn hidden | |
| ) | |
| # --- New Rename Callbacks --- | |
| def start_rename_cb(): | |
| """Show the rename input box and save button, hide rename button""" | |
| return ( | |
| gr.update(visible=True), # edit_title_box visible | |
| gr.update(visible=False), # rename_btn hidden | |
| gr.update(visible=True) # save_title_btn visible | |
| ) | |
| def save_rename_cb(selected_label, new_title): | |
| """Save the new chat title to database""" | |
| sid = label_to_id(selected_label) | |
| if not sid or not new_title or not new_title.strip(): | |
| # If no valid title, just revert UI | |
| return ( | |
| gr.update(visible=False), # edit_title_box hidden | |
| gr.update(visible=True), # rename_btn visible | |
| gr.update(visible=False), # save_title_btn hidden | |
| gr.update() # session_list unchanged | |
| ) | |
| # Update the title in database | |
| supabase.table("sessions") \ | |
| .update({"title": new_title.strip()}) \ | |
| .eq("id", sid) \ | |
| .execute() | |
| # Refresh the session list | |
| labels, _ = list_sessions() | |
| selected = next((lbl for lbl in labels if lbl.startswith(f"{sid} ")), None) | |
| return ( | |
| gr.update(visible=False), # edit_title_box hidden | |
| gr.update(visible=True), # rename_btn visible | |
| gr.update(visible=False), # save_title_btn hidden | |
| gr.update(choices=labels, value=selected) # updated session list | |
| ) | |
| def cancel_rename_cb(): | |
| """Cancel rename operation (if user clicks away)""" | |
| return ( | |
| gr.update(visible=False), # edit_title_box hidden | |
| gr.update(visible=True), # rename_btn visible | |
| gr.update(visible=False) # save_title_btn hidden | |
| ) | |
| # --- Send with stop capability --- | |
| def send_cb(user_text, selected_label, chatbot_msgs, system_message, max_tokens, temperature, top_p, model_choice, dataset_choice, *args): | |
| global stop_generation | |
| stop_generation = False # Reset stop flag at start | |
| sid = label_to_id(selected_label) or create_session("New chat") | |
| add_message(sid, "user", user_text) | |
| update_session_title_if_needed(sid, user_text) | |
| display_msgs = chatbot_msgs[:] + [{"role": "user", "content": user_text}] | |
| # Check for frontend request | |
| if is_frontend_request(user_text): | |
| apology = "⚠️ I'm a backend-focused assistant and cannot provide frontend code." | |
| display_msgs.append({"role": "assistant", "content": apology}) | |
| add_message(sid, "assistant", apology) | |
| yield display_msgs, "", selected_label, gr.update(visible=True), gr.update(visible=False) | |
| return | |
| display_msgs.append({"role": "assistant", "content": "…"}) | |
| # Show stop button, hide send button | |
| yield display_msgs, "", selected_label, gr.update(visible=False), gr.update(visible=True) | |
| client = get_client(model_choice) | |
| api_messages = build_api_messages(sid, system_message) | |
| partial = "" | |
| try: | |
| for chunk in client.chat_completion( | |
| messages=api_messages, | |
| max_tokens=int(max_tokens), | |
| temperature=float(temperature), | |
| top_p=float(top_p), | |
| stream=True | |
| ): | |
| # Check if stop was requested | |
| if stop_generation: | |
| display_msgs[-1]["content"] = partial + "\n\n[Generation stopped by user]" | |
| yield display_msgs, "", selected_label, gr.update(visible=True), gr.update(visible=False) | |
| add_message(sid, "assistant", partial + "\n\n[Generation stopped by user]") | |
| return | |
| if not hasattr(chunk, "choices") or not chunk.choices: continue | |
| choice = chunk.choices[0] | |
| delta = getattr(getattr(choice, "delta", None), "content", None) or getattr(getattr(choice, "message", None), "content", None) or "" | |
| if delta: | |
| partial += delta | |
| display_msgs[-1]["content"] = partial | |
| yield display_msgs, "", selected_label, gr.update(visible=False), gr.update(visible=True) | |
| # Only add message if not stopped | |
| if not stop_generation: | |
| add_message(sid, "assistant", partial) | |
| yield display_msgs, "", selected_label, gr.update(visible=True), gr.update(visible=False) | |
| else: | |
| yield display_msgs, "", selected_label, gr.update(visible=True), gr.update(visible=False) | |
| except Exception as e: | |
| display_msgs[-1]["content"] = f"⚠️ Error: {e}" | |
| yield display_msgs, "", selected_label, gr.update(visible=True), gr.update(visible=False) | |
| # =========================== | |
| # Init | |
| # =========================== | |
| init_db() | |
| labels, _ = list_sessions() | |
| if not labels: | |
| create_session("New chat") | |
| labels, _ = list_sessions() | |
| default_selected = labels[0] if labels else None | |
| # =========================== | |
| # App UI (YOUR ORIGINAL UI WITH STOP BUTTON) | |
| # =========================== | |
| with gr.Blocks(title="Backend-Focused LLaMA/Mistral CRUD Assistant", theme=gr.themes.Soft()) as demo: | |
| # --- Custom CSS (your original CSS) --- | |
| gr.HTML(""" | |
| <style> | |
| /* ========== Compact section headings ========== */ | |
| .compact-heading h3 { | |
| font-size: 0.9rem !important; | |
| font-weight: 600 !important; | |
| margin: 0.3rem 0 !important; | |
| padding: 0 !important; | |
| } | |
| /* ========== Main top title smaller ========== */ | |
| .main-title h2 { | |
| font-size: 1.2rem !important; | |
| font-weight: 700 !important; | |
| margin-bottom: 0.6rem !important; | |
| } | |
| /* ========== Reduce spacing below sliders & dropdowns ========== */ | |
| .compact-sliders .gr-slider, | |
| .compact-sliders .gr-number, | |
| .compact-sliders .gr-dropdown { | |
| margin-bottom: 0.4rem !important; | |
| } | |
| /* ========== Compact the left panel column ========== */ | |
| .left-panel .gr-column { | |
| gap: 0.3rem !important; | |
| } | |
| /* ========== Tiny / pressed buttons ========== */ | |
| .tiny-btn .gr-button { | |
| font-size: 0.75rem !important; /* smaller text */ | |
| padding: 2px 6px !important; /* tight padding */ | |
| min-height: 24px !important; /* shorter button */ | |
| line-height: 1.1 !important; /* compact vertical spacing */ | |
| border-radius: 4px !important; /* slightly rounded */ | |
| } | |
| /* ========== Remove extra top/left page gaps ========== */ | |
| body, html { | |
| margin: 0 !important; | |
| padding: 0 !important; | |
| } | |
| .gradio-container { | |
| margin-top: -40px !important; /* was -10px, move up more */ | |
| margin-left: -40px !important; | |
| padding-top: 0 !important; | |
| padding-left: 0 !important; | |
| } | |
| .main-title, | |
| .gr-block:first-of-type { | |
| margin-top: -10px !important; /* was -5px, pull up further */ | |
| margin-left: -10 !important; | |
| padding-top: 0 !important; | |
| padding-left: 0 !important; | |
| } | |
| /* ========== Compact sliders: reduce vertical height and spacing ========== */ | |
| .compact-sliders .gr-slider { | |
| height: 28px !important; /* shorter track */ | |
| padding: 0 !important; /* remove inner padding */ | |
| margin-bottom: 0.3rem !important; /* less spacing below each slider */ | |
| } | |
| /* Compact slider label and value text */ | |
| .compact-sliders .gr-slider label, | |
| .compact-sliders .gr-slider span { | |
| font-size: 0.8rem !important; /* smaller text */ | |
| } | |
| /* Tighten the numeric input box on sliders */ | |
| .compact-sliders input[type="number"] { | |
| max-width: 70px !important; /* smaller numeric input width */ | |
| font-size: 0.8rem !important; | |
| padding: 2px 4px !important; | |
| } | |
| /* Stop button styling */ | |
| .stop-btn { | |
| background-color: #ff4444 !important; | |
| color: white !important; | |
| } | |
| .stop-btn:hover { | |
| background-color: #cc0000 !important; | |
| } | |
| </style> | |
| """) | |
| with gr.Row(equal_height=True): | |
| with gr.Column(scale=1, min_width=260): | |
| session_list = gr.Radio(choices=labels, value=default_selected, label="Your Chats", interactive=True) | |
| with gr.Row(elem_id="session-actions-row"): | |
| new_btn = gr.Button("New Chat") | |
| rename_btn = gr.Button("Rename", visible=bool(default_selected)) | |
| save_title_btn = gr.Button("Save", visible=False) | |
| del_btn = gr.Button("Delete", visible=bool(default_selected)) | |
| refresh_btn = gr.Button("Refresh", visible=bool(default_selected)) | |
| edit_title_box = gr.Textbox(label="Edit Chat Name", placeholder="Type new chat name…", visible=False) | |
| # Model selection | |
| model_choice = gr.Dropdown(choices=list(MODELS.keys()), value=list(MODELS.keys())[0], label="Choose a model", interactive=True) | |
| # Dataset selection | |
| dataset_choice = gr.Dropdown(choices=DATASETS, value=DATASETS[0], label="Select a dataset", interactive=True) | |
| # Generation settings | |
| with gr.Group(elem_classes="system-message-compact"): | |
| system_box = gr.Textbox(value=SYSTEM_DEFAULT, label="System message", lines=1) | |
| with gr.Group(elem_classes="compact-sliders"): | |
| max_tokens = gr.Slider(256, 4096, value=1200, step=16, label="Max tokens") | |
| temperature = gr.Slider(0.0, 2.0, value=0.25, step=0.05, label="Temperature") | |
| top_p = gr.Slider(0.1, 1.0, value=0.9, step=0.05, label="Top-p") | |
| with gr.Column(scale=3): | |
| chatbot = gr.Chatbot(label="Assistant", type="messages") | |
| with gr.Row(elem_classes="user-input-row"): | |
| user_box = gr.Textbox(placeholder="Describe your CRUD/backend task…", lines=3, scale=5) | |
| send_btn = gr.Button("▶️", variant="primary", scale=1, visible=True) | |
| stop_btn = gr.Button("⏹️", variant="stop", scale=1, visible=False, elem_classes="stop-btn") | |
| # --- Wire callbacks --- | |
| # Stop button | |
| stop_btn.click( | |
| stop_generation_cb, | |
| outputs=[send_btn, stop_btn] | |
| ) | |
| # Refresh button | |
| refresh_btn.click( | |
| refresh_sessions_cb, | |
| outputs=[session_list, edit_title_box, rename_btn, save_title_btn, del_btn, refresh_btn] | |
| ) | |
| # New chat button | |
| new_btn.click( | |
| new_chat_cb, | |
| outputs=[session_list, chatbot, user_box, edit_title_box, rename_btn, save_title_btn, del_btn, refresh_btn, send_btn, stop_btn] | |
| ) | |
| # Delete button | |
| del_btn.click( | |
| delete_chat_cb, | |
| inputs=session_list, | |
| outputs=[session_list, chatbot, edit_title_box, rename_btn, save_title_btn, del_btn, refresh_btn, send_btn, stop_btn] | |
| ) | |
| # Session selection change | |
| session_list.change( | |
| load_session_cb, | |
| inputs=session_list, | |
| outputs=[chatbot, edit_title_box, rename_btn, save_title_btn, del_btn, refresh_btn, send_btn, stop_btn] | |
| ) | |
| # Rename button - starts the rename process | |
| rename_btn.click( | |
| start_rename_cb, | |
| outputs=[edit_title_box, rename_btn, save_title_btn] | |
| ) | |
| # Save button - saves the new title | |
| save_title_btn.click( | |
| save_rename_cb, | |
| inputs=[session_list, edit_title_box], | |
| outputs=[edit_title_box, rename_btn, save_title_btn, session_list] | |
| ) | |
| # Pressing Enter in the rename box also saves | |
| edit_title_box.submit( | |
| save_rename_cb, | |
| inputs=[session_list, edit_title_box], | |
| outputs=[edit_title_box, rename_btn, save_title_btn, session_list] | |
| ) | |
| # Clicking away from the rename box (blur) cancels | |
| edit_title_box.blur( | |
| cancel_rename_cb, | |
| outputs=[edit_title_box, rename_btn, save_title_btn] | |
| ) | |
| # Send message | |
| send_btn.click( | |
| send_cb, | |
| inputs=[user_box, session_list, chatbot, system_box, max_tokens, temperature, top_p, model_choice, dataset_choice], | |
| outputs=[chatbot, user_box, session_list, send_btn, stop_btn] | |
| ) | |
| # Enter key in user box | |
| user_box.submit( | |
| send_cb, | |
| inputs=[user_box, session_list, chatbot, system_box, max_tokens, temperature, top_p, model_choice, dataset_choice], | |
| outputs=[chatbot, user_box, session_list, send_btn, stop_btn] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |