Skip to main content
Glama
runwareUtils.py9.89 kB
#!/usr/bin/env python3 """ Runware API utilities and helper functions. Provides functions for API communication, video model management, and video generation polling. """ import json import os import time import uuid from typing import Dict, Any, Optional, Tuple, List import requests # ============================================================================ # CONSTANTS AND CONFIGURATION # ============================================================================ # API Configuration DEFAULT_POLL_INTERVAL = 2 DEFAULT_TIMEOUT = 300 DEFAULT_API_BASE_URL = "https://api.runware.ai/v1" # Video Models Information VIDEO_MODELS: Dict[str, List[str]] = { "KlingAI": [ "klingai:1@2 (KlingAI V1.0 Pro)", "klingai:1@1 (KlingAI V1 Standard)", "klingai:2@2 (KlingAI V1.5 Pro)", "klingai:2@1 (KlingAI V1.5 Standard)", "klingai:3@1 (KlingAI V1.6 Standard)", "klingai:3@2 (KlingAI V1.6 Pro)", "klingai:4@3 (KlingAI V2.1 Master)", "klingai:5@1 (KlingAI V2.1 Standard (I2V))", "klingai:5@2 (KlingAI V2.1 Pro (I2V))", "klingai:5@3 (KlingAI V2.0 Master)", ], "Veo": [ "google:2@0 (Veo 2.0)", "google:3@0 (Veo 3.0)", "google:3@1 (Veo 3.0 Fast)", ], "Seedance": [ "bytedance:2@1 (Seedance 1.0 Pro)", "bytedance:1@1 (Seedance 1.0 Lite)", ], "MiniMax": [ "minimax:1@1 (MiniMax 01 Base)", "minimax:2@1 (MiniMax 01 Director)", "minimax:2@3 (MiniMax I2V 01 Live)", "minimax:3@1 (MiniMax 02 Hailuo)", ], "PixVerse": [ "pixverse:1@1 (PixVerse v3.5)", "pixverse:1@2 (PixVerse v4)", "pixverse:1@3 (PixVerse v4.5)", ], "Vidu": [ "vidu:1@0 (Vidu Q1 Classic)", "vidu:1@1 (Vidu Q1)", "vidu:1@5 (Vidu 1.5)", "vidu:2@0 (Vidu 2.0)", ], "Wan": [ "runware:200@1 (Wan 2.1 1.3B)", "runware:200@2 (Wan 2.1 14B)", ], } # Model dimensions mapping MODEL_DIMENSIONS: Dict[str, Dict[str, int]] = { # KlingAI Models "klingai:1@2": {"width": 1280, "height": 720}, # KlingAI V1.0 Pro "klingai:1@1": {"width": 1280, "height": 720}, # KlingAI V1 Standard "klingai:2@2": {"width": 1920, "height": 1080}, # KlingAI V1.5 Pro "klingai:2@1": {"width": 1280, "height": 720}, # KlingAI V1.5 Standard "klingai:3@1": {"width": 1280, "height": 720}, # KlingAI V1.6 Standard "klingai:3@2": {"width": 1920, "height": 1080}, # KlingAI V1.6 Pro "klingai:4@3": {"width": 1280, "height": 720}, # KlingAI V2.1 Master "klingai:5@1": {"width": 1280, "height": 720}, # KlingAI V2.1 Standard (I2V) "klingai:5@2": {"width": 1920, "height": 1080}, # KlingAI V2.1 Pro (I2V) "klingai:5@3": {"width": 1920, "height": 1080}, # KlingAI V2.0 Master # Veo Models "google:2@0": {"width": 1280, "height": 720}, # Veo 2.0 "google:3@0": {"width": 1280, "height": 720}, # Veo 3.0 "google:3@1": {"width": 1280, "height": 720}, # Veo 3.0 Fast # Seedance Models "bytedance:2@1": {"width": 864, "height": 480}, # Seedance 1.0 Pro "bytedance:1@1": {"width": 864, "height": 480}, # Seedance 1.0 Lite # MiniMax Models "minimax:1@1": {"width": 1366, "height": 768}, # MiniMax 01 Base "minimax:2@1": {"width": 1366, "height": 768}, # MiniMax 01 Director "minimax:2@3": {"width": 1366, "height": 768}, # MiniMax I2V 01 Live "minimax:3@1": {"width": 1366, "height": 768}, # MiniMax 02 Hailuo # PixVerse Models "pixverse:1@1": {"width": 640, "height": 360}, # PixVerse v3.5 "pixverse:1@2": {"width": 640, "height": 360}, # PixVerse v4 "pixverse:1@3": {"width": 640, "height": 360}, # PixVerse v4.5 # Vidu Models "vidu:1@0": {"width": 1920, "height": 1080}, # Vidu Q1 Classic "vidu:1@1": {"width": 1920, "height": 1080}, # Vidu Q1 "vidu:1@5": {"width": 1920, "height": 1080}, # Vidu 1.5 "vidu:2@0": {"width": 1920, "height": 1080}, # Vidu 2.0 # Wan Models "runware:200@1": {"width": 853, "height": 480}, # Wan 2.1 1.3B "runware:200@2": {"width": 853, "height": 480}, # Wan 2.1 14B } # ============================================================================ # CORE API FUNCTIONS # ============================================================================ def genRandUUID() -> str: """ Generate a random UUID string. Returns: A random UUID v4 string Example: >>> genRandUUID() '550e8400-e29b-41d4-a716-446655440000' """ return str(uuid.uuid4()) def inferenceRequest(genConfig: Dict[str, Any]) -> Dict[str, Any]: """ Make an inference request to the Runware API. Args: genConfig: Configuration dictionary for the inference request Returns: Dict containing the API response Raises: ValueError: If required environment variables are missing Exception: If the request fails or returns an error Example: >>> config = {"taskType": "imageInference", "positivePrompt": "A cat"} >>> result = inferenceRequest(config) """ # Get and validate environment variables api_key = os.getenv("RUNWARE_API_KEY") api_base_url = os.getenv("RUNWARE_BASE_URL", DEFAULT_API_BASE_URL) session_timeout = DEFAULT_TIMEOUT if not api_key: raise ValueError("RUNWARE_API_KEY not found in environment variables") headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate, br, zstd", } try: request_payload = [genConfig] response = requests.post( api_base_url, headers=headers, json=request_payload, timeout=session_timeout, allow_redirects=False, stream=True, ) result = response.json() if "errors" in result: raise Exception(result["errors"][0]["message"]) return result except Exception as e: raise Exception(f"Error: {e}") # ============================================================================ # VIDEO MODEL MANAGEMENT FUNCTIONS # ============================================================================ def getModelDimensions(model_id: str) -> Optional[Dict[str, int]]: """ Get the supported dimensions for a specific video model. Args: model_id: The model identifier (e.g., "bytedance:2@1") Returns: Dictionary with "width" and "height" keys, or None if model not found Example: >>> getModelDimensions("klingai:1@2") {'width': 1280, 'height': 720} >>> getModelDimensions("nonexistent") None """ return MODEL_DIMENSIONS.get(model_id) def validateVideoDimensions(model_id: str, width: int, height: int) -> Tuple[bool, str]: """ Validate if the provided dimensions are supported by the specified video model. Args: model_id: The model identifier width: Requested width height: Requested height Returns: Tuple of (is_valid, error_message) Example: >>> validateVideoDimensions("klingai:1@2", 1280, 720) (True, '') >>> validateVideoDimensions("klingai:1@2", 1920, 1080) (False, "Model 'klingai:1@2' only supports dimensions 1280x720, but you provided 1920x1080") """ model_dims = getModelDimensions(model_id) if not model_dims: return False, f"Model '{model_id}' not found in supported video models" expected_width = model_dims["width"] expected_height = model_dims["height"] if width != expected_width or height != expected_height: return False, f"Model '{model_id}' only supports dimensions {expected_width}x{expected_height}, but you provided {width}x{height}" return True, "" def getSupportedVideoModels() -> Dict[str, List[str]]: """ Get all supported video models organized by provider. Returns: Dictionary of video models organized by provider Example: >>> models = getSupportedVideoModels() >>> models["KlingAI"] ['klingai:1@2 (KlingAI V1.0 Pro)', 'klingai:1@1 (KlingAI V1 Standard)', ...] """ return VIDEO_MODELS # ============================================================================ # VIDEO GENERATION POLLING FUNCTIONS # ============================================================================ def pollVideoCompletion(taskUUID: str) -> Dict[str, Any]: """ Poll for video generation completion using taskUUID. Args: taskUUID: The task UUID to poll for Returns: Dictionary containing the final result when video is ready or failed Raises: ValueError: If taskUUID is empty or API key is missing Example: >>> result = pollVideoCompletion("550e8400-e29b-41d4-a716-446655440000") >>> result["status"] 'success' """ # Input validation if not taskUUID: raise ValueError("taskUUID cannot be empty") if not os.getenv("RUNWARE_API_KEY"): raise ValueError("RUNWARE_API_KEY not found in environment variables") while True: time.sleep(DEFAULT_POLL_INTERVAL) poll_config = { "taskType": "getResponse", "taskUUID": taskUUID, } poll_result = inferenceRequest(poll_config) if "data" in poll_result and len(poll_result["data"]) > 0: video_data = poll_result["data"][0] status = video_data.get("status") if status != "processing": return poll_result

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/elijahdev0/MCP-Runware'

If you have feedback or need assistance with the MCP directory API, please join our Discord server