Musify / app.py
solinm's picture
Update app.py
b7614a2 verified
raw
history blame
17.6 kB
import gradio as gr
import os
from groq import Groq
api_key = os.getenv("GROQ_API_KEY")
client = Groq(api_key=api_key)
def chat_with_bot_stream(user_input, conversation_history):
if conversation_history is None:
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."
"If asked about visibility on the website, such as font sizing and themes (dark or light mode ONLY), direct them to the settings tab at the top of the chatbot."
"If asked about the languages you speak, you can say that you speak English, Spanish, and French ONLY. Direct the user to the settings tab to change the language."
"Limit your responses to music-related inquiries only. Limit your responses to 10 lines or less."
)
})
completion = client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=conversation_history,
temperature=0.95,
max_tokens=1024,
top_p=0.9,
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
], conversation_history
# word translation
translations = {
"English": {
"header_description": "Your own personal music discovery assistant!",
"user_input_placeholder": "Enter your music-related questions here!",
"send_button": "↗️ Send",
"settings_tab_item": "⚙️ Settings",
"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", "Español", "Français"]
},
"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_tab_item": "⚙️ Configuración",
"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": ["English", "Español", "Français"]
},
"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_tab_item": "⚙️ Paramètres",
"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": ["English", "Español", "Français"]
}
}
# translations for theme
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"}
# I wanted to include the c in Fraincais and the spanish e and n in Spanish
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: # target is English
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)
#Languages
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 = "#2E2E2E"
button_bg = "#3A3A3A"
settings_box_bg = "#2E2E2E"
apply_button_bg = "#3A3A3A"
radio_bg = "#2E2E2E"
settings_heading_color = text_color
border_color = "#444444"
placeholder_color = "#e8e8e8"
chatbot_bg = "#18181B"
chatbot_text_color = "#ffffff"
purple="#56246B"
light_purple="#795699"
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"
border_color = "#cccccc"
placeholder_color = "#e8e8e8"
chatbot_bg = "#cfcfcf"
chatbot_text_color = "#000000"
purple="#56246B"
light_purple="#795699"
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">
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');
body, .gradio-container {{
background-color: {bg} !important;
color: {text_color} !important;
font-size: {fsize} !important;
font-family: 'Inter', sans-serif;
margin: 0;
padding: 0;
}}
#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;
color: {text_color} !important;
font-size: {fsize} !important;
margin-top: -10px;
margin-bottom: 10px;
}}
h3 {{
color: {text_color} !important;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-size: {fsize} !important;
}}
#chatbot {{
background-color: {chatbot_bg} !important;
color: {chatbot_text_color} !important;
font-size: {fsize} !important;
}}
div[role="log"] {{
background-color: {chatbot_bg} !important;
color: {chatbot_text_color} !important;
}}
div[data-testid="bot"], div[data-testid="user"] {{
color: {chatbot_text_color} !important;
}}
#user_input {{
background-color: {purple} !important;
border: 1px solid {purple} !important;
height: 65px;
}}
#user_input textarea {{
background-color: {light_purple} !important;
color: {text_color} !important;
font-size: {fsize} !important;
border: 1px solid {light_purple} !important;
padding: 10px;
border: none;
}}
#user_input textarea::placeholder {{
background-color: {light_purple} !important;
color: {placeholder_color} !important;
font-size: {fsize} !important;
opacity: 0.73;
}}
#send_button {{
background-color: {purple} !important;
color: {placeholder_color} !important;
font-size: {fsize} !important;
border: 1px solid {purple} !important;
margin-left: 1px;
font-family: 'Inter', sans-serif;
height: 67px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
}}
#settings_box {{
background-color: {settings_box_bg} !important;
padding: 10px;
border-radius: 8px;
font-size: {fsize} !important;
border: 1px solid {border_color} !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 {{
background-color: {purple} !important;
color: {placeholder_color} !important;
font-size: {fsize} !important;
border: 1px solid {border_color} !important;
}}
div[role="tablist"] {{
border: 1px;
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;
color: {text_color} !important;
}}
button[role="tab"][aria-selected="true"]::after {{
background-color:#56246B !important;
}}
button[role="tab"][aria-selected="true"] {{
color: {text_color} !important;
}}
button[role="tab"][aria-selected="false"] {{
background-color:transparent !important;
color: #616161 !important;
}}
input[type="radio"] {{
background-color: #795699 !important;
}}
input[type="radio"]:checked {{
background-color: #56246B !important;
border-color: #795699 !important;
}}
fieldset {{
background-color: {settings_box_bg} !important;
color: {text_color} !important;
}}
label[data-testid] {{
background-color: {bg} !important;
color: {text_color} !important;
}}
[data-testid="block-info"] {{
color: {text_color} !important;
}}
</style>
"""
return style
# Gradio build stuff actually starts here
with gr.Blocks(css=None) 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
)
conversation_state = gr.State(value=[])
send_button.click(
fn=chat_with_bot_stream,
inputs=[user_input, conversation_state],
outputs=[chatbot, conversation_state]
).then(
fn=lambda: "",
inputs=None,
outputs=user_input
)
# SETTINGS PAGE
with gr.TabItem(translations["English"]["settings_tab_item"]):
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()