Spaces:
Runtime error
Runtime error
| import os | |
| import requests | |
| import json | |
| import base64 | |
| import time | |
| from flask import Flask, request, jsonify, send_file | |
| app = Flask(__name__) | |
| # ===== SECRETS ===== | |
| AGNES_API_KEY = os.environ.get("AGNES_API_KEY") | |
| if not AGNES_API_KEY: | |
| print("⚠️ AGNES_API_KEY not set! Get from agnes-ai.com") | |
| # ===== AGNES AI API ===== | |
| AGNES_BASE = "https://apihub.agnes-ai.com/v1" | |
| def get_valid_num_frames(duration): | |
| valid_values = [9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 113, 121] | |
| target = duration * 8 | |
| closest = min(valid_values, key=lambda x: abs(x - target)) | |
| return closest | |
| def generate_video_agnes(prompt, duration=20): | |
| headers = { | |
| "Authorization": f"Bearer {AGNES_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| num_frames = get_valid_num_frames(duration) | |
| print(f"🎬 Duration: {duration}s → {num_frames} frames") | |
| # Try with model | |
| models = ["agnes-video-v2.0", "agnes-video-2.0", "video", "agnes-video"] | |
| for model in models: | |
| try: | |
| payload = { | |
| "model": model, | |
| "prompt": prompt, | |
| "num_frames": num_frames, | |
| "frame_rate": 8, | |
| "width": 1152, | |
| "height": 768, | |
| "guidance_scale": 7.5, | |
| "negative_prompt": "low quality, blurry, distorted, ugly" | |
| } | |
| response = requests.post(f"{AGNES_BASE}/videos", json=payload, headers=headers, timeout=30) | |
| if response.status_code == 200: | |
| data = response.json() | |
| video_id = data.get("video_id") or data.get("id") | |
| if video_id: | |
| print(f"✅ Task created! video_id: {video_id}") | |
| return poll_for_video(video_id, headers) | |
| video_url = data.get("video_url") or data.get("url") or data.get("output") | |
| if video_url: | |
| return video_url | |
| elif response.status_code == 400: | |
| error = response.json() | |
| if "model" in str(error).lower(): | |
| continue | |
| except: | |
| continue | |
| # Try without model | |
| try: | |
| payload = { | |
| "prompt": prompt, | |
| "num_frames": num_frames, | |
| "frame_rate": 8, | |
| "width": 1152, | |
| "height": 768, | |
| "guidance_scale": 7.5, | |
| "negative_prompt": "low quality, blurry, distorted, ugly" | |
| } | |
| response = requests.post(f"{AGNES_BASE}/videos", json=payload, headers=headers, timeout=30) | |
| if response.status_code == 200: | |
| data = response.json() | |
| video_id = data.get("video_id") or data.get("id") | |
| if video_id: | |
| print("✅ Task created without model!") | |
| return poll_for_video(video_id, headers) | |
| video_url = data.get("video_url") or data.get("url") or data.get("output") | |
| if video_url: | |
| return video_url | |
| except: | |
| pass | |
| raise Exception("All attempts failed") | |
| def poll_for_video(video_id, headers): | |
| for attempt in range(40): | |
| time.sleep(3) | |
| print(f"⏳ Polling attempt {attempt + 1}/40...") | |
| poll_response = requests.get( | |
| f"{AGNES_BASE}/agnesapi?video_id={video_id}", | |
| headers=headers, | |
| timeout=30 | |
| ) | |
| if poll_response.status_code == 200: | |
| result = poll_response.json() | |
| status = result.get("status") or result.get("state") | |
| if status in ["completed", "succeeded", "done"]: | |
| video_url = result.get("video_url") or result.get("url") or result.get("output") | |
| if video_url: | |
| return video_url | |
| if result.get("data") and isinstance(result["data"], list): | |
| for item in result["data"]: | |
| if isinstance(item, dict) and item.get("url"): | |
| return item["url"] | |
| raise Exception("No video URL found") | |
| elif status in ["failed", "error"]: | |
| error_msg = result.get("error") or result.get("message") or "Unknown" | |
| raise Exception(f"Video generation failed: {error_msg}") | |
| else: | |
| print(f"⚠️ Poll failed: {poll_response.status_code}") | |
| raise Exception("Video generation timed out") | |
| def index(): | |
| return send_file('index.html') | |
| def generate_video(): | |
| try: | |
| data = request.json | |
| prompt = data.get('prompt') | |
| duration = int(data.get('duration', 20)) | |
| if not prompt: | |
| return jsonify({'error': 'Prompt is required'}), 400 | |
| if not AGNES_API_KEY: | |
| return jsonify({'error': 'AGNES_API_KEY not configured'}), 500 | |
| video_url = generate_video_agnes(prompt, duration) | |
| return jsonify({ | |
| 'success': True, | |
| 'video_url': video_url | |
| }) | |
| except Exception as e: | |
| return jsonify({'error': str(e)}), 500 | |
| if __name__ == '__main__': | |
| app.run(host='0.0.0.0', port=7860, debug=False) |