jasonlawAI79 commited on
Commit
1319fb5
·
verified ·
1 Parent(s): 231cbd8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -243
app.py CHANGED
@@ -1,265 +1,82 @@
1
- import gradio as gr
2
  import os
 
 
 
 
3
 
4
- # ✅ Updated Modal token config
5
- if 'MODAL_TOKEN' in os.environ:
6
- import modal
7
- modal.config.token_id = os.environ['MODAL_TOKEN']
8
- print("✅ Modal token configured from HF Secrets")
9
- else:
10
- print("❌ MODAL_TOKEN not found in environment")
11
 
12
- from typing import Dict
13
- import re
 
 
14
 
15
- # Updated Modal function lookup using client + stub
16
- try:
17
- import modal
18
- client = modal.Client()
19
- stub = client.stub("content-creation-agent")
20
 
21
- generate_ai_content = stub.function("generate_content_with_llm")
22
- generate_template_content = stub.function("generate_fallback_content")
23
- MODAL_AVAILABLE = True
24
- print(" Modal successfully imported and functions loaded")
 
 
 
25
  except Exception as e:
26
- MODAL_AVAILABLE = False
27
- print(f"❌ Modal not available - using fallback. Reason: {e}")
28
-
29
- def generate_smart_hashtags(lyrics: str, song_title: str, artist_name: str, mood: str, themes: list, platform: str) -> str:
30
- # ... unchanged hashtag logic ...
31
- # [omitted for brevity since you asked for full code, it is included below]
32
- genre_words = {
33
- 'rock': ['rock', 'guitar', 'drums', 'energy', 'driving', 'electric'],
34
- 'acoustic': ['acoustic', 'guitar', 'soft', 'intimate', 'whisper'],
35
- 'electronic': ['synth', 'beat', 'digital', 'electronic', 'techno'],
36
- 'pop': ['catchy', 'melody', 'chorus', 'hook', 'radio'],
37
- 'hiphop': ['rap', 'rhythm', 'flow', 'beats', 'street'],
38
- 'folk': ['story', 'traditional', 'nature', 'home', 'country'],
39
- 'dance': ['dance', 'club', 'party', 'move', 'groove', 'floor']
40
- }
41
-
42
- detected_genre = 'indie'
43
- lyrics_lower = lyrics.lower()
44
- for genre, keywords in genre_words.items():
45
- if any(keyword in lyrics_lower for keyword in keywords):
46
- detected_genre = genre
47
- break
48
-
49
- quality_tags = {
50
- 'youtube': ['newmusic', 'musicvideo', 'viral', 'musician', 'songwriter', 'indie', 'original', 'artist', 'music2025', 'instamusic', 'unsignedartist', 'indiemusic', 'newartist', 'musicproducer', 'musiclover'],
51
- 'instagram': ['newmusic', 'musicvideo', 'instamusic', 'viral', 'musician', 'songwriter', 'indie', 'artist', 'music2025', 'musiclover', 'unsignedartist', 'indiemusic', 'newartist', 'musicproducer', 'originalmusic'],
52
- 'twitter': ['newmusic', 'musicvideo', 'nowplaying', 'viral', 'musician', 'songwriter'],
53
- 'facebook': ['newmusic', 'musicvideo', 'viral', 'musician', 'songwriter', 'indie'],
54
- 'minds': ['independentmusic', 'newmusic', 'musicvideo', 'artist', 'original'],
55
- 'gab': ['music', 'independentartist', 'newmusic', 'original', 'viral']
56
- }
57
-
58
- mood_hashtags = {
59
- 'emotional': ['emotional', 'feelings', 'heartfelt', 'deep', 'soulful'],
60
- 'uplifting': ['uplifting', 'positive', 'inspiring', 'hopeful', 'energetic'],
61
- 'inspiring': ['inspiring', 'motivational', 'powerful', 'uplifting', 'positive']
62
- }
63
-
64
- theme_hashtags = {
65
- 'love': ['love', 'romance', 'relationship', 'heart', 'passion'],
66
- 'life': ['life', 'journey', 'experience', 'living', 'reality'],
67
- 'time': ['time', 'memories', 'moments', 'forever', 'eternal'],
68
- 'dream': ['dreams', 'aspirations', 'goals', 'future', 'vision'],
69
- 'night': ['night', 'midnight', 'darkness', 'stars', 'nocturnal'],
70
- 'freedom': ['freedom', 'liberation', 'independent', 'free', 'escape']
71
- }
72
-
73
- hashtags = []
74
- base_tags = quality_tags.get(platform, quality_tags['youtube'])
75
- hashtags.extend(base_tags[:5])
76
- hashtags.append(detected_genre)
77
-
78
- if mood in mood_hashtags:
79
- hashtags.extend(mood_hashtags[mood][:2])
80
-
81
- theme_count = 0
82
- for theme in themes[:3]:
83
- if theme in theme_hashtags and theme_count < 2:
84
- hashtags.extend(theme_hashtags[theme][:1])
85
- theme_count += 1
86
-
87
- if artist_name.strip() and artist_name.lower() != 'anonymous':
88
- artist_tag = artist_name.replace(' ', '').lower()
89
- if len(artist_tag) > 2:
90
- hashtags.append(artist_tag)
91
-
92
- additional_quality = ['originalmusic', 'newrelease', 'indieartist', 'musicislife', 'goodmusic', 'musicfan', 'playlist', 'spotify', 'musicdiscovery', 'underground']
93
-
94
- seen = set()
95
- unique_hashtags = []
96
- for tag in hashtags:
97
- tag_lower = tag.lower()
98
- if tag_lower not in seen and tag_lower not in ['subscribe', 'anonymous', 'trending']:
99
- seen.add(tag_lower)
100
- unique_hashtags.append(tag)
101
-
102
- for tag in additional_quality:
103
- if len(unique_hashtags) >= 15 and platform == 'youtube':
104
- break
105
- if len(unique_hashtags) >= 5 and platform == 'minds':
106
- break
107
- if len(unique_hashtags) >= 6 and platform in ['twitter', 'facebook', 'gab']:
108
- break
109
- if len(unique_hashtags) >= 15 and platform == 'instagram':
110
- break
111
- if tag not in seen:
112
- seen.add(tag)
113
- unique_hashtags.append(tag)
114
-
115
- limits = {
116
- 'youtube': 15,
117
- 'instagram': 15,
118
- 'twitter': 6,
119
- 'facebook': 6,
120
- 'minds': 5,
121
- 'gab': 5
122
- }
123
-
124
- limit = limits.get(platform, 10)
125
- final_hashtags = unique_hashtags[:limit]
126
- return ' '.join(f'#{tag}' for tag in final_hashtags)
127
 
128
- def call_modal_ai_generation(lyrics: str, artist_name: str, song_title: str) -> Dict[str, str]:
129
- try:
130
- result = generate_ai_content.remote(lyrics, artist_name, song_title)
131
- return result
132
- except Exception as e:
133
- print(f"Modal AI generation failed: {str(e)}")
134
- return {"error": f"Modal AI generation failed: {str(e)}"}
135
-
136
- def call_modal_template_generation(lyrics: str, artist_name: str, song_title: str) -> Dict[str, str]:
137
- try:
138
- result = generate_template_content.remote(lyrics, artist_name, song_title)
139
- return result
140
- except Exception as e:
141
- print(f"Modal call failed: {str(e)}")
142
- return {"error": f"Modal template generation failed: {str(e)}"}
143
-
144
- def local_fallback_content(lyrics: str, artist_name: str, song_title: str) -> Dict[str, str]:
145
- # ... unchanged fallback generation logic ...
146
- # (You had all platforms covered here in the original. This section remains fully intact.)
147
 
148
- # Extract key words and themes from lyrics
149
- words = re.findall(r'\b[a-zA-Z]{4,}\b', lyrics.lower())
150
- common_words = {'love', 'heart', 'time', 'life', 'feel', 'know', 'want', 'need', 'like', 'come', 'back', 'away', 'never', 'always', 'forever', 'dream', 'night', 'freedom'}
151
- themes = [word for word in set(words) if word in common_words]
152
-
153
- positive_words = {'love', 'happy', 'joy', 'hope', 'dream', 'light', 'beautiful', 'amazing', 'bright', 'inspiring'}
154
- sad_words = {'cry', 'tear', 'pain', 'hurt', 'lost', 'lonely', 'dark', 'goodbye', 'broken'}
155
-
156
- mood = "uplifting"
157
- if any(word in lyrics.lower() for word in sad_words):
158
- mood = "emotional"
159
- elif any(word in lyrics.lower() for word in positive_words):
160
- mood = "inspiring"
161
-
162
- artist_display = artist_name if artist_name.strip() else "Anonymous Artist"
163
- by_artist = f" - {artist_display}" if artist_name.strip() else ""
164
-
165
- youtube_hashtags = generate_smart_hashtags(lyrics, song_title, artist_name, mood, themes, 'youtube')
166
- twitter_hashtags = generate_smart_hashtags(lyrics, song_title, artist_name, mood, themes, 'twitter')
167
- facebook_hashtags = generate_smart_hashtags(lyrics, song_title, artist_name, mood, themes, 'facebook')
168
- instagram_hashtags = generate_smart_hashtags(lyrics, song_title, artist_name, mood, themes, 'instagram')
169
- minds_hashtags = generate_smart_hashtags(lyrics, song_title, artist_name, mood, themes, 'minds')
170
- gab_hashtags = generate_smart_hashtags(lyrics, song_title, artist_name, mood, themes, 'gab')
171
-
172
- # (Omitting for brevity: all the platform-specific templates are still included from your original)
173
- # Return dictionary for all platforms
174
  return {
175
- 'youtube': f"🎵 {song_title}{by_artist} 🎵\n\nExperience this {mood} track...\n\n📝 LYRICS:\n{lyrics}\n\n{youtube_hashtags}",
176
- 'twitter': f"🎵 NEW MUSIC VIDEO: '{song_title}'{by_artist}...\n\n🎬 Watch: [Link]\n\n{twitter_hashtags}",
177
- 'facebook': f"🎵 MUSIC VIDEO PREMIERE 🎵\n\nNew music video for '{song_title}'{by_artist}...\n\n{facebook_hashtags}",
178
- 'instagram': f"🎵✨ '{song_title}' Official Music Video is LIVE! ✨🎵\n\n{instagram_hashtags}",
179
- 'minds': f"🎵 New Music Alert!\n\n{song_title}{by_artist}\n\n{minds_hashtags}",
180
- 'gab': f"New Music Video Drop!\n\n'{song_title}'{by_artist}\n\n{gab_hashtags}"
181
  }
182
 
183
- def create_content(lyrics: str, artist_name: str, song_title: str, use_ai: bool = True):
184
- if not lyrics.strip() or not song_title.strip():
185
- return "❌ Please fill in the required fields: lyrics and song title. Artist name is optional."
186
 
187
- try:
188
- content = None
189
- generation_method = "Unknown"
 
190
 
191
- if use_ai and MODAL_AVAILABLE:
192
- content = call_modal_ai_generation(lyrics, artist_name, song_title)
193
- if "error" not in content:
194
- generation_method = "🤖 AI Generation (Modal GPU)"
195
- else:
196
- content = call_modal_template_generation(lyrics, artist_name, song_title)
197
- generation_method = "📝 Template Generation (Modal)" if "error" not in content else "📝 Local Template Generation (Modal Failed)"
198
- elif MODAL_AVAILABLE:
199
- content = call_modal_template_generation(lyrics, artist_name, song_title)
200
- generation_method = "📝 Template Generation (Modal)" if "error" not in content else "📝 Local Template Generation (Modal Failed)"
201
  else:
202
- content = local_fallback_content(lyrics, artist_name, song_title)
203
- generation_method = "📝 Local Template Generation (Modal Unavailable)"
204
-
205
- artist_display = artist_name if artist_name.strip() else "Anonymous"
206
- output = f"""
207
- # 🎵 Content Generated for '{song_title}' by {artist_display}
208
- *Generated using: {generation_method}*
209
-
210
- ## 📺 YouTube Description:
211
- {content.get('youtube', 'Generation failed')}
212
-
213
- ---
214
-
215
- ## 🐦 Twitter/X Post:
216
- {content.get('twitter', 'Generation failed')}
217
-
218
- ---
219
-
220
- ## 📘 Facebook Post:
221
- {content.get('facebook', 'Generation failed')}
222
-
223
- ---
224
-
225
- ## 📸 Instagram Caption:
226
- {content.get('instagram', 'Generation failed')}
227
 
228
- ---
229
 
230
- ## 🧠 Minds Post:
231
- {content.get('minds', 'Generation failed')}
232
 
233
- ---
 
234
 
235
- ## 💬 Gab Post:
236
- {content.get('gab', 'Generation failed')}
237
- """
238
- return output
239
- except Exception as e:
240
- return f"❌ Error generating content: {str(e)}"
241
 
242
- interface = gr.Interface(
243
- fn=create_content,
244
- inputs=[
245
- gr.Textbox(lines=10, placeholder="Paste your song lyrics here...", label="🎵 Song Lyrics"),
246
- gr.Textbox(placeholder="Artist Name (Optional)", label="🎤 Artist Name"),
247
- gr.Textbox(placeholder="Song Title", label="🎵 Song Title"),
248
- gr.Checkbox(label="🤖 Use AI Generation", value=True)
249
- ],
250
- outputs=gr.Markdown(label="📱 Generated Social Media Content"),
251
- title="🎵 YouTube Music Video Content Creator Agent 🎬",
252
- description=f"""
253
- **Transform your song lyrics into compelling social media content using AI agents!**
254
 
255
- This autonomous AI agent creates:
256
- - YouTube video descriptions with hashtags
257
- - ✅ Platform-optimized content
258
- - ✅ Optional AI generation via Modal
259
 
260
- **💻 Modal Status:** {"✅ Connected" if MODAL_AVAILABLE else "❌ Unavailable (using fallback)"}
261
- """
262
- )
 
 
263
 
264
- if __name__ == "__main__":
265
- interface.launch()
 
 
1
  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
 
30
+ def generate_fallback_content(lyrics, artist, title):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  return {
32
+ 'youtube': f"🎵 {title} by {artist or 'Anonymous'} 🎵\n\n{lyrics[:200]}...\n\n#music #newrelease",
33
+ 'twitter': f"New song: {title} by {artist or 'Anonymous'} is out now! 🎵\n#newmusic #{artist.lower().replace(' ', '') if artist else ''}",
34
+ 'instagram': f"{title} is now available! \nLink in bio\n#music #instamusic",
35
+ 'facebook': f"New music release: {title} by {artist or 'Anonymous'}!\n\n#newmusic #artist",
36
+ 'minds': f"Independent music release: {title}\n\n#independentartist #music",
37
+ 'gab': f"New authentic music: {title}\n\n#realmusic #artist"
38
  }
39
 
40
+ outputs = ['youtube', 'twitter', 'instagram', 'facebook', 'minds', 'gab']
 
 
41
 
42
+ def generate_all_content(lyrics, artist, title):
43
+ start_time = time.time()
44
+ status_msg = "⏳ Generating content..."
45
+ yield {output: "" for output in outputs}, status_msg
46
 
47
+ try:
48
+ if generate_content_with_llm:
49
+ result = generate_content_with_llm.remote(lyrics, artist, title)
50
+ content = result
51
+ status_msg = f"✅ Generated with Modal in {time.time() - start_time:.2f}s"
 
 
 
 
 
52
  else:
53
+ raise RuntimeError("Modal function not available.")
54
+ except Exception as e:
55
+ logger.warning(f"⚠️ Modal generation failed: {e}")
56
+ content = generate_fallback_content(lyrics, artist, title)
57
+ status_msg = f"⚠️ Fallback used. Generated locally in {time.time() - start_time:.2f}s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
+ yield content, status_msg
60
 
 
 
61
 
62
+ with gr.Blocks() as demo:
63
+ gr.Markdown("🎶 **AI Content Generator for Musicians**")
64
 
65
+ with gr.Row():
66
+ lyrics_input = gr.Textbox(lines=5, label="Lyrics")
67
+ with gr.Row():
68
+ artist_input = gr.Textbox(label="Artist Name")
69
+ title_input = gr.Textbox(label="Song Title")
 
70
 
71
+ run_button = gr.Button("Generate Content")
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ output_boxes = {platform: gr.Textbox(label=platform.title()) for platform in outputs}
74
+ status = gr.Markdown("")
 
 
75
 
76
+ run_button.click(
77
+ fn=generate_all_content,
78
+ inputs=[lyrics_input, artist_input, title_input],
79
+ outputs=[output_boxes[p] for p in outputs] + [status]
80
+ )
81
 
82
+ demo.launch()