rairo commited on
Commit
27077ed
Β·
verified Β·
1 Parent(s): cfd4972

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +50 -68
main.py CHANGED
@@ -13,6 +13,11 @@ from flask_cors import CORS, cross_origin
13
  from firebase_admin import credentials, db, storage, auth
14
  import firebase_admin
15
 
 
 
 
 
 
16
  # Initialize Flask app and CORS
17
  app = Flask(__name__)
18
  CORS(app)
@@ -21,6 +26,9 @@ CORS(app)
21
  Firebase_DB = os.getenv("Firebase_DB")
22
  Firebase_Storage = os.getenv("Firebase_Storage")
23
 
 
 
 
24
  try:
25
  # Retrieve the JSON content from the secret
26
  credentials_json_string = os.environ.get("FIREBASE")
@@ -169,6 +177,16 @@ def get_user_profile():
169
  return jsonify({'error': str(e)}), 500
170
 
171
 
 
 
 
 
 
 
 
 
 
 
172
 
173
  # -----------------------
174
  # Content
@@ -334,60 +352,64 @@ def generate_story_endpoint():
334
  return jsonify({'error': str(e)}), 500
335
 
336
  # ---------- Video Generation Endpoint ----------
 
 
 
 
 
337
  @app.route('/api/video/generate', methods=['POST'])
338
  def generate_video_endpoint():
339
  try:
340
- print("➑️ Received video generation request...")
341
-
342
- # Verify user token
343
  auth_header = request.headers.get('Authorization', '')
344
  if not auth_header.startswith('Bearer '):
345
- print("❌ ERROR: Missing or invalid token")
346
- return jsonify({'error': 'Missing or invalid token'}), 401
347
 
348
  token = auth_header.split(' ')[1]
349
  uid = verify_token(token)
350
  if not uid:
351
- print("❌ ERROR: Invalid or expired token")
352
- return jsonify({'error': 'Invalid or expired token'}), 401
353
 
354
  data = request.get_json()
355
  story_id = data.get('story_id')
356
  if not story_id:
357
- print("❌ ERROR: story_id is required")
358
- return jsonify({'error': 'story_id is required'}), 400
359
 
360
- print(f"Fetching story {story_id} from Firebase...")
361
  story_ref = db.reference(f"stories/{story_id}")
362
  story_data = story_ref.get()
363
 
364
  if not story_data:
365
- print("❌ ERROR: Story not found")
366
- return jsonify({'error': 'Story not found'}), 404
367
 
368
  sections = story_data.get("sections", [])
369
  if not sections:
370
- print("❌ ERROR: No sections found in the story")
371
- return jsonify({'error': 'No sections found in the story'}), 404
372
 
373
  image_files = []
374
  audio_files = []
375
-
376
- print(f"Processing {len(sections)} sections...")
377
 
378
  for section in sections:
379
  image_url = section.get("image_url")
380
  audio_url = section.get("audio_url")
381
 
382
- print(f"➑️ Downloading image from: {image_url}")
383
  img_resp = requests.get(image_url)
384
  if img_resp.status_code == 200:
385
  img = Image.open(io.BytesIO(img_resp.content))
386
  image_files.append(img)
387
  else:
388
- print(f"❌ ERROR: Failed to download image {image_url}")
389
 
390
- print(f"➑️ Downloading audio from: {audio_url}")
391
  aud_resp = requests.get(audio_url)
392
  if aud_resp.status_code == 200:
393
  aud_path = f"/tmp/{uuid.uuid4().hex}.mp3"
@@ -395,66 +417,26 @@ def generate_video_endpoint():
395
  f.write(aud_resp.content)
396
  audio_files.append(aud_path)
397
  else:
398
- print(f"❌ ERROR: Failed to download audio {audio_url}")
399
 
400
  if not image_files:
401
- print("❌ ERROR: No valid images found")
402
- return jsonify({'error': 'No images available for video generation'}), 500
403
 
404
- # Generate video
405
  video_output_path = f"/tmp/{uuid.uuid4().hex}.mp4"
406
  video_file = create_silent_video(image_files, [5.0] * len(image_files), video_output_path)
407
 
408
  if not video_file:
409
- print("❌ ERROR: Video generation failed")
410
- return jsonify({'error': 'Video generation failed'}), 500
411
 
412
- print(f"βœ… Video generated successfully: {video_file}")
413
 
414
- return jsonify({"video_url": video_file})
415
 
416
  except Exception as e:
417
- print(f"❌ ERROR: {e}")
418
- return jsonify({'error': str(e)}), 500
419
-
420
-
421
- # ---------- Audio Generation Endpoint ----------
422
- @app.route('/api/audio/generate', methods=['POST'])
423
- def generate_audio_edit():
424
- try:
425
- auth_header = request.headers.get('Authorization', '')
426
- if not auth_header.startswith('Bearer '):
427
- return jsonify({'error': 'Authorization header missing or malformed'}), 401
428
- token = auth_header.split(' ')[1]
429
- uid = verify_token(token)
430
- if not uid:
431
- return jsonify({'error': 'Invalid token'}), 401
432
-
433
- # Get user data and check credits
434
- user_ref = db.reference(f'users/{uid}')
435
- user_data = user_ref.get()
436
- if not user_data or user_data.get('credits', 0) < 1:
437
- return jsonify({'error': 'Insufficient credits'}), 400
438
-
439
- # Deduct one credit
440
- new_credits = user_data.get('credits', 0) - 1
441
- user_ref.update({'credits': new_credits})
442
-
443
- # Get prompt and generate video (simulation using Gemini)
444
- req_data = request.get_json()
445
- prompt = req_data.get('prompt', '')
446
- if not prompt:
447
- return jsonify({'error': 'Prompt is required'}), 400
448
-
449
-
450
-
451
- return jsonify({
452
- 'success': True,
453
- 'audio': generated_audio,
454
- 'remaining_credits': new_credits
455
- })
456
- except Exception as e:
457
- return jsonify({'error': str(e)}), 500
458
 
459
 
460
  #----------Image Generation Endpoint ----------
 
13
  from firebase_admin import credentials, db, storage, auth
14
  import firebase_admin
15
 
16
+ import logging
17
+ import traceback
18
+
19
+
20
+
21
  # Initialize Flask app and CORS
22
  app = Flask(__name__)
23
  CORS(app)
 
26
  Firebase_DB = os.getenv("Firebase_DB")
27
  Firebase_Storage = os.getenv("Firebase_Storage")
28
 
29
+
30
+ LOG_FILE_PATH = "/tmp/video_gen.log"
31
+
32
  try:
33
  # Retrieve the JSON content from the secret
34
  credentials_json_string = os.environ.get("FIREBASE")
 
177
  return jsonify({'error': str(e)}), 500
178
 
179
 
180
+ def upload_log():
181
+ """Uploads the log file to Firebase Storage and returns the download URL."""
182
+ try:
183
+ log_blob_name = f"logs/{uuid.uuid4().hex}.log"
184
+ log_url = upload_to_storage(LOG_FILE_PATH, log_blob_name)
185
+ return log_url
186
+ except Exception as e:
187
+ logging.error(f"❌ ERROR: Failed to upload log file: {e}")
188
+ return None
189
+
190
 
191
  # -----------------------
192
  # Content
 
352
  return jsonify({'error': str(e)}), 500
353
 
354
  # ---------- Video Generation Endpoint ----------
355
+
356
+
357
+ # Configure logging to write to a file
358
+ logging.basicConfig(filename=LOG_FILE_PATH, level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
359
+
360
  @app.route('/api/video/generate', methods=['POST'])
361
  def generate_video_endpoint():
362
  try:
363
+ logging.info("➑️ Received video generation request...")
364
+
 
365
  auth_header = request.headers.get('Authorization', '')
366
  if not auth_header.startswith('Bearer '):
367
+ logging.error("❌ ERROR: Missing or invalid token")
368
+ return jsonify({'error': 'Missing or invalid token', 'log_url': upload_log()}), 401
369
 
370
  token = auth_header.split(' ')[1]
371
  uid = verify_token(token)
372
  if not uid:
373
+ logging.error("❌ ERROR: Invalid or expired token")
374
+ return jsonify({'error': 'Invalid or expired token', 'log_url': upload_log()}), 401
375
 
376
  data = request.get_json()
377
  story_id = data.get('story_id')
378
  if not story_id:
379
+ logging.error("❌ ERROR: story_id is required")
380
+ return jsonify({'error': 'story_id is required', 'log_url': upload_log()}), 400
381
 
382
+ logging.info(f"Fetching story {story_id} from Firebase...")
383
  story_ref = db.reference(f"stories/{story_id}")
384
  story_data = story_ref.get()
385
 
386
  if not story_data:
387
+ logging.error("❌ ERROR: Story not found")
388
+ return jsonify({'error': 'Story not found', 'log_url': upload_log()}), 404
389
 
390
  sections = story_data.get("sections", [])
391
  if not sections:
392
+ logging.error("❌ ERROR: No sections found in the story")
393
+ return jsonify({'error': 'No sections found in the story', 'log_url': upload_log()}), 404
394
 
395
  image_files = []
396
  audio_files = []
397
+
398
+ logging.info(f"Processing {len(sections)} sections...")
399
 
400
  for section in sections:
401
  image_url = section.get("image_url")
402
  audio_url = section.get("audio_url")
403
 
404
+ logging.info(f"➑️ Downloading image from: {image_url}")
405
  img_resp = requests.get(image_url)
406
  if img_resp.status_code == 200:
407
  img = Image.open(io.BytesIO(img_resp.content))
408
  image_files.append(img)
409
  else:
410
+ logging.error(f"❌ ERROR: Failed to download image {image_url}")
411
 
412
+ logging.info(f"➑️ Downloading audio from: {audio_url}")
413
  aud_resp = requests.get(audio_url)
414
  if aud_resp.status_code == 200:
415
  aud_path = f"/tmp/{uuid.uuid4().hex}.mp3"
 
417
  f.write(aud_resp.content)
418
  audio_files.append(aud_path)
419
  else:
420
+ logging.error(f"❌ ERROR: Failed to download audio {audio_url}")
421
 
422
  if not image_files:
423
+ logging.error("❌ ERROR: No valid images found")
424
+ return jsonify({'error': 'No images available for video generation', 'log_url': upload_log()}), 500
425
 
 
426
  video_output_path = f"/tmp/{uuid.uuid4().hex}.mp4"
427
  video_file = create_silent_video(image_files, [5.0] * len(image_files), video_output_path)
428
 
429
  if not video_file:
430
+ logging.error("❌ ERROR: Video generation failed")
431
+ return jsonify({'error': 'Video generation failed', 'log_url': upload_log()}), 500
432
 
433
+ logging.info(f"βœ… Video generated successfully: {video_file}")
434
 
435
+ return jsonify({"video_url": video_file, "log_url": upload_log()})
436
 
437
  except Exception as e:
438
+ logging.error(f"❌ ERROR: {e}\n{traceback.format_exc()}")
439
+ return jsonify({'error': str(e), 'log_url': upload_log()}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
 
441
 
442
  #----------Image Generation Endpoint ----------