MySafeCode commited on
Commit
2232aef
·
verified ·
1 Parent(s): bb93e1d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +220 -35
app.py CHANGED
@@ -10,14 +10,17 @@ import sys
10
  logging.basicConfig(level=logging.INFO)
11
  logger = logging.getLogger(__name__)
12
 
 
 
 
13
 
14
- # Suno API key
15
  api_key = os.environ.get("Key", "")
16
  if not api_key:
17
- print("⚠️ SunoKey not set!")
18
-
19
- # Print Gradio version for debugging
20
- logger.info(f"Gradio version: {gr.__version__}")
21
 
22
  # Import BytePlus SDK
23
  try:
@@ -29,27 +32,50 @@ except ImportError as e:
29
  SDK_AVAILABLE = False
30
  logger.warning(f"⚠️ BytePlus SDK not available: {e}")
31
 
32
- def generate_video(api_key, prompt_text, image_url, model_id, progress=gr.Progress()):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  """Generate video using the BytePlus SDK"""
34
 
35
- if not api_key or api_key == "key":
36
- yield "⚠️ Please enter your actual BytePlus API key (the 'key' is just a placeholder)", None
 
 
 
37
  return
38
 
39
  if not SDK_AVAILABLE:
40
- yield "❌ BytePlus SDK not available. Please check installation of byteplus-python-sdk-v2", None
41
  return
42
 
43
  try:
44
  progress(0, desc="Initializing SDK...")
45
 
46
- # Set environment variable
47
- os.environ["Key"] = api_key
 
 
 
 
 
 
48
 
49
  # Initialize client
50
  client = Ark(
51
  base_url="https://ark.ap-southeast.bytepluses.com/api/v3",
52
- api_key=os.environ.get("Key"),
53
  )
54
 
55
  progress(0.1, desc="Creating video generation request...")
@@ -124,54 +150,213 @@ def generate_video(api_key, prompt_text, image_url, model_id, progress=gr.Progre
124
  logger.error(f"Error: {e}")
125
  yield f"❌ Error: {str(e)}", None
126
 
127
- # Simple, clean UI
128
- with gr.Blocks(title="BytePlus Video Generator", theme=gr.themes.Soft()) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  gr.Markdown("""
130
  # 🎥 BytePlus Video Generator
131
- Generate videos from images and text prompts
132
  """)
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  with gr.Row():
135
- with gr.Column():
136
- api_key = gr.Textbox(
137
- label="🔑 API Key",
 
 
 
 
 
 
 
 
 
 
138
  type="password",
139
- placeholder="Enter your BytePlus API key",
140
- value="key"
 
 
 
 
 
141
  )
142
 
 
143
  model_id = gr.Textbox(
144
  label="🤖 Model ID",
145
- value="seedance-1-5-pro-251215"
 
146
  )
147
 
 
148
  image_url = gr.Textbox(
149
- label="🖼️ Image URL",
150
- value="https://ark-doc.tos-ap-southeast-1.bytepluses.com/seepro_i2v%20.png"
 
 
151
  )
152
 
 
 
 
 
 
 
 
 
153
  prompt = gr.Textbox(
154
- label="📝 Prompt",
155
- lines=3,
156
- value="At breakneck speed, drones thread through intricate obstacles --duration 5 --camerafixed false"
 
157
  )
158
 
159
- generate_btn = gr.Button("🚀 Generate", variant="primary")
 
160
 
161
- with gr.Column():
162
- status = gr.Textbox(label="Status", lines=3)
163
- video = gr.Video(label="Generated Video")
164
- video_url = gr.Textbox(label="Video URL")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
- generate_btn.click(
 
 
 
 
 
 
 
 
 
 
 
 
167
  fn=generate_video,
168
- inputs=[api_key, prompt, image_url, model_id],
169
  outputs=[status, video]
170
- ).then(
 
 
 
171
  fn=lambda url: url if url else "",
172
  inputs=[video],
173
  outputs=[video_url]
174
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
  if __name__ == "__main__":
177
- demo.launch()
 
 
 
 
 
 
 
 
10
  logging.basicConfig(level=logging.INFO)
11
  logger = logging.getLogger(__name__)
12
 
13
+ # Print versions for debugging
14
+ logger.info(f"Gradio version: {gr.__version__}")
15
+ logger.info(f"Python version: {sys.version}")
16
 
17
+ # Get API key from environment variable "Key"
18
  api_key = os.environ.get("Key", "")
19
  if not api_key:
20
+ logger.warning("⚠️ API Key not set in environment variable 'Key'!")
21
+ logger.info("Will use input field instead")
22
+ else:
23
+ logger.info(" API Key loaded from environment")
24
 
25
  # Import BytePlus SDK
26
  try:
 
32
  SDK_AVAILABLE = False
33
  logger.warning(f"⚠️ BytePlus SDK not available: {e}")
34
 
35
+ def initialize_sdk_config():
36
+ """Initialize SDK configuration as per docs"""
37
+ try:
38
+ configuration = byteplussdkcore.Configuration()
39
+ configuration.client_side_validation = True
40
+ configuration.schema = "http"
41
+ configuration.debug = False
42
+ configuration.logger_file = "sdk.log"
43
+ byteplussdkcore.Configuration.set_default(configuration)
44
+ return True
45
+ except Exception as e:
46
+ logger.error(f"SDK config error: {e}")
47
+ return False
48
+
49
+ def generate_video(input_api_key, prompt_text, image_url, model_id, progress=gr.Progress()):
50
  """Generate video using the BytePlus SDK"""
51
 
52
+ # Use input API key if provided, otherwise fall back to environment variable
53
+ effective_api_key = input_api_key if input_api_key and input_api_key != "key" else api_key
54
+
55
+ if not effective_api_key:
56
+ yield "⚠️ Please enter your BytePlus API key or set it in the 'Key' environment variable", None
57
  return
58
 
59
  if not SDK_AVAILABLE:
60
+ yield "❌ BytePlus SDK not available. Please check installation.", None
61
  return
62
 
63
  try:
64
  progress(0, desc="Initializing SDK...")
65
 
66
+ # Initialize SDK config
67
+ try:
68
+ initialize_sdk_config()
69
+ except:
70
+ pass # Continue even if config fails
71
+
72
+ # Set environment variable for SDK (it expects ARK_API_KEY)
73
+ os.environ["ARK_API_KEY"] = effective_api_key
74
 
75
  # Initialize client
76
  client = Ark(
77
  base_url="https://ark.ap-southeast.bytepluses.com/api/v3",
78
+ api_key=os.environ.get("ARK_API_KEY"),
79
  )
80
 
81
  progress(0.1, desc="Creating video generation request...")
 
150
  logger.error(f"Error: {e}")
151
  yield f"❌ Error: {str(e)}", None
152
 
153
+ # Custom CSS
154
+ custom_css = """
155
+ .gradio-container {
156
+ max-width: 1200px !important;
157
+ margin: auto !important;
158
+ }
159
+ .video-container {
160
+ border-radius: 8px;
161
+ overflow: hidden;
162
+ }
163
+ .env-badge {
164
+ background: #e3f2fd;
165
+ color: #0d47a1;
166
+ padding: 5px 10px;
167
+ border-radius: 4px;
168
+ font-size: 0.9em;
169
+ margin-bottom: 10px;
170
+ }
171
+ """
172
+
173
+ # Create Gradio interface
174
+ with gr.Blocks(title="BytePlus Video Generator") as demo:
175
+
176
  gr.Markdown("""
177
  # 🎥 BytePlus Video Generator
178
+ Generate stunning videos from images and text prompts using BytePlus AI
179
  """)
180
 
181
+ # Show API key source
182
+ if api_key:
183
+ gr.Markdown("""
184
+ <div class="env-badge">
185
+ ✅ API Key loaded from environment variable 'Key'
186
+ </div>
187
+ """)
188
+ else:
189
+ gr.Markdown("""
190
+ <div class="env-badge" style="background: #fff3e0; color: #bf360c;">
191
+ ⚠️ No API Key in environment variable 'Key'. Please enter below.
192
+ </div>
193
+ """)
194
+
195
+ # SDK Status
196
  with gr.Row():
197
+ if SDK_AVAILABLE:
198
+ gr.Markdown("✅ **SDK Status:** Connected to BytePlus SDK")
199
+ else:
200
+ gr.Markdown("❌ **SDK Status:** SDK not available")
201
+
202
+ gr.Markdown("---")
203
+
204
+ with gr.Row():
205
+ with gr.Column(scale=1):
206
+ # API Key input - will use env var as default if available
207
+ api_key_input = gr.Textbox(
208
+ label="🔑 BytePlus API Key",
209
+ placeholder="Enter your BytePlus API key here",
210
  type="password",
211
+ value="key" if not api_key else "", # Empty if env var exists
212
+ info=f"Using env var 'Key' by default. Enter only to override."
213
+ )
214
+
215
+ # Show if env var is being used
216
+ env_status = gr.Markdown(
217
+ f"*Using environment variable 'Key'*" if api_key else "*Enter API key above*"
218
  )
219
 
220
+ # Model ID
221
  model_id = gr.Textbox(
222
  label="🤖 Model ID",
223
+ value="seedance-1-5-pro-251215",
224
+ info="Model ID for video generation"
225
  )
226
 
227
+ # Image URL input
228
  image_url = gr.Textbox(
229
+ label="🔗 Image URL",
230
+ placeholder="Enter public image URL",
231
+ value="https://ark-doc.tos-ap-southeast-1.bytepluses.com/seepro_i2v%20.png",
232
+ info="Image must be publicly accessible"
233
  )
234
 
235
+ # Image preview
236
+ image_preview = gr.Image(
237
+ label="Image Preview",
238
+ type="pil",
239
+ height=200
240
+ )
241
+
242
+ # Text prompt
243
  prompt = gr.Textbox(
244
+ label="📝 Text Prompt",
245
+ placeholder="Describe your video...",
246
+ value="At breakneck speed, drones thread through intricate obstacles or stunning natural wonders, delivering an immersive, heart-pounding flying experience. --duration 5 --camerafixed false",
247
+ lines=4
248
  )
249
 
250
+ # Generate button
251
+ generate_btn = gr.Button("🚀 Generate Video", variant="primary")
252
 
253
+ with gr.Column(scale=1):
254
+ # Status output
255
+ status = gr.Textbox(
256
+ label="📊 Generation Status",
257
+ lines=5
258
+ )
259
+
260
+ # Video output
261
+ video = gr.Video(
262
+ label="🎬 Generated Video",
263
+ show_download_button=True,
264
+ show_share_button=True
265
+ )
266
+
267
+ # Video URL
268
+ video_url = gr.Textbox(
269
+ label="🔗 Video URL",
270
+ interactive=False
271
+ )
272
+
273
+ # Example prompts
274
+ gr.Markdown("---")
275
+ gr.Markdown("## 📋 Example Prompts")
276
+
277
+ with gr.Row():
278
+ example1 = gr.Button("🌄 Nature Drone")
279
+ example2 = gr.Button("🏙️ City Racing")
280
+ example3 = gr.Button("🌊 Ocean Waves")
281
+
282
+ # Function to update image preview
283
+ def update_preview(url):
284
+ try:
285
+ if url and url.startswith(('http://', 'https://')):
286
+ import requests
287
+ from io import BytesIO
288
+
289
+ response = requests.get(url, timeout=5)
290
+ img = Image.open(BytesIO(response.content))
291
+ return img
292
+ return None
293
+ except:
294
+ return None
295
+
296
+ # Example prompt functions
297
+ def set_nature():
298
+ return "Aerial drone shot flying over majestic mountains at sunrise, cinematic lighting, smooth motion --duration 5 --camerafixed false"
299
+
300
+ def set_city():
301
+ return "Fast-paced drone racing through futuristic city streets with neon lights, dynamic angles, high speed --duration 5 --camerafixed false"
302
+
303
+ def set_ocean():
304
+ return "Drone following surfers riding massive waves, slow motion, dramatic ocean views, golden hour --duration 5 --camerafixed false"
305
 
306
+ # Connect events
307
+ image_url.change(
308
+ fn=update_preview,
309
+ inputs=image_url,
310
+ outputs=image_preview
311
+ )
312
+
313
+ example1.click(fn=set_nature, outputs=prompt)
314
+ example2.click(fn=set_city, outputs=prompt)
315
+ example3.click(fn=set_ocean, outputs=prompt)
316
+
317
+ # Generate
318
+ generate_event = generate_btn.click(
319
  fn=generate_video,
320
+ inputs=[api_key_input, prompt, image_url, model_id],
321
  outputs=[status, video]
322
+ )
323
+
324
+ # Update video URL
325
+ generate_event.then(
326
  fn=lambda url: url if url else "",
327
  inputs=[video],
328
  outputs=[video_url]
329
  )
330
+
331
+ # Clear button
332
+ clear_btn = gr.Button("🗑️ Clear", variant="secondary")
333
+ clear_btn.click(
334
+ fn=lambda: (
335
+ "key" if not api_key else "", # Reset API key input
336
+ "https://ark-doc.tos-ap-southeast-1.bytepluses.com/seepro_i2v%20.png",
337
+ "Enter your prompt here...",
338
+ "",
339
+ None,
340
+ ""
341
+ ),
342
+ outputs=[api_key_input, image_url, prompt, status, video, video_url]
343
+ )
344
+
345
+ # Footer
346
+ gr.Markdown("---")
347
+ gr.Markdown("""
348
+ <div style='text-align: center'>
349
+ <p>Powered by BytePlus SDK | Gradio 6.5.1</p>
350
+ <p style='font-size: 0.8em; color: gray;'>API key sourced from environment variable 'Key'</p>
351
+ </div>
352
+ """)
353
 
354
  if __name__ == "__main__":
355
+ demo.launch(
356
+ server_name="0.0.0.0",
357
+ theme=gr.themes.Soft(
358
+ primary_hue="blue",
359
+ secondary_hue="purple",
360
+ ),
361
+ css=custom_css
362
+ )