| | import gradio as gr |
| | import os |
| | import time |
| | import logging |
| | import socket |
| | import requests |
| | from byteplussdkarkruntime import Ark |
| | import byteplussdkcore |
| |
|
| | |
| | logging.basicConfig(level=logging.INFO) |
| | logger = logging.getLogger(__name__) |
| |
|
| | |
| | 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)}") |
| |
|
| | |
| | def test_connectivity(): |
| | """Test if we can reach the API server""" |
| | try: |
| | |
| | ip = socket.gethostbyname('ark.ap-southeast.bytepluses.com') |
| | logger.info(f"✅ DNS resolved: {ip}") |
| | |
| | |
| | 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 |
| |
|
| | |
| | connectivity_ok = test_connectivity() |
| |
|
| | |
| | try: |
| | configuration = byteplussdkcore.Configuration() |
| | configuration.client_side_validation = True |
| | configuration.schema = "http" |
| | configuration.debug = True |
| | 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}") |
| |
|
| | |
| | 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...") |
| | |
| | |
| | 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...") |
| | |
| | |
| | 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 |
| |
|
| | |
| | with gr.Blocks() as demo: |
| | gr.Markdown("# BytePlus Video Generator") |
| | |
| | |
| | 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") |