| | import gradio as gr |
| | import os |
| | from groq import Groq |
| |
|
| | api_key = os.getenv("GROQ_API_KEY") |
| | client = Groq(api_key=api_key) |
| |
|
| | conversation_history = [] |
| |
|
| | def chat_with_bot_stream(user_input): |
| | global conversation_history |
| | conversation_history.append({"role": "user", "content": user_input}) |
| | |
| | if len(conversation_history) == 1: |
| | conversation_history.insert(0, { |
| | "role": "system", |
| | "content": ( |
| | "You are a music and genre recommendation bot designed to help users discover new music " |
| | "based on their preferences, mood, or activity.\n\nYour responses should be engaging, " |
| | "personalized, and insightful. You can recommend:\n\n- Specific songs, albums, or artists\n" |
| | "- Genres based on mood, activity, or past preferences\n- Hidden gems and deep cuts " |
| | "for music enthusiasts\n- Trending or classic hits based on user taste\n\nBe conversational, " |
| | "suggest multiple options when possible, and encourage users to explore new sounds. " |
| | "If requested, provide brief descriptions of artists or genres, and explain why a " |
| | "recommendation might suit the user." |
| | ) |
| | }) |
| | |
| | completion = client.chat.completions.create( |
| | model="llama3-70b-8192", |
| | messages=conversation_history, |
| | temperature=1, |
| | max_tokens=1024, |
| | top_p=1, |
| | stream=True, |
| | ) |
| | |
| | response_content = "" |
| | for chunk in completion: |
| | response_content += chunk.choices[0].delta.content or "" |
| | |
| | conversation_history.append({"role": "assistant", "content": response_content}) |
| | |
| | return [ |
| | (msg["content"] if msg["role"] == "user" else None, |
| | msg["content"] if msg["role"] == "assistant" else None) |
| | for msg in conversation_history |
| | ] |
| |
|
| | |
| | translations = { |
| | "English": { |
| | "header_description": "Your own personal music discovery assistant!", |
| | "user_input_placeholder": "Enter your music-related questions here!", |
| | "send_button": "Send", |
| | "settings_markdown": "### Settings", |
| | "apply_settings_button": "Apply Settings", |
| | "select_language_label": "🌐 Language", |
| | "theme_label": "Theme", |
| | "theme_choices": ["Dark", "Light"], |
| | "font_size_label": "Font Size", |
| | "font_size_choices": ["Small", "Medium", "Large"], |
| | "language_choices": ["English", "Spanish", "French"] |
| | }, |
| | "Spanish": { |
| | "header_description": "¡Tu asistente personal para descubrir música!", |
| | "user_input_placeholder": "¡Introduce tus preguntas relacionadas con la música!", |
| | "send_button": "Enviar", |
| | "settings_markdown": "### Configuración", |
| | "apply_settings_button": "Aplicar Configuración", |
| | "select_language_label": "🌐 Idioma", |
| | "theme_label": "Tema", |
| | "theme_choices": ["Oscuro", "Claro"], |
| | "font_size_label": "Tamaño de Fuente", |
| | "font_size_choices": ["Pequeño", "Mediano", "Grande"], |
| | "language_choices": ["Inglés", "Español", "Francés"] |
| | }, |
| | "French": { |
| | "header_description": "Votre assistant personnel pour découvrir de la musique !", |
| | "user_input_placeholder": "Entrez vos questions sur la musique ici !", |
| | "send_button": "Envoyer", |
| | "settings_markdown": "### Paramètres", |
| | "apply_settings_button": "Appliquer les paramètres", |
| | "select_language_label": "🌐 Langue", |
| | "theme_label": "Thème", |
| | "theme_choices": ["Sombre", "Clair"], |
| | "font_size_label": "Taille de police", |
| | "font_size_choices": ["Petit", "Moyen", "Grand"], |
| | "language_choices": ["Anglais", "Espagnol", "Français"] |
| | } |
| | } |
| |
|
| | |
| | english_to_spanish_theme = {"Dark": "Oscuro", "Light": "Claro"} |
| | spanish_to_english_theme = {"Oscuro": "Dark", "Claro": "Light"} |
| | english_to_french_theme = {"Dark": "Sombre", "Light": "Clair"} |
| | french_to_english_theme = {"Sombre": "Dark", "Clair": "Light"} |
| |
|
| | english_to_spanish_font = {"Small": "Pequeño", "Medium": "Mediano", "Large": "Grande"} |
| | spanish_to_english_font = {"Pequeño": "Small", "Mediano": "Medium", "Grande": "Large"} |
| | english_to_french_font = {"Small": "Petit", "Medium": "Moyen", "Large": "Grand"} |
| | french_to_english_font = {"Petit": "Small", "Moyen": "Medium", "Grand": "Large"} |
| |
|
| | |
| | def normalize_language(lang): |
| | if lang in ["English", "Inglés", "Anglais"]: |
| | return "English" |
| | elif lang in ["Spanish", "Español", "Espagnol"]: |
| | return "Spanish" |
| | elif lang in ["French", "Français"]: |
| | return "French" |
| | else: |
| | return "English" |
| |
|
| | def update_all_settings(theme, font_size, language): |
| | target_lang = normalize_language(language) |
| | t = translations[target_lang] |
| | |
| | if target_lang == "Spanish": |
| | theme_for_ui = english_to_spanish_theme.get(theme, theme) if theme in english_to_spanish_theme else theme if theme in spanish_to_english_theme else "Oscuro" |
| | elif target_lang == "French": |
| | theme_for_ui = english_to_french_theme.get(theme, theme) if theme in english_to_french_theme else theme if theme in french_to_english_theme else "Sombre" |
| | else: |
| | theme_for_ui = spanish_to_english_theme.get(theme, theme) if theme in spanish_to_english_theme else theme if theme in english_to_spanish_theme else "Dark" |
| | |
| | if target_lang == "Spanish": |
| | font_for_ui = english_to_spanish_font.get(font_size, font_size) if font_size in english_to_spanish_font else font_size if font_size in spanish_to_english_font else "Mediano" |
| | elif target_lang == "French": |
| | font_for_ui = english_to_french_font.get(font_size, font_size) if font_size in english_to_french_font else font_size if font_size in french_to_english_font else "Moyen" |
| | else: |
| | font_for_ui = spanish_to_english_font.get(font_size, font_size) if font_size in spanish_to_english_font else font_size if theme in english_to_spanish_font else "Medium" |
| | |
| | if theme in ["Dark", "Light"]: |
| | theme_for_style = theme |
| | elif theme in spanish_to_english_theme: |
| | theme_for_style = spanish_to_english_theme.get(theme, "Dark") |
| | elif theme in french_to_english_theme: |
| | theme_for_style = french_to_english_theme.get(theme, "Dark") |
| | else: |
| | theme_for_style = "Dark" |
| | |
| | if font_size in ["Small", "Medium", "Large"]: |
| | font_for_style = font_size |
| | elif font_size in spanish_to_english_font: |
| | font_for_style = spanish_to_english_font.get(font_size, "Medium") |
| | elif font_size in french_to_english_font: |
| | font_for_style = french_to_english_font.get(font_size, "Medium") |
| | else: |
| | font_for_style = "Medium" |
| | |
| | dynamic_style = update_styles(theme_for_style, font_for_style) |
| | |
| | |
| | if target_lang == "English": |
| | language_value = "English" |
| | elif target_lang == "Spanish": |
| | language_value = "Español" |
| | elif target_lang == "French": |
| | language_value = "Français" |
| | header_html = f'<p id="header_description">{t["header_description"]}</p>' |
| | |
| | return ( |
| | dynamic_style, |
| | gr.update(value=header_html), |
| | gr.update(placeholder=t["user_input_placeholder"]), |
| | gr.update(value=t["send_button"]), |
| | gr.update(value=t["settings_markdown"]), |
| | gr.update(value=t["apply_settings_button"]), |
| | gr.update(label=t["theme_label"], choices=t["theme_choices"], value=theme_for_ui), |
| | gr.update(label=t["font_size_label"], choices=t["font_size_choices"], value=font_for_ui), |
| | gr.update(label=t["select_language_label"], choices=t["language_choices"], value=language_value) |
| | ) |
| |
|
| |
|
| | |
| | def update_styles(theme, font_size): |
| | if theme == "Dark": |
| | bg = "#18181B" |
| | text_color = "#ffffff" |
| | input_bg = "#AFA79F" |
| | button_bg = "#56246B" |
| | settings_box_bg = "#555555" |
| | apply_button_bg = "#666666" |
| | radio_bg = "#555555" |
| | settings_heading_color = text_color |
| | else: |
| | bg = "#ffffff" |
| | text_color = "#000000" |
| | input_bg = "#f2f2f2" |
| | button_bg = "#dddddd" |
| | settings_box_bg = "#eeeeee" |
| | apply_button_bg = "#e0e0e0" |
| | radio_bg = "#e0e0e0" |
| | settings_heading_color = "#333333" |
| | |
| | |
| | if font_size == "Small": |
| | fsize = "0.8rem" |
| | tab_padding = "4px 8px" |
| | elif font_size == "Medium": |
| | fsize = "1.2rem" |
| | tab_padding = "6px 12px" |
| | elif font_size == "Large": |
| | fsize = "1.8rem" |
| | tab_padding = "8px 16px" |
| | else: |
| | fsize = "1rem" |
| | tab_padding = "5px 10px" |
| | |
| | style = f""" |
| | <style id="dynamic_styles"> |
| | |
| | body, .gradio-container {{ |
| | background-color: {bg} !important; |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | #header_description {{ |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | #chatbot {{ |
| | background-color: {button_bg} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | #chatbot .chatbot-message, |
| | #chatbot .message {{ |
| | background-color: {button_bg} !important; |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | #user_input {{ |
| | background-color: {button_bg} !important; |
| | }} |
| | #user_input textarea {{ |
| | background-color: {input_bg} !important; |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | #user_input textarea::placeholder {{ |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | #send_button {{ |
| | background-color: {button_bg} !important; |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | #settings_box {{ |
| | background-color: {settings_box_bg} !important; |
| | padding: 10px; |
| | border-radius: 8px; |
| | font-size: {fsize} !important; |
| | }} |
| | #settings_box .gr-markdown h3 {{ |
| | color: {settings_heading_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | #settings_box .gr-radio-group, |
| | #settings_box .gr-radio-group * {{ |
| | background-color: {radio_bg} !important; |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | /* Apply Settings button */ |
| | #apply_settings_button {{ |
| | background-color: {apply_button_bg} !important; |
| | color: {text_color} !important; |
| | font-size: {fsize} !important; |
| | }} |
| | |
| | div[role="tablist"] {{ |
| | background-color: #8A2BE2 !important; |
| | border-radius: 8px; |
| | padding: {tab_padding} !important; |
| | height: auto !important; |
| | min-height: 0 !important; |
| | }} |
| | div[role="tab"] {{ |
| | font-size: {fsize} !important; |
| | padding: {tab_padding} !important; |
| | }} |
| | </style> |
| | """ |
| | return style |
| |
|
| | custom_css = """ |
| | @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap'); |
| | body, .gradio-container { |
| | margin: 0; |
| | padding: 0; |
| | font-family: 'Inter', sans-serif; |
| | } |
| | #header_section { |
| | width: 400px; |
| | height: 100px; |
| | background: url("https://huggingface.co/spaces/MusifyLTD/Musify/resolve/main/logo.png") |
| | no-repeat center center; |
| | background-size: contain; |
| | margin: 0px auto; |
| | margin-bottom: -10px; |
| | } |
| | #header_description { |
| | text-align: center; |
| | font-size: 20px; |
| | margin-top: -10px; |
| | margin-bottom: 10px; |
| | } |
| | #user_input textarea { |
| | border: none; |
| | padding: 10px; |
| | font-size: 1rem; |
| | } |
| | #user_input textarea::placeholder { |
| | font-size: 1rem; |
| | opacity: 0.73; |
| | } |
| | #user_input { |
| | height: 65px; |
| | border: none; |
| | } |
| | #send_button { |
| | margin-left: 1px; |
| | border: none; |
| | font-family: 'Inter', sans-serif; |
| | height: 67px; |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | padding: 0 10px; |
| | font-size: 1rem; |
| | } |
| | div[role="tablist"] { |
| | background-color: #8A2BE2 !important; |
| | border-radius: 8px; |
| | padding: 5px; |
| | } |
| | """ |
| | |
| | with gr.Blocks(css=custom_css) as demo: |
| | dynamic_styles = gr.HTML(value=update_styles("Dark", "Medium")) |
| | |
| | with gr.Tabs(): |
| | with gr.TabItem("💬 Chatbot"): |
| | gr.HTML('<div id="header_section"></div>') |
| | header_desc = gr.HTML('<p id="header_description">' + translations["English"]["header_description"] + '</p>') |
| | chatbot = gr.Chatbot(label="", height=400, show_label=False, elem_id="chatbot") |
| | with gr.Row(): |
| | user_input = gr.Textbox( |
| | show_label=False, |
| | lines=1, |
| | placeholder=translations["English"]["user_input_placeholder"], |
| | interactive=True, |
| | elem_id="user_input", |
| | scale=15 |
| | ) |
| | send_button = gr.Button( |
| | value=translations["English"]["send_button"], |
| | elem_id="send_button", |
| | scale=1 |
| | ) |
| | send_button.click( |
| | fn=chat_with_bot_stream, |
| | inputs=user_input, |
| | outputs=chatbot |
| | ).then( |
| | fn=lambda: "", |
| | inputs=None, |
| | outputs=user_input |
| | ) |
| | |
| | |
| | with gr.TabItem("⚙️ Settings"): |
| | with gr.Column(elem_id="settings_box"): |
| | settings_md = gr.Markdown(translations["English"]["settings_markdown"]) |
| | theme_radio = gr.Radio( |
| | choices=translations["English"]["theme_choices"], |
| | value="Dark", |
| | label=translations["English"]["theme_label"] |
| | ) |
| | font_radio = gr.Radio( |
| | choices=translations["English"]["font_size_choices"], |
| | value="Medium", |
| | label=translations["English"]["font_size_label"] |
| | ) |
| | language_radio = gr.Radio( |
| | choices=translations["English"]["language_choices"], |
| | value="English", |
| | label=translations["English"]["select_language_label"] |
| | ) |
| | apply_button = gr.Button( |
| | translations["English"]["apply_settings_button"], |
| | elem_id="apply_settings_button" |
| | ) |
| | apply_button.click( |
| | fn=update_all_settings, |
| | inputs=[theme_radio, font_radio, language_radio], |
| | outputs=[ |
| | dynamic_styles, |
| | header_desc, |
| | user_input, |
| | send_button, |
| | settings_md, |
| | apply_button, |
| | theme_radio, |
| | font_radio, |
| | language_radio |
| | ] |
| | ) |
| | |
| | demo.launch() |