Musify / tempCodeRunnerFile.py
Fasty's picture
added accessibility settings, translations are in code in a dict
9ddddcb
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
]
# 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_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"]
}
}
# 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)
)
# DARK ADN LIGHT MODE
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"
# Font, still havent decided if i want a slider but this is cleaner design in my op
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;
}
"""
# Gradio build stuff actually starts here
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
)
# SETTINGS PAGE
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()