jasonlawAI79 commited on
Commit
a3307cf
Β·
verified Β·
1 Parent(s): 6da81fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +255 -45
app.py CHANGED
@@ -2,77 +2,264 @@ import os
2
  import time
3
  import logging
4
  import gradio as gr
5
- import modal
6
 
7
  logging.basicConfig(level=logging.INFO)
8
  logger = logging.getLogger(__name__)
9
 
10
- logger.info(f"Modal version: {modal.__version__}")
11
- logger.info("===== Environment Variables =====")
12
- for k in ["HF_HUB_ENABLE_HF_TRANSFER", "HF_DATASETS_TRUST_REMOTE_CODE", "MODAL_TOKEN"]:
13
- logger.info(f"{k}: {os.environ.get(k, '❌ MISSING')}")
14
 
15
- if os.environ.get("MODAL_TOKEN") is None:
16
- raise RuntimeError("❌ MODAL_TOKEN not found in environment!")
17
-
18
- # βœ… Modal 1.x style β€” no modal.configure
19
  try:
20
- generate_content_with_llm = modal.Function.from_name(
21
- "mr-law-jason/main/content-creation-agent", # App path
22
- "generate_content_with_llm" # Function name
23
- )
24
- logger.info("βœ… Loaded remote Modal function")
25
- except Exception as e:
26
- logger.error(f"❌ Failed to load Modal function: {e}")
27
- generate_content_with_llm = None
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  def generate_fallback_content(lyrics, artist, title):
30
- return {
31
- 'youtube': f"🎡 {title} by {artist or 'Anonymous'} 🎡\n\n{lyrics[:200]}...\n\n#music #newrelease",
32
- 'twitter': f"New song: {title} by {artist or 'Anonymous'} is out now! 🎡\n#newmusic #{artist.lower().replace(' ', '') if artist else ''}",
33
- 'instagram': f"{title} is now available! ✨\nLink in bio\n#music #instamusic",
34
- 'facebook': f"New music release: {title} by {artist or 'Anonymous'}!\n\n#newmusic #artist",
35
- 'minds': f"Independent music release: {title}\n\n#independentartist #music",
36
- 'gab': f"New authentic music: {title}\n\n#realmusic #artist"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- outputs = ['youtube', 'twitter', 'instagram', 'facebook', 'minds', 'gab']
40
 
41
- def generate_all_content(lyrics, artist, title):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  start_time = time.time()
43
 
44
  # Initial yield - empty outputs and loading status
45
- empty_outputs = [""] * len(outputs) # 6 empty strings for platforms
46
- status_msg = "⏳ Generating content..."
47
- yield empty_outputs + [status_msg] # 7 total outputs
 
 
 
48
 
49
  try:
50
- if generate_content_with_llm:
 
51
  result = generate_content_with_llm.remote(lyrics, artist, title)
52
  content = result
53
  status_msg = f"βœ… Generated with Modal AI in {time.time() - start_time:.2f}s"
54
  else:
55
- raise RuntimeError("Modal function not available.")
 
 
 
 
 
 
56
  except Exception as e:
57
  logger.warning(f"⚠️ Modal generation failed: {e}")
58
  content = generate_fallback_content(lyrics, artist, title)
59
- status_msg = f"⚠️ Fallback used. Generated locally in {time.time() - start_time:.2f}s"
60
 
61
  # Final yield - actual content for each platform + status
62
- platform_outputs = [content.get(platform, f"Error generating {platform} content") for platform in outputs]
63
- yield platform_outputs + [status_msg] # 7 total outputs
 
64
 
 
65
  with gr.Blocks(theme=gr.themes.Soft(), title="🎡 Music Content Creator") as demo:
66
- gr.Markdown("""
67
  # 🎡 AI Content Generator for Musicians 🎬
68
 
69
- Transform your song lyrics into compelling social media content using AI!
70
 
71
  **✨ Features:**
72
- - πŸ€– AI-powered content generation using GPT-2
73
- - πŸ“± Platform-optimized content for YouTube, Twitter, Instagram, Facebook, Minds, and Gab
74
  - 🎯 Smart hashtag generation based on lyrics analysis
75
  - 🎀 Support for both named artists and anonymous releases
 
 
76
  """)
77
 
78
  with gr.Row():
@@ -90,18 +277,29 @@ with gr.Blocks(theme=gr.themes.Soft(), title="🎡 Music Content Creator") as de
90
  info="Leave blank for anonymous releases"
91
  )
92
  title_input = gr.Textbox(
93
- label="🎡 Song Title",
94
  placeholder="Song Title",
95
  info="The title of your song"
96
  )
97
 
 
 
 
 
 
 
 
 
 
 
 
98
  run_button = gr.Button("πŸš€ Generate Content", variant="primary", size="lg")
99
 
100
  gr.Markdown("## πŸ“± Generated Social Media Content")
101
 
102
  with gr.Row():
103
  with gr.Column():
104
- youtube_output = gr.Textbox(label="πŸ“Ί YouTube Description", lines=10)
105
  twitter_output = gr.Textbox(label="🐦 Twitter/X Post", lines=4)
106
  instagram_output = gr.Textbox(label="πŸ“Έ Instagram Caption", lines=6)
107
  with gr.Column():
@@ -114,7 +312,7 @@ with gr.Blocks(theme=gr.themes.Soft(), title="🎡 Music Content Creator") as de
114
  # Connect the function with proper outputs
115
  run_button.click(
116
  fn=generate_all_content,
117
- inputs=[lyrics_input, artist_input, title_input],
118
  outputs=[youtube_output, twitter_output, instagram_output, facebook_output, minds_output, gab_output, status]
119
  )
120
 
@@ -123,18 +321,30 @@ with gr.Blocks(theme=gr.themes.Soft(), title="🎡 Music Content Creator") as de
123
  examples=[
124
  [
125
  "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",
126
- "", # Empty artist name for anonymous example
127
- "Dreams Tonight"
 
128
  ],
129
  [
130
  "Love is in the air tonight\nHearts beating as one\nDancing under moonlight\nUntil the morning sun\nThis feeling never ends\nLove conquers all",
131
  "Romantic Vibes",
132
- "Moonlight Dance"
 
133
  ]
134
  ],
135
- inputs=[lyrics_input, artist_input, title_input],
136
  label="πŸ’‘ Try these examples"
137
  )
 
 
 
 
 
 
 
 
 
 
138
 
139
  if __name__ == "__main__":
140
  demo.launch()
 
2
  import time
3
  import logging
4
  import gradio as gr
 
5
 
6
  logging.basicConfig(level=logging.INFO)
7
  logger = logging.getLogger(__name__)
8
 
9
+ # Check Modal availability
10
+ MODAL_AVAILABLE = False
11
+ generate_content_with_llm = None
 
12
 
 
 
 
 
13
  try:
14
+ import modal
15
+ logger.info(f"Modal version: {modal.__version__}")
16
+
17
+ # Check for Modal token
18
+ if os.environ.get("MODAL_TOKEN"):
19
+ try:
20
+ generate_content_with_llm = modal.Function.from_name(
21
+ "mr-law-jason/main/content-creation-agent",
22
+ "generate_content_with_llm"
23
+ )
24
+ MODAL_AVAILABLE = True
25
+ logger.info("βœ… Modal successfully connected")
26
+ except Exception as e:
27
+ logger.warning(f"⚠️ Modal function loading failed: {e}")
28
+ else:
29
+ logger.warning("⚠️ MODAL_TOKEN not found in environment")
30
+
31
+ except ImportError:
32
+ logger.warning("⚠️ Modal package not available")
33
+
34
+ logger.info(f"Modal Status: {'βœ… Available' if MODAL_AVAILABLE else '❌ Unavailable'}")
35
 
36
  def generate_fallback_content(lyrics, artist, title):
37
+ """High-quality local content generation"""
38
+
39
+ # Analyze lyrics for themes and mood
40
+ lyrics_lower = lyrics.lower()
41
+
42
+ # Detect mood
43
+ mood = "uplifting"
44
+ if any(word in lyrics_lower for word in ['cry', 'tear', 'pain', 'hurt', 'lost', 'broken', 'sad']):
45
+ mood = "emotional"
46
+ elif any(word in lyrics_lower for word in ['energy', 'power', 'fire', 'strong', 'fight', 'drive']):
47
+ mood = "energetic"
48
+ elif any(word in lyrics_lower for word in ['love', 'happy', 'joy', 'hope', 'dream', 'light']):
49
+ mood = "inspiring"
50
+
51
+ # Extract themes
52
+ theme_words = []
53
+ if any(word in lyrics_lower for word in ['love', 'heart', 'romance']):
54
+ theme_words.append('love')
55
+ if any(word in lyrics_lower for word in ['dream', 'hope', 'future']):
56
+ theme_words.append('dreams')
57
+ if any(word in lyrics_lower for word in ['night', 'dark', 'star']):
58
+ theme_words.append('night')
59
+ if any(word in lyrics_lower for word in ['life', 'living', 'journey']):
60
+ theme_words.append('life')
61
+
62
+ themes_text = ', '.join(theme_words[:3]) if theme_words else 'deep emotions'
63
+
64
+ # Detect genre for hashtags
65
+ genre = 'indie'
66
+ if any(word in lyrics_lower for word in ['rock', 'guitar', 'band', 'drums']):
67
+ genre = 'rock'
68
+ elif any(word in lyrics_lower for word in ['pop', 'radio', 'catchy', 'dance']):
69
+ genre = 'pop'
70
+ elif any(word in lyrics_lower for word in ['rap', 'flow', 'beats', 'hip']):
71
+ genre = 'hiphop'
72
+ elif any(word in lyrics_lower for word in ['electronic', 'synth', 'edm']):
73
+ genre = 'electronic'
74
+
75
+ # Generate platform-specific hashtags
76
+ hashtags = {
77
+ 'youtube': f"#{genre}music #newmusic #musicvideo #{mood}music #originalmusic #independentartist #songwriter #musicdiscovery #viral #subscribe #newrelease #musicproducer #instamusic #unsignedartist #emergingartist",
78
+ 'twitter': f"#{genre} #newmusic #nowplaying #{mood} #musicvideo #viral",
79
+ 'instagram': f"#{genre}vibes #newmusic #instamusic #{mood} #musicpost #originalmusic #artist #viral #trending #musiclover #songwriter #independentartist #newrelease #musicdiscovery #vibes",
80
+ 'facebook': f"#{genre}music #newmusic #originalmusic #{mood} #musicvideo #viral",
81
+ 'minds': f"#independentmusic #originalmusic #newmusic #creative #authentic",
82
+ 'gab': f"#originalmusic #independent #authentic #realmusic #newmusic"
83
  }
84
+
85
+ artist_display = artist if artist.strip() else "Anonymous Artist"
86
+ by_artist = f" - {artist_display}" if artist.strip() else ""
87
+
88
+ if artist.strip():
89
+ # Content with artist name
90
+ return {
91
+ 'youtube': f"""🎡 {title}{by_artist} 🎡
92
+
93
+ Experience this latest music video! This {mood} track explores themes of {themes_text}.
94
+
95
+ 🎬 Watch the full music video above
96
+ πŸ’Ώ Stream on all platforms
97
+ πŸ”” Subscribe for more music videos
98
+ πŸ‘ Like if you enjoyed this track
99
+
100
+ πŸ“ LYRICS:
101
+ {lyrics}
102
+
103
+ {hashtags['youtube']}""",
104
+
105
+ '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']}",
106
+
107
+ 'instagram': f"""🎡✨ '{title}' Official Music Video is LIVE! ✨🎡
108
+
109
+ {artist_display} delivers another {mood} masterpiece that speaks to the soul πŸ’«
110
+
111
+ 🎬 Full video in bio
112
+ πŸ’­ What's your favorite lyric? Comment below!
113
+
114
+ {hashtags['instagram']}""",
115
+
116
+ 'facebook': f"""🎡 MUSIC VIDEO PREMIERE 🎡
117
+
118
+ New music video for '{title}'{by_artist} just dropped!
119
+
120
+ This {mood} track captures the essence of {themes_text} in a beautiful way. The visuals perfectly complement the powerful lyrics.
121
+
122
+ 🎬 Watch the full video now!
123
+ πŸ’¬ Let us know what you think in the comments
124
+ πŸ”„ Share with friends who love good music
125
+
126
+ {hashtags['facebook']}""",
127
+
128
+ 'minds': f"""🎡 New Music Alert!
129
+
130
+ {artist_display} - '{title}' Official Music Video
131
+
132
+ This {mood} track showcases incredible artistry and meaningful lyrics. Independent artists like {artist_display} are creating the future of music.
133
+
134
+ Support independent music and check out this latest release!
135
+
136
+ {hashtags['minds']}""",
137
+
138
+ 'gab': f"""New Music Video Drop!
139
+
140
+ '{title}'{by_artist}
141
+
142
+ Real music with real meaning. This {mood} track reminds us why authentic artistry matters in today's world.
143
 
144
+ Give it a listen and support independent creators!
145
 
146
+ {hashtags['gab']}"""
147
+ }
148
+ else:
149
+ # Anonymous content
150
+ return {
151
+ 'youtube': f"""🎡 {title} 🎡
152
+
153
+ Experience this captivating music video! This {mood} track explores themes of {themes_text}.
154
+
155
+ 🎬 Watch the full music video above
156
+ πŸ’Ώ Available on all streaming platforms
157
+ πŸ”” Subscribe for more amazing music videos
158
+ πŸ‘ Like if this track moved you
159
+
160
+ πŸ“ LYRICS:
161
+ {lyrics}
162
+
163
+ {hashtags['youtube']}""",
164
+
165
+ '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']}",
166
+
167
+ 'instagram': f"""🎡✨ '{title}' Official Music Video is LIVE! ✨🎡
168
+
169
+ Another {mood} masterpiece that speaks to the soul πŸ’«
170
+
171
+ 🎬 Full video in bio
172
+ πŸ’­ What's your favorite lyric? Comment below!
173
+
174
+ {hashtags['instagram']}""",
175
+
176
+ 'facebook': f"""🎡 MUSIC VIDEO PREMIERE 🎡
177
+
178
+ '{title}' official music video just dropped!
179
+
180
+ This {mood} track captures the essence of {themes_text} in a beautiful way. The visuals perfectly complement the powerful lyrics.
181
+
182
+ 🎬 Watch the full video now!
183
+ πŸ’¬ Let us know what you think in the comments
184
+ πŸ”„ Share with friends who love good music
185
+
186
+ {hashtags['facebook']}""",
187
+
188
+ 'minds': f"""🎡 New Music Alert!
189
+
190
+ '{title}' Official Music Video
191
+
192
+ This {mood} track showcases incredible artistry and meaningful lyrics. Independent music continues to push creative boundaries.
193
+
194
+ Support independent music and check out this latest release!
195
+
196
+ {hashtags['minds']}""",
197
+
198
+ 'gab': f"""New Music Video Drop!
199
+
200
+ '{title}'
201
+
202
+ Real music with real meaning. This {mood} track reminds us why authentic artistry matters in today's world.
203
+
204
+ Give it a listen and support independent creators!
205
+
206
+ {hashtags['gab']}"""
207
+ }
208
+
209
+ def generate_all_content(lyrics, artist, title, use_modal):
210
+ """Generate content with Modal toggle"""
211
+ if not lyrics.strip() or not title.strip():
212
+ error_msg = "❌ Please provide both lyrics and song title"
213
+ return [""] * 6 + [error_msg]
214
+
215
  start_time = time.time()
216
 
217
  # Initial yield - empty outputs and loading status
218
+ empty_outputs = [""] * 6
219
+ if use_modal and MODAL_AVAILABLE:
220
+ status_msg = "⏳ Generating content with Modal AI..."
221
+ else:
222
+ status_msg = "⏳ Generating content with local templates..."
223
+ yield empty_outputs + [status_msg]
224
 
225
  try:
226
+ if use_modal and MODAL_AVAILABLE and generate_content_with_llm:
227
+ # Try Modal AI generation
228
  result = generate_content_with_llm.remote(lyrics, artist, title)
229
  content = result
230
  status_msg = f"βœ… Generated with Modal AI in {time.time() - start_time:.2f}s"
231
  else:
232
+ # Use local fallback
233
+ if use_modal and not MODAL_AVAILABLE:
234
+ status_msg = "⚠️ Modal unavailable, using local generation..."
235
+ content = generate_fallback_content(lyrics, artist, title)
236
+ if not (use_modal and not MODAL_AVAILABLE):
237
+ status_msg = f"βœ… Generated with local templates in {time.time() - start_time:.2f}s"
238
+
239
  except Exception as e:
240
  logger.warning(f"⚠️ Modal generation failed: {e}")
241
  content = generate_fallback_content(lyrics, artist, title)
242
+ status_msg = f"⚠️ Modal failed, used local fallback in {time.time() - start_time:.2f}s"
243
 
244
  # Final yield - actual content for each platform + status
245
+ platforms = ['youtube', 'twitter', 'instagram', 'facebook', 'minds', 'gab']
246
+ platform_outputs = [content.get(platform, f"Error generating {platform} content") for platform in platforms]
247
+ yield platform_outputs + [status_msg]
248
 
249
+ # Create Gradio interface
250
  with gr.Blocks(theme=gr.themes.Soft(), title="🎡 Music Content Creator") as demo:
251
+ gr.Markdown(f"""
252
  # 🎡 AI Content Generator for Musicians 🎬
253
 
254
+ Transform your song lyrics into compelling social media content!
255
 
256
  **✨ Features:**
257
+ - πŸ€– AI-powered content generation (when Modal is available)
258
+ - πŸ“± Platform-optimized content for YouTube, Twitter, Instagram, Facebook, Minds, and Gab
259
  - 🎯 Smart hashtag generation based on lyrics analysis
260
  - 🎀 Support for both named artists and anonymous releases
261
+
262
+ **πŸ”§ Backend Status:** {"🟒 Modal Available" if MODAL_AVAILABLE else "🟑 Local Mode Only"}
263
  """)
264
 
265
  with gr.Row():
 
277
  info="Leave blank for anonymous releases"
278
  )
279
  title_input = gr.Textbox(
280
+ label="🎡 Song Title",
281
  placeholder="Song Title",
282
  info="The title of your song"
283
  )
284
 
285
+ # Modal toggle with clear labeling
286
+ modal_toggle = gr.Radio(
287
+ choices=[
288
+ ("πŸ€– AI Generation (Modal)", True),
289
+ ("πŸ“ Local Templates", False)
290
+ ],
291
+ value=MODAL_AVAILABLE, # Default to Modal if available
292
+ label="Generation Method",
293
+ info="Choose between AI-powered generation or local templates"
294
+ )
295
+
296
  run_button = gr.Button("πŸš€ Generate Content", variant="primary", size="lg")
297
 
298
  gr.Markdown("## πŸ“± Generated Social Media Content")
299
 
300
  with gr.Row():
301
  with gr.Column():
302
+ youtube_output = gr.Textbox(label="πŸ“Ί YouTube Description", lines=12)
303
  twitter_output = gr.Textbox(label="🐦 Twitter/X Post", lines=4)
304
  instagram_output = gr.Textbox(label="πŸ“Έ Instagram Caption", lines=6)
305
  with gr.Column():
 
312
  # Connect the function with proper outputs
313
  run_button.click(
314
  fn=generate_all_content,
315
+ inputs=[lyrics_input, artist_input, title_input, modal_toggle],
316
  outputs=[youtube_output, twitter_output, instagram_output, facebook_output, minds_output, gab_output, status]
317
  )
318
 
 
321
  examples=[
322
  [
323
  "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",
324
+ "", # Empty artist name
325
+ "Dreams Tonight",
326
+ True # Use Modal if available
327
  ],
328
  [
329
  "Love is in the air tonight\nHearts beating as one\nDancing under moonlight\nUntil the morning sun\nThis feeling never ends\nLove conquers all",
330
  "Romantic Vibes",
331
+ "Moonlight Dance",
332
+ False # Use local generation
333
  ]
334
  ],
335
+ inputs=[lyrics_input, artist_input, title_input, modal_toggle],
336
  label="πŸ’‘ Try these examples"
337
  )
338
+
339
+ # Add footer with info
340
+ gr.Markdown("""
341
+ ---
342
+ **πŸ’‘ Tips:**
343
+ - **AI Generation:** Uses GPT-2 on Modal for creative, context-aware content
344
+ - **Local Templates:** Fast, rule-based generation that works offline
345
+ - **Modal Credits:** Can be used for LLM inference and GPU-intensive functions ([Modal Docs](https://modal.com/docs))
346
+ - **Best Results:** Include rich, descriptive lyrics for better theme detection
347
+ """)
348
 
349
  if __name__ == "__main__":
350
  demo.launch()