Ansa12 commited on
Commit
bbc5824
Β·
verified Β·
1 Parent(s): efda241

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +191 -251
app.py CHANGED
@@ -1,18 +1,23 @@
 
 
1
  import gradio as gr
2
- import requests
3
- import json
4
  import re
5
- import os
6
 
7
- # Groq API configuration - will be set via Hugging Face secrets
8
- GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
9
- GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
 
 
 
 
10
 
11
  def generate_story(age, theme, language):
12
- # Check if API key is available
13
- if not GROQ_API_KEY:
14
- return "❌ **Please set your GROQ_API_KEY in Hugging Face Space secrets**\n\nTo use this app:\n1. Go to your Space Settings β†’ Repository secrets\n2. Add a new secret:\n - Name: `GROQ_API_KEY`\n - Value: Your Groq API key from https://console.groq.com\n3. Restart the Space"
15
-
 
16
  age_i = int(age)
17
  if age_i <= 6:
18
  length = "300 words"
@@ -21,186 +26,172 @@ def generate_story(age, theme, language):
21
  else:
22
  length = "1000 words"
23
 
24
- # Prepare the request payload for Groq API
25
- payload = {
26
- "messages": [
27
- {
28
- "role": "system",
29
- "content": "You write age-appropriate stories with complete endings and a moral."
30
- },
31
- {
32
- "role": "user",
33
- "content": (
34
- f"Write a complete story for a {age}-year-old child. "
35
- f"Theme: {theme}. Language: {language}. Length about {length}. "
36
- "End with a clear moral of the story."
37
- )
38
- }
39
- ],
40
- "model": "llama-3.1-8b-instant",
41
- "max_tokens": 2000,
42
- "temperature": 0.8
43
  }
44
 
45
- headers = {
46
- "Authorization": f"Bearer {GROQ_API_KEY}",
47
- "Content-Type": "application/json"
48
- }
 
 
49
 
50
- try:
51
- response = requests.post(GROQ_API_URL, json=payload, headers=headers)
52
- response.raise_for_status()
53
-
54
- data = response.json()
55
- story = data["choices"][0]["message"]["content"].strip()
56
- return story
57
-
58
- except Exception as e:
59
- return f"Error generating story: {str(e)}\n\nPlease check your API key and try again."
60
 
61
  def story_to_speech(story, language_code='en'):
62
- try:
63
- from gtts import gTTS
64
- tts = gTTS(text=story, lang=language_code)
65
- filename = "story.mp3"
66
- tts.save(filename)
67
- return filename
68
- except Exception as e:
69
- print(f"TTS Error: {e}")
70
- return None
71
 
72
  def create_story_interface(age, theme, language, tts_option):
73
  story = generate_story(age, theme, language)
74
 
75
- # Remove Markdown symbols (*, #, _, etc.) to prevent asterisks showing up
76
  story = re.sub(r'[*_#`~]', '', story)
77
 
78
- # Generate audio if TTS is enabled
 
 
 
 
 
 
79
  if language.lower().startswith("u"): # Urdu
 
 
 
 
80
  lang_code = "ur"
81
  else: # English
 
 
 
 
82
  lang_code = "en"
83
 
 
84
  audio_file = story_to_speech(story, lang_code) if tts_option else None
85
 
86
- return story, audio_file
87
 
88
- # Age options
89
  age_options = [str(i) for i in range(3, 13)]
90
-
91
- # Theme options
92
  theme_options = [
93
  "Adventure", "Animals", "Fantasy", "Educational",
94
  "Friendship", "Magic", "Science", "Mystery",
95
  "Space", "Nature", "Kindness", "Courage"
96
  ]
97
-
98
  language_options = ["English", "Urdu"]
99
 
100
- # Create the interface - WITHOUT css parameter
101
- with gr.Blocks() as iface:
102
-
103
- # Inject CSS as HTML
104
- gr.HTML("""
105
- <style>
106
- @import url('https://fonts.googleapis.com/css2?family=Comic+Neue:wght@400;700&display=swap');
107
-
108
- .gradio-container {
109
- font-family: 'Comic Neue', cursive !important;
110
- background: linear-gradient(135deg, #ffafbd, #ffc3a0) !important;
111
- padding: 20px;
112
- min-height: 100vh;
113
- }
114
-
115
- .main-header {
116
- text-align: center;
117
- font-weight: bold;
118
- font-size: 3.2em;
119
- margin: 20px 0;
120
- text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
121
- color: #12979B;
122
- }
123
-
124
- .subtitle {
125
- text-align: center;
126
- font-size: 1.5em;
127
- font-weight: 600;
128
- color: white;
129
- margin: 20px 0;
130
- text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
131
- }
132
-
133
- .control-panel {
134
- background: #fff5ee;
135
- border-radius: 15px;
136
- padding: 20px;
137
- border: 3px dashed #4ECDC4;
138
- margin: 20px 0;
139
- }
140
-
141
- .story-container {
142
- background: #fff5ee;
143
- border-radius: 20px;
144
- padding: 25px;
145
- border: 5px solid #FFD166;
146
- box-shadow: 0 8px 25px rgba(0,0,0,0.1);
147
- min-height: 400px;
148
- margin: 20px 0;
149
- }
150
-
151
- .generate-btn {
152
- background: linear-gradient(45deg, #FF6B6B, #FF9E7D) !important;
153
- border: none !important;
154
- border-radius: 50px !important;
155
- padding: 15px 30px !important;
156
- font-size: 1.2em !important;
157
- font-weight: bold !important;
158
- color: white !important;
159
- margin: 20px 0 !important;
160
- width: 100% !important;
161
- cursor: pointer !important;
162
- }
163
-
164
- .generate-btn:hover {
165
- transform: scale(1.05) !important;
166
- box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4) !important;
167
- }
168
-
169
- .footer {
170
- text-align: center;
171
- margin: 20px 0;
172
- color: #666;
173
- font-style: italic;
174
- font-size: 1.1em;
175
- }
176
-
177
- .warning-box {
178
- background: #fff3cd;
179
- border: 2px solid #ffeaa7;
180
- border-radius: 10px;
181
- padding: 15px;
182
- margin: 20px 0;
183
- }
184
-
185
- /* Style Gradio components */
186
- .gradio-container .dropdown, .gradio-container .checkbox {
187
- background: white !important;
188
- border-radius: 10px !important;
189
- border: 2px solid #96CEB4 !important;
190
- margin: 10px 0 !important;
191
- }
192
-
193
- .gradio-container .audio {
194
- border-radius: 15px !important;
195
- margin: 20px 0 !important;
196
- }
197
- </style>
198
- """)
199
-
200
- # Header
201
  gr.HTML("""
202
  <div class="main-header">
203
- 🌈 StoryTime AI πŸŽͺ
204
  </div>
205
  """)
206
 
@@ -209,108 +200,57 @@ with gr.Blocks() as iface:
209
  🎯 Create amazing stories that spark imagination and teach valuable lessons!
210
  </div>
211
  """)
212
-
213
- # API Key warning
214
- if not GROQ_API_KEY:
215
- gr.HTML("""
216
- <div class="warning-box">
217
- <h3 style="color: #856404; margin: 0 0 10px 0;">⚠️ Setup Required</h3>
218
- <p style="color: #856404; margin: 0;">
219
- To generate stories, please add your <strong>GROQ_API_KEY</strong> in the Hugging Face Space settings:<br>
220
- 1. Go to your Space β†’ Settings β†’ Repository secrets<br>
221
- 2. Add new secret: Name = <code>GROQ_API_KEY</code>, Value = your_api_key<br>
222
- 3. Get your API key from: <a href="https://console.groq.com" target="_blank">https://console.groq.com</a>
223
- </p>
224
- </div>
225
- """)
226
 
227
  with gr.Row():
228
- # Left Column - Controls
229
  with gr.Column(scale=1, min_width=300):
230
- gr.HTML('<div class="control-panel">')
231
- gr.Markdown("### 🎨 Story Settings")
232
-
233
- age_input = gr.Dropdown(
234
- age_options,
235
- label="πŸ‘Ά Child's Age",
236
- value="5",
237
- info="Select age 3-12 years"
238
- )
239
-
240
- theme_input = gr.Dropdown(
241
- theme_options,
242
- label="🎭 Story Theme",
243
- value="Adventure",
244
- info="Choose your favorite theme"
245
- )
246
-
247
- language_input = gr.Dropdown(
248
- language_options,
249
- label="🌍 Language",
250
- value="English",
251
- info="English or Urdu"
252
- )
253
-
254
- tts_input = gr.Checkbox(
255
- label="πŸ”Š Include Audio Story",
256
- value=True,
257
- info="Generate audio narration"
258
- )
259
-
260
- gr.HTML('</div>')
261
-
262
- generate_btn = gr.Button(
263
- "✨ Create Magical Story! ✨"
264
- )
265
-
266
- # Right Column - Output
267
  with gr.Column(scale=2):
268
- gr.HTML('<div class="story-container">')
269
- gr.Markdown("### πŸ“– Your Magical Story")
270
- story_output = gr.Markdown(
271
- "🌟 **Welcome to StoryTime AI!** 🌟\n\nChoose your story settings on the left and click the magic button to create a wonderful story! Your adventure begins here...",
272
- show_label=False
273
- )
274
- gr.HTML('</div>')
275
-
276
- gr.Markdown("### 🎧 Listen to Your Story")
277
- audio_output = gr.Audio(
278
- label="",
279
- show_label=False,
280
- interactive=False
281
- )
282
-
283
- # Footer
284
  gr.HTML("""
285
  <div class="footer">
286
  Made with ❀️ for young readers everywhere! | Watch your stories come to life! ✨
287
  </div>
288
  """)
289
 
290
- # Apply button styling with JavaScript
291
- gr.HTML("""
292
- <script>
293
- function styleButton() {
294
- const buttons = document.querySelectorAll('button');
295
- buttons.forEach(button => {
296
- if (button.textContent.includes('Create Magical Story')) {
297
- button.classList.add('generate-btn');
298
- }
299
- });
300
- }
301
- // Style button on load and when DOM changes
302
- document.addEventListener('DOMContentLoaded', styleButton);
303
- setTimeout(styleButton, 1000);
304
- setInterval(styleButton, 2000);
305
- </script>
306
- """)
307
-
308
  generate_btn.click(
309
  create_story_interface,
310
- inputs=[age_input, theme_input, language_input, tts_input],
311
- outputs=[story_output, audio_output]
312
  )
313
 
314
- # Launch without SSR to avoid the warning
315
  if __name__ == "__main__":
316
- iface.launch(ssr_mode=False)
 
1
+ import os
2
+ from groq import Groq
3
  import gradio as gr
4
+ from gtts import gTTS
 
5
  import re
 
6
 
7
+ # Get API key from Hugging Face Secrets
8
+ groq_key = os.environ.get("GROQ_API_KEY")
9
+
10
+ if not groq_key:
11
+ raise ValueError("GROQ_API_KEY not found in environment variables. Please add it to your Hugging Face Space secrets.")
12
+
13
+ client = Groq(api_key=groq_key)
14
 
15
  def generate_story(age, theme, language):
16
+ system_msg = {
17
+ "role": "system",
18
+ "content": "You write age-appropriate stories with complete endings and a moral."
19
+ }
20
+
21
  age_i = int(age)
22
  if age_i <= 6:
23
  length = "300 words"
 
26
  else:
27
  length = "1000 words"
28
 
29
+ user_msg = {
30
+ "role": "user",
31
+ "content": (
32
+ f"Write a complete story for a {age}-year-old child. "
33
+ f"Theme: {theme}. Language: {language}. Length about {length}. "
34
+ "End with a clear moral of the story."
35
+ )
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
+ response = client.chat.completions.create(
39
+ messages=[system_msg, user_msg],
40
+ model="llama-3.3-70b-versatile",
41
+ max_tokens=2000,
42
+ temperature=0.8
43
+ )
44
 
45
+ return response.choices[0].message.content.strip()
 
 
 
 
 
 
 
 
 
46
 
47
  def story_to_speech(story, language_code='en'):
48
+ tts = gTTS(text=story, lang=language_code)
49
+ filename = "story.mp3"
50
+ tts.save(filename)
51
+ return filename
 
 
 
 
 
52
 
53
  def create_story_interface(age, theme, language, tts_option):
54
  story = generate_story(age, theme, language)
55
 
56
+ # Remove Markdown symbols
57
  story = re.sub(r'[*_#`~]', '', story)
58
 
59
+ # Split first line as title
60
+ lines = story.split("\n", 1)
61
+ if len(lines) > 1:
62
+ title, rest_of_story = lines[0], lines[1]
63
+ else:
64
+ title, rest_of_story = lines[0], ""
65
+
66
  if language.lower().startswith("u"): # Urdu
67
+ story_html = (
68
+ f'<div style="text-align:center; font-size:1.3em; direction:rtl; margin-bottom:5px;">{title}</div>'
69
+ f'<div style="font-size:1.2em; direction:rtl; text-align:right;">{rest_of_story}</div>'
70
+ )
71
  lang_code = "ur"
72
  else: # English
73
+ story_html = (
74
+ f'<div style="text-align:center; font-size:1.3em; direction:ltr; margin-bottom:5px;">{title}</div>'
75
+ f'<div style="font-size:1.2em; direction:ltr; text-align:left;">{rest_of_story}</div>'
76
+ )
77
  lang_code = "en"
78
 
79
+ # Generate audio if TTS is enabled
80
  audio_file = story_to_speech(story, lang_code) if tts_option else None
81
 
82
+ return story_html, audio_file
83
 
 
84
  age_options = [str(i) for i in range(3, 13)]
 
 
85
  theme_options = [
86
  "Adventure", "Animals", "Fantasy", "Educational",
87
  "Friendship", "Magic", "Science", "Mystery",
88
  "Space", "Nature", "Kindness", "Courage"
89
  ]
 
90
  language_options = ["English", "Urdu"]
91
 
92
+ # Custom CSS for child-friendly interface
93
+ custom_css = """
94
+ @import url('https://fonts.googleapis.com/css2?family=Comic+Neue:wght@400;700&display=swap');
95
+
96
+ .gradio-container {
97
+ font-family: 'Comic Neue', cursive !important;
98
+ background: linear-gradient(135deg, #ffafbd, #ffc3a0) !important;
99
+ padding-top: 10px !important;
100
+ margin-top: -70px !important;
101
+ }
102
+
103
+ .main-header {
104
+ text-align: center;
105
+ font-weight: bold !important;
106
+ font-size: 3.2em !important;
107
+ margin-top: 40px !important;
108
+ margin-bottom: 20px !important;
109
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
110
+ color: #12979B;
111
+ }
112
+
113
+ .story-container {
114
+ background:#fff5ee;
115
+ border-radius: 20px;
116
+ padding: 25px;
117
+ border: 5px solid #FFD166;
118
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
119
+ min-height: 400px;
120
+ margin-top: -20px !important;
121
+ }
122
+
123
+ .control-panel {
124
+ background: #fff5ee;;
125
+ border-radius: 15px;
126
+ padding: 20px;
127
+ border: 3px dashed #4ECDC4;
128
+ font-size: 1.2em !important;
129
+ font-weight: 600;
130
+ margin-top: -20px !important;
131
+ }
132
+
133
+ .generate-btn {
134
+ background: linear-gradient(45deg, #FF6B6B, #FF9E7D) !important;
135
+ border: none !important;
136
+ border-radius: 50px !important;
137
+ padding: 10px 22px !important;
138
+ font-size: 1em !important;
139
+ font-weight: bold !important;
140
+ color: white !important;
141
+ margin-top: 20px !important;
142
+ }
143
+
144
+ .generate-btn:hover {
145
+ transform: scale(1.05);
146
+ box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4);
147
+ }
148
+
149
+ .dropdown, .checkbox {
150
+ background: white !important;
151
+ border-radius: 10px !important;
152
+ border: 2px solid #96CEB4 !important;
153
+ }
154
+
155
+ .audio-player {
156
+ border-radius: 15px !important;
157
+ margin-top: 20px;
158
+ }
159
+
160
+ .subtitle {
161
+ text-align: left;
162
+ font-size: 1.5em !important;
163
+ font-weight: 600;
164
+ color: white;
165
+ margin-top: -10px !important;
166
+ margin-bottom: 20px;
167
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
168
+ }
169
+
170
+ .control-panel .gr-Markdown {
171
+ font-size: 1.5em !important;
172
+ }
173
+
174
+ .story-container .gr-Markdown {
175
+ font-size: 1.5em !important;
176
+ }
177
+
178
+ .footer {
179
+ text-align: center;
180
+ margin-top: 20px;
181
+ color: #666;
182
+ font-style: italic;
183
+ font-size: 1.5em !important;
184
+ }
185
+
186
+ .main-header + div {
187
+ margin-top: -145px !important;
188
+ }
189
+ """
190
+
191
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as iface:
 
192
  gr.HTML("""
193
  <div class="main-header">
194
+ 🌈 StoryTime AIπŸŽͺ
195
  </div>
196
  """)
197
 
 
200
  🎯 Create amazing stories that spark imagination and teach valuable lessons!
201
  </div>
202
  """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
  with gr.Row():
 
205
  with gr.Column(scale=1, min_width=300):
206
+ with gr.Group(elem_classes="control-panel"):
207
+ gr.Markdown("### 🎨 Story Settings")
208
+
209
+ with gr.Group():
210
+ gr.Markdown("πŸ‘Ά **Child's Age**")
211
+ age_input = gr.Dropdown(age_options, label="", value="5", show_label=False)
212
+
213
+ with gr.Group():
214
+ gr.Markdown("🎭 **Story Theme**")
215
+ theme_input = gr.Dropdown(theme_options, label="", value="Adventure", show_label=False)
216
+
217
+ with gr.Group():
218
+ gr.Markdown("🌍 **Language**")
219
+ language_input = gr.Dropdown(language_options, label="", value="English", show_label=False)
220
+
221
+ with gr.Group():
222
+ gr.Markdown("πŸ”Š **Audio Options**")
223
+ tts_input = gr.Checkbox(label="🎡 Include Audio Story", value=True)
224
+
225
+ generate_btn = gr.Button("✨ Create Magical Story! ✨", elem_classes="generate-btn", size="lg")
226
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  with gr.Column(scale=2):
228
+ with gr.Group(elem_classes="story-container"):
229
+ gr.Markdown("### πŸ“– Your Magical Story")
230
+ story_output = gr.Markdown(
231
+ "Your story will appear here! Choose settings and click the magic button! πŸŽ‡",
232
+ show_label=False
233
+ )
234
+
235
+ with gr.Group():
236
+ gr.Markdown("### 🎧 Listen to Your Story")
237
+ audio_output = gr.Audio(
238
+ label="Audio Story",
239
+ elem_classes="audio-player",
240
+ show_label=False
241
+ )
242
+
 
243
  gr.HTML("""
244
  <div class="footer">
245
  Made with ❀️ for young readers everywhere! | Watch your stories come to life! ✨
246
  </div>
247
  """)
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  generate_btn.click(
250
  create_story_interface,
251
+ [age_input, theme_input, language_input, tts_input],
252
+ [story_output, audio_output]
253
  )
254
 
 
255
  if __name__ == "__main__":
256
+ iface.launch()