import gradio as gr import os import time import logging import socket import requests from byteplussdkarkruntime import Ark import byteplussdkcore # Set up logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Get API key API_KEY = os.environ.get("key", "") logger.info(f"API Key loaded: {'Yes' if API_KEY else 'No'}") logger.info(f"Key length: {len(API_KEY)}") # Test basic connectivity first def test_connectivity(): """Test if we can reach the API server""" try: # Test DNS resolution ip = socket.gethostbyname('ark.ap-southeast.bytepluses.com') logger.info(f"✅ DNS resolved: {ip}") # Test basic HTTPS connection r = requests.get("https://ark.ap-southeast.bytepluses.com", timeout=5) logger.info(f"✅ Base URL reachable (status: {r.status_code})") return True except Exception as e: logger.error(f"❌ Connection test failed: {e}") return False # Run connection test on startup connectivity_ok = test_connectivity() # Configure SDK try: configuration = byteplussdkcore.Configuration() configuration.client_side_validation = True configuration.schema = "http" configuration.debug = True # Enable debug logging configuration.logger_file = "sdk.log" byteplussdkcore.Configuration.set_default(configuration) logger.info("✅ SDK configured") except Exception as e: logger.error(f"❌ SDK config failed: {e}") # Initialize client try: client = Ark( base_url="https://ark.ap-southeast.bytepluses.com/api/v3", api_key=API_KEY, ) logger.info("✅ Client initialized") except Exception as e: logger.error(f"❌ Client init failed: {e}") client = None def generate_video(prompt_text, image_url, progress=gr.Progress()): """Generate video with detailed debugging""" if not API_KEY: yield "❌ No API key", None return if not client: yield "❌ Client not initialized", None return if not connectivity_ok: yield "❌ Cannot reach API server", None return try: progress(0, desc="Creating task...") logger.info("Creating task...") # Log the request details logger.info(f"Prompt: {prompt_text[:50]}...") logger.info(f"Image URL: {image_url}") create_result = client.content_generation.tasks.create( model="seedance-1-5-pro-251215", content=[ { "type": "text", "text": prompt_text }, { "type": "image_url", "image_url": { "url": image_url } } ] ) task_id = create_result.id logger.info(f"✅ Task created: {task_id}") yield f"Task created: {task_id}", None progress(0.3, desc="Polling...") # Poll for results attempts = 0 while attempts < 60: try: get_result = client.content_generation.tasks.get(task_id=task_id) status = get_result.status logger.info(f"Status: {status}") if status == "succeeded": progress(1.0, desc="Complete!") video_url = get_result.output[0].get('video_url') if get_result.output else None yield "Success!", video_url return elif status == "failed": yield f"Failed: {get_result.error}", None return else: progress(0.3 + (attempts/60)*0.7, desc=f"Status: {status}") yield f"Status: {status}...", None time.sleep(1) attempts += 1 except Exception as e: logger.error(f"Polling error: {e}") yield f"Polling error: {e}", None return yield "Timeout", None except Exception as e: logger.error(f"❌ Error: {e}", exc_info=True) yield f"Error: {str(e)}", None # Simple interface with gr.Blocks() as demo: gr.Markdown("# BytePlus Video Generator") # Show connection status if connectivity_ok: gr.Markdown("✅ **API Server:** Reachable") else: gr.Markdown("❌ **API Server:** Cannot connect - check network") with gr.Row(): with gr.Column(): prompt = gr.Textbox( label="Prompt", lines=3, value="At breakneck speed, drones fly through obstacles --duration 5 --camerafixed false" ) image_url = gr.Textbox( label="Image URL", value="https://ark-doc.tos-ap-southeast-1.bytepluses.com/seepro_i2v%20.png" ) btn = gr.Button("Generate", variant="primary") with gr.Column(): status = gr.Textbox(label="Status", lines=5) video = gr.Video(label="Generated Video") btn.click( fn=generate_video, inputs=[prompt, image_url], outputs=[status, video] ) demo.launch(server_name="0.0.0.0")