jasonlawAI79's picture
Update app.py
c362691 verified
import os
import time
import logging
import gradio as gr
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Modal setup with proper secret handling
MODAL_AVAILABLE = False
generate_content_with_llm = None
try:
import modal
logger.info(f"Modal version: {modal.__version__}")
# Check for Modal tokens - HuggingFace should have both ID and SECRET
modal_token_id = os.environ.get("MODAL_TOKEN_ID")
modal_token_secret = os.environ.get("MODAL_TOKEN_SECRET")
if modal_token_id and modal_token_secret:
try:
# Try to connect to your deployed Modal functions using the new API
logger.info("πŸ”„ Attempting to connect to Modal functions...")
# First try the main AI function
try:
generate_content_with_llm = modal.Function.from_name(
"content-creation-agent",
"generate_content_with_llm"
)
# Test connection with health check
health_check_func = modal.Function.from_name(
"content-creation-agent",
"health_check"
)
# Test if Modal is working
test_result = health_check_func.remote()
logger.info(f"βœ… Modal health check passed: {test_result}")
MODAL_AVAILABLE = True
logger.info("βœ… Modal successfully connected to main AI function")
except Exception as e:
logger.warning(f"⚠️ Modal main function connection failed: {e}")
# Try fallback function instead (this one we know works)
try:
generate_content_with_llm = modal.Function.from_name(
"content-creation-agent",
"generate_fallback_content"
)
# Still test health check
health_check_func = modal.Function.from_name(
"content-creation-agent",
"health_check"
)
test_result = health_check_func.remote()
logger.info(f"βœ… Modal health check passed: {test_result}")
MODAL_AVAILABLE = True
logger.info("βœ… Modal connected using fallback function (still high quality!)")
except Exception as e2:
logger.warning(f"⚠️ Modal fallback also failed: {e2}")
MODAL_AVAILABLE = False
except Exception as main_e:
logger.warning(f"⚠️ Modal connection failed: {main_e}")
MODAL_AVAILABLE = False
else:
logger.warning("⚠️ MODAL_TOKEN_ID and MODAL_TOKEN_SECRET not found in environment variables")
logger.info("πŸ’‘ To fix this, add MODAL_TOKEN_ID and MODAL_TOKEN_SECRET to your HuggingFace Space environment variables")
except ImportError:
logger.warning("⚠️ Modal package not available")
except Exception as e:
logger.warning(f"⚠️ Modal setup failed: {e}")
logger.info(f"Modal Status: {'βœ… Available' if MODAL_AVAILABLE else '❌ Unavailable'}")
def generate_fallback_content(lyrics, artist, title):
"""High-quality local content generation"""
# Analyze lyrics for themes and mood
lyrics_lower = lyrics.lower()
# Advanced mood detection
mood = "uplifting"
if any(word in lyrics_lower for word in ['cry', 'tear', 'pain', 'hurt', 'lost', 'broken', 'sad', 'lonely', 'dark']):
mood = "emotional"
elif any(word in lyrics_lower for word in ['energy', 'power', 'fire', 'strong', 'fight', 'drive', 'force', 'intense']):
mood = "energetic"
elif any(word in lyrics_lower for word in ['love', 'happy', 'joy', 'hope', 'dream', 'light', 'beautiful', 'amazing']):
mood = "inspiring"
# Extract themes with better detection
theme_words = []
if any(word in lyrics_lower for word in ['love', 'heart', 'romance', 'kiss', 'together']):
theme_words.append('love')
if any(word in lyrics_lower for word in ['dream', 'hope', 'future', 'tomorrow', 'vision']):
theme_words.append('dreams')
if any(word in lyrics_lower for word in ['night', 'dark', 'star', 'moon', 'midnight']):
theme_words.append('night')
if any(word in lyrics_lower for word in ['life', 'living', 'journey', 'path', 'way']):
theme_words.append('life')
if any(word in lyrics_lower for word in ['freedom', 'free', 'escape', 'break', 'liberation']):
theme_words.append('freedom')
if any(word in lyrics_lower for word in ['time', 'moment', 'forever', 'always', 'memory']):
theme_words.append('time')
themes_text = ', '.join(theme_words[:3]) if theme_words else 'deep emotions'
# Advanced genre detection
genre = 'indie'
if any(word in lyrics_lower for word in ['rock', 'guitar', 'band', 'drums', 'electric', 'amp']):
genre = 'rock'
elif any(word in lyrics_lower for word in ['pop', 'radio', 'catchy', 'dance', 'party', 'club']):
genre = 'pop'
elif any(word in lyrics_lower for word in ['rap', 'flow', 'beats', 'hip', 'street', 'rhyme']):
genre = 'hiphop'
elif any(word in lyrics_lower for word in ['electronic', 'synth', 'edm', 'techno', 'digital']):
genre = 'electronic'
elif any(word in lyrics_lower for word in ['acoustic', 'folk', 'country', 'traditional']):
genre = 'acoustic'
# Premium hashtag generation
base_hashtags = {
'youtube': [f'{genre}music', 'newmusic', 'musicvideo', f'{mood}music', 'originalmusic', 'independentartist', 'songwriter', 'musicdiscovery', 'viral', 'subscribe', 'newrelease', 'musicproducer', 'instamusic', 'unsignedartist', 'emergingartist'],
'twitter': [f'{genre}', 'newmusic', 'nowplaying', f'{mood}', 'musicvideo', 'viral'],
'instagram': [f'{genre}vibes', 'newmusic', 'instamusic', f'{mood}', 'musicpost', 'originalmusic', 'artist', 'viral', 'trending', 'musiclover', 'songwriter', 'independentartist', 'newrelease', 'musicdiscovery', 'vibes'],
'facebook': [f'{genre}music', 'newmusic', 'originalmusic', f'{mood}', 'musicvideo', 'viral'],
'minds': ['independentmusic', 'originalmusic', 'newmusic', 'creative', 'authentic'],
'gab': ['originalmusic', 'independent', 'authentic', 'realmusic', 'newmusic']
}
# Add theme-based hashtags
for platform in base_hashtags:
for theme in theme_words[:2]: # Add top 2 themes
base_hashtags[platform].append(f'{theme}music')
# Format hashtags with proper limits
hashtags = {}
limits = {'youtube': 15, 'instagram': 15, 'twitter': 6, 'facebook': 6, 'minds': 5, 'gab': 5}
for platform, tags in base_hashtags.items():
limit = limits.get(platform, 10)
formatted_tags = ' '.join(f'#{tag}' for tag in tags[:limit])
hashtags[platform] = formatted_tags
artist_display = artist if artist.strip() else "Anonymous Artist"
by_artist = f" - {artist_display}" if artist.strip() else ""
if artist.strip():
# Content with artist name
return {
'youtube': f"""🎡 {title}{by_artist} 🎡
Experience this latest music video! This {mood} track explores themes of {themes_text}.
🎬 Watch the full music video above
πŸ’Ώ Stream on all platforms
πŸ”” Subscribe for more music videos
πŸ‘ Like if you enjoyed this track
πŸ“ LYRICS:
{lyrics}
{hashtags['youtube']}""",
'twitter': f"🎡 NEW MUSIC VIDEO: '{title}'{by_artist} is here! This {mood} track will give you all the feels πŸ’«\n\n🎬 Watch: [Link]\n\n{hashtags['twitter']}",
'instagram': f"""🎡✨ '{title}' Official Music Video is LIVE! ✨🎡
{artist_display} delivers another {mood} masterpiece that speaks to the soul πŸ’«
🎬 Full video in bio
πŸ’­ What's your favorite lyric? Comment below!
{hashtags['instagram']}""",
'facebook': f"""🎡 MUSIC VIDEO PREMIERE 🎡
New music video for '{title}'{by_artist} just dropped!
This {mood} track captures the essence of {themes_text} in a beautiful way. The visuals perfectly complement the powerful lyrics.
🎬 Watch the full video now!
πŸ’¬ Let us know what you think in the comments
πŸ”„ Share with friends who love good music
{hashtags['facebook']}""",
'minds': f"""🎡 New Music Alert!
{artist_display} - '{title}' Official Music Video
This {mood} track showcases incredible artistry and meaningful lyrics. Independent artists like {artist_display} are creating the future of music.
Support independent music and check out this latest release!
{hashtags['minds']}""",
'gab': f"""New Music Video Drop!
'{title}'{by_artist}
Real music with real meaning. This {mood} track reminds us why authentic artistry matters in today's world.
Give it a listen and support independent creators!
{hashtags['gab']}"""
}
else:
# Anonymous content
return {
'youtube': f"""🎡 {title} 🎡
Experience this captivating music video! This {mood} track explores themes of {themes_text}.
🎬 Watch the full music video above
πŸ’Ώ Available on all streaming platforms
πŸ”” Subscribe for more amazing music videos
πŸ‘ Like if this track moved you
πŸ“ LYRICS:
{lyrics}
{hashtags['youtube']}""",
'twitter': f"🎡 NEW MUSIC VIDEO: '{title}' is here! This {mood} track will give you all the feels πŸ’«\n\n🎬 Watch: [Link]\n\n{hashtags['twitter']}",
'instagram': f"""🎡✨ '{title}' Official Music Video is LIVE! ✨🎡
Another {mood} masterpiece that speaks to the soul πŸ’«
🎬 Full video in bio
πŸ’­ What's your favorite lyric? Comment below!
{hashtags['instagram']}""",
'facebook': f"""🎡 MUSIC VIDEO PREMIERE 🎡
'{title}' official music video just dropped!
This {mood} track captures the essence of {themes_text} in a beautiful way. The visuals perfectly complement the powerful lyrics.
🎬 Watch the full video now!
πŸ’¬ Let us know what you think in the comments
πŸ”„ Share with friends who love good music
{hashtags['facebook']}""",
'minds': f"""🎡 New Music Alert!
'{title}' Official Music Video
This {mood} track showcases incredible artistry and meaningful lyrics. Independent music continues to push creative boundaries.
Support independent music and check out this latest release!
{hashtags['minds']}""",
'gab': f"""New Music Video Drop!
'{title}'
Real music with real meaning. This {mood} track reminds us why authentic artistry matters in today's world.
Give it a listen and support independent creators!
{hashtags['gab']}"""
}
def generate_all_content(lyrics, artist, title, use_modal):
"""Generate content with Modal toggle"""
if not lyrics.strip() or not title.strip():
error_msg = "❌ Please provide both lyrics and song title"
return [""] * 6 + [error_msg]
start_time = time.time()
# Initial yield - empty outputs and loading status
empty_outputs = [""] * 6
if use_modal and MODAL_AVAILABLE:
status_msg = "⏳ Generating content with Modal AI..."
else:
status_msg = "⏳ Generating content with local templates..."
yield empty_outputs + [status_msg]
try:
if use_modal and MODAL_AVAILABLE and generate_content_with_llm:
# Try Modal AI generation
try:
logger.info("πŸ”„ Attempting Modal AI generation...")
result = generate_content_with_llm.remote(lyrics, artist, title)
# Validate result
if isinstance(result, dict) and len(result) > 0:
content = result
status_msg = f"βœ… Generated with Modal AI in {time.time() - start_time:.2f}s"
logger.info("βœ… Modal AI generation successful")
else:
raise ValueError("Invalid result from Modal function")
except Exception as modal_error:
logger.warning(f"⚠️ Modal AI generation failed: {modal_error}")
# Fall back to local generation
content = generate_fallback_content(lyrics, artist, title)
status_msg = f"⚠️ Modal failed, used local fallback in {time.time() - start_time:.2f}s"
else:
# Use local fallback
if use_modal and not MODAL_AVAILABLE:
status_msg = "⚠️ Modal unavailable, using local generation..."
content = generate_fallback_content(lyrics, artist, title)
if not (use_modal and not MODAL_AVAILABLE):
status_msg = f"βœ… Generated with local templates in {time.time() - start_time:.2f}s"
except Exception as e:
logger.error(f"❌ Unexpected error: {e}")
content = generate_fallback_content(lyrics, artist, title)
status_msg = f"❌ Error occurred, used local fallback in {time.time() - start_time:.2f}s"
# Final yield - actual content for each platform + status
platforms = ['youtube', 'twitter', 'instagram', 'facebook', 'minds', 'gab']
platform_outputs = [content.get(platform, f"Error generating {platform} content") for platform in platforms]
yield platform_outputs + [status_msg]
# Create Gradio interface
with gr.Blocks(theme=gr.themes.Soft(), title="🎡 Music Content Creator") as demo:
gr.Markdown(f"""
# 🎡 AI Content Generator for Musicians 🎬
Transform your song lyrics into compelling social media content!
**✨ Features:**
- πŸ€– AI-powered content generation (when Modal is available)
- πŸ“± Platform-optimized content for YouTube, Twitter, Instagram, Facebook, Minds, and Gab
- 🎯 Smart hashtag generation based on lyrics analysis
- 🎀 Support for both named artists and anonymous releases
**πŸ”§ Backend Status:** {"🟒 Modal Available" if MODAL_AVAILABLE else "🟑 Local Mode Only"}
{"" if MODAL_AVAILABLE else "πŸ’‘ **To enable AI generation:** Add your Modal token to the HuggingFace Space environment variables"}
""")
with gr.Row():
with gr.Column(scale=2):
lyrics_input = gr.Textbox(
lines=8,
label="🎡 Song Lyrics",
placeholder="Enter your complete song lyrics here...",
info="Paste the full lyrics of your song"
)
with gr.Column(scale=1):
artist_input = gr.Textbox(
label="🎀 Artist Name",
placeholder="Artist Name (Optional)",
info="Leave blank for anonymous releases"
)
title_input = gr.Textbox(
label="🎡 Song Title",
placeholder="Song Title",
info="The title of your song"
)
# Modal toggle
modal_toggle = gr.Radio(
choices=[
("πŸ€– AI Generation (Modal)", True),
("πŸ“ Local Templates", False)
],
value=MODAL_AVAILABLE, # Default to Modal if available, otherwise local
label="Generation Method",
info="Choose between AI-powered generation or local templates"
)
run_button = gr.Button("πŸš€ Generate Content", variant="primary", size="lg")
gr.Markdown("## πŸ“± Generated Social Media Content")
with gr.Row():
with gr.Column():
youtube_output = gr.Textbox(label="πŸ“Ί YouTube Description", lines=12)
twitter_output = gr.Textbox(label="🐦 Twitter/X Post", lines=4)
instagram_output = gr.Textbox(label="πŸ“Έ Instagram Caption", lines=6)
with gr.Column():
facebook_output = gr.Textbox(label="πŸ“˜ Facebook Post", lines=6)
minds_output = gr.Textbox(label="🧠 Minds Post", lines=4)
gab_output = gr.Textbox(label="πŸ’¬ Gab Post", lines=4)
status = gr.Markdown("Ready to generate content!")
# Connect the function with proper outputs
run_button.click(
fn=generate_all_content,
inputs=[lyrics_input, artist_input, title_input, modal_toggle],
outputs=[youtube_output, twitter_output, instagram_output, facebook_output, minds_output, gab_output, status]
)
# Add examples
gr.Examples(
examples=[
[
"Here's an example with some sample lyrics\nAbout dreams and aspirations\nReaching for the stars tonight\nNothing's gonna stop this fight\nWe'll keep on climbing higher\nUntil we touch the sky",
"", # Empty artist name
"Dreams Tonight",
MODAL_AVAILABLE # Use Modal if available
],
[
"Love is in the air tonight\nHearts beating as one\nDancing under moonlight\nUntil the morning sun\nThis feeling never ends\nLove conquers all",
"Romantic Vibes",
"Moonlight Dance",
False # Use local generation
]
],
inputs=[lyrics_input, artist_input, title_input, modal_toggle],
label="πŸ’‘ Try these examples"
)
# Add footer with info
gr.Markdown(f"""
---
**πŸ’‘ Tips:**
- **AI Generation:** Uses GPT-2 on Modal for creative, context-aware content
- **Local Templates:** Fast, rule-based generation that always works
- **Modal Credits:** Can be used for LLM inference and GPU-intensive functions ([Modal Docs](https://modal.com/docs))
- **Best Results:** Include rich, descriptive lyrics for better theme detection
**πŸ”§ Status:** {"βœ… Modal Working" if MODAL_AVAILABLE else "🟑 Local Mode Only"}
{"" if MODAL_AVAILABLE else "**To enable Modal AI:** Add MODAL_TOKEN to your HuggingFace Space environment variables"}
""")
if __name__ == "__main__":
demo.launch()