Merge pull request #7 from ru4ls/develop
Enhance region selection support for Wan API
This commit is contained in:
@@ -29,30 +29,13 @@ This is a direct integration with Alibaba Cloud's Model Studio service, not a th
|
||||
|
||||
## Regional Support
|
||||
|
||||
This node supports both international and Mainland China Alibaba Cloud regions. By default, it uses the international region endpoints, but you can easily switch to Mainland China endpoints by modifying the variables in `core/base.py`:
|
||||
This node supports both international and Mainland China Alibaba Cloud regions. To switch regions, simply select "international" or "mainland_china" from the "region" dropdown parameter available in all nodes. The node will automatically use the appropriate API endpoint and API key for the selected region.
|
||||
|
||||
- **International Region** (default):
|
||||
- Video POST: `https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis`
|
||||
- II2V POST: `https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis`
|
||||
- T2I POST: `https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis`
|
||||
- GET: `https://dashscope-intl.aliyuncs.com/api/v1/tasks/{task_id}`
|
||||
|
||||
- **Mainland China Region**:
|
||||
- Video POST: `https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis`
|
||||
- II2V POST: `https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis`
|
||||
- T2I POST: `https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis`
|
||||
- GET: `https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}`
|
||||
|
||||
To switch regions, simply modify the `API_ENDPOINT_POST_VIDEO`, `API_ENDPOINT_POST_II2V`, `API_ENDPOINT_POST_T2I`, and `API_ENDPOINT_GET` variables in `core/base.py` to the corresponding Mainland China endpoints listed above.
|
||||
**Note**: If you want to use the Mainland China region, you must have a separate API key for that region. Make sure to set both `DASHSCOPE_API_KEY` (for international) and `DASHSCOPE_API_KEY_CHINA` (for Mainland China) in your `.env` file.
|
||||
|
||||
## Centralized Endpoint Management
|
||||
|
||||
All API endpoints are centrally managed in the `core/base.py` file, making it easy to maintain and switch between regions. This approach ensures consistency across all nodes and simplifies future updates. The centralized management includes:
|
||||
|
||||
- `API_ENDPOINT_POST_VIDEO`: For general video generation nodes (I2V, T2V, VACE)
|
||||
- `API_ENDPOINT_POST_II2V`: For image-to-video with first/last frames (II2V)
|
||||
- `API_ENDPOINT_POST_T2I`: For text-to-image generation (T2I)
|
||||
- `API_ENDPOINT_GET`: For task result polling (shared across all nodes)
|
||||
All API endpoints are centrally managed in the `core/base.py` file, making it easy to maintain and switch between regions. This approach ensures consistency across all nodes and simplifies future updates.
|
||||
|
||||
## Available Nodes
|
||||
|
||||
@@ -108,35 +91,17 @@ If you're using a workspace other than your default workspace, you may need to a
|
||||
|
||||
### Set Environment Variable
|
||||
|
||||
Copy the `.env.template` file to `.env` in your ComfyUI root directory and replace the placeholder with your actual API key:
|
||||
Copy the `.env.template` file to `.env` in your `config` directory and replace the placeholders with your actual API keys:
|
||||
|
||||
```
|
||||
# For international region (default)
|
||||
DASHSCOPE_API_KEY=your_actual_api_key_here
|
||||
|
||||
# For mainland China region (optional, if you have a separate key for China)
|
||||
DASHSCOPE_API_KEY_CHINA=your_china_api_key_here
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Text-to-Image Generation
|
||||
|
||||
1. Add the "Wan Text-to-Image Generator" node to your workflow
|
||||
2. Select the desired model (wan2.2-t2i-flash or wan2.2-t2i-plus)
|
||||
3. Connect a text input with your prompt
|
||||
4. Configure parameters as needed (seed, resolution, etc.)
|
||||
5. Execute the node
|
||||
|
||||
### Image-to-Video Generation
|
||||
|
||||
1. Add the "Wan Image-to-Video Generator" node to your workflow
|
||||
2. Provide a publicly accessible URL to the image you want to use as the first frame of your video
|
||||
3. Select the desired model (wan2.2-i2v-flash or wan2.2-i2v-plus)
|
||||
4. Connect a text input with your prompt describing the video content
|
||||
5. Optionally configure the output directory where the video will be saved (can be browsed in ComfyUI)
|
||||
6. Execute the node
|
||||
7. The node will return both a path to the downloaded video file and the video URL
|
||||
8. To preview the video, connect the output to a "Load Video (Path)" node from ComfyUI-VideoHelperSuite
|
||||
9. To use the video URL directly (e.g., for sharing or further processing), you can connect the video_url output to appropriate nodes
|
||||
|
||||
**Note**: The image URL must be publicly accessible (not behind authentication or on localhost).
|
||||
You can use services like Imgur, cloud storage providers, or your own web server to host the image.
|
||||
If you only use the international region, you only need to set `DASHSCOPE_API_KEY`. If you plan to use both regions, you should set both keys. The nodes will automatically use the appropriate key based on the region you select.
|
||||
|
||||
## Node Parameters
|
||||
|
||||
@@ -326,49 +291,30 @@ This node scales videos in different directions using the Wan VACE model.
|
||||
|
||||
## Examples
|
||||
|
||||
### Text-to-Image Generation
|
||||
Prompt: "Generate an image of a cat swimming under the water"
|
||||
Prompt: "Generate an image of a cat"
|
||||
|
||||

|
||||
|
||||
### Text-to-Video Generation
|
||||
1. Add the "Wan Text-to-Video Generator" node to your workflow
|
||||
2. Select the desired model (wan2.2-t2v-plus)
|
||||
3. Connect a text input with your prompt (e.g., "A kitten running in the moonlight")
|
||||
4. Optionally configure the output directory where the video will be saved (can be browsed in ComfyUI)
|
||||
5. Execute the node
|
||||
6. The node will return both a path to the downloaded video file and the video URL
|
||||
7. To preview the video, connect the video_file_path output to a "Load Video (Path)" node from ComfyUI-VideoHelperSuite
|
||||
8. To use the video URL directly (e.g., for sharing or further processing), you can connect the video_url output to appropriate nodes
|
||||
|
||||

|
||||
|
||||
### Image-to-Video Generation
|
||||
1. First frame: Provide a URL to an image (e.g., "https://example.com/your_image.png")
|
||||
2. Prompt: "a cat running in the grass"
|
||||
3. Output directory: "./videos" (default) or any custom path
|
||||
4. To preview: Connect the video_file_path output to a "Load Video (Path)" node from ComfyUI-VideoHelperSuite
|
||||
5. To share or process further: Use the video_url output directly in your workflow
|
||||
|
||||

|
||||
|
||||
### Image-to-Video (First/Last Frame) Generation
|
||||
1. Add the "Wan Image-to-Video (First/Last Frame) Generator" node to your workflow
|
||||
2. Select the desired model (wan2.1-kf2v-plus)
|
||||
3. Provide publicly accessible URLs to the first and last frame images
|
||||
4. Prompt: "a cat running in the grass"Realistic style. A black kitten looks up at the sky curiously. The camera gradually rises from eye level, ending with a top-down shot of the kitten's curious eyes."
|
||||
5. Optionally configure the output directory where the video will be saved (can be browsed in ComfyUI)
|
||||
6. Execute the node
|
||||
7. The node will return both a path to the downloaded video file and the video URL
|
||||
8. To preview the video, connect the video_file_path output to a "Load Video (Path)" node from ComfyUI-VideoHelperSuite
|
||||
9. To use the video URL directly (e.g., for sharing or further processing), you can connect the video_url output to appropriate nodes
|
||||
|
||||

|
||||

|
||||
|
||||
## Security
|
||||
|
||||
The API key is loaded from the `DASHSCOPE_API_KEY` environment variable and never stored in files or code, following Alibaba Cloud security best practices.
|
||||
|
||||
## Changelog
|
||||
|
||||
### v1.1.0 - Region Selection Feature
|
||||
- Added region selection parameter to all nodes, allowing users to easily switch between international and Mainland China regions
|
||||
- Updated `.env.template` to include separate API key variables for international and Mainland China regions
|
||||
- Modified `core/base.py` to support automatic endpoint and API key selection based on region
|
||||
- Updated all generator nodes (T2I, I2V, T2V, II2V) and VACE nodes to include region selection
|
||||
- Improved documentation with updated setup instructions and regional support information
|
||||
|
||||
### v1.0.0 - Initial Release
|
||||
- Initial release with full Wan model integration
|
||||
- Support for Text-to-Image, Image-to-Video, Text-to-Video, and Image-to-Video (First/Last Frame) generation
|
||||
- Full VACE model integration with 5 specialized nodes for video editing
|
||||
- Dual output support (local file paths and remote URLs) for all video generation nodes
|
||||
- International and Mainland China region support (manual configuration required)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
@@ -2,5 +2,8 @@
|
||||
# Copy this file to .env and replace the placeholder with your actual API key
|
||||
|
||||
# Visit https://dashscope.console.aliyuncs.com/apiKey to get your API key
|
||||
# This key is used for all Wan models (text-to-image and image-to-video)
|
||||
DASHSCOPE_API_KEY=your_actual_api_key_here
|
||||
# For international endpoint (default)
|
||||
DASHSCOPE_API_KEY=your_actual_api_key_here
|
||||
|
||||
# For mainland China endpoint (optional, if you have a separate key for China)
|
||||
DASHSCOPE_API_KEY_CHINA=your_china_api_key_here
|
||||
+49
-20
@@ -19,41 +19,70 @@ except ImportError:
|
||||
print("folder_paths not available, using default directory handling")
|
||||
|
||||
# Load environment variables from .env file
|
||||
# Try to load .env file from the current directory first
|
||||
env_path = pathlib.Path(__file__).parent / '.env'
|
||||
# Try multiple locations for the .env file:
|
||||
# 1. config/.env (our preferred location)
|
||||
# 2. .env in the project root (for backward compatibility)
|
||||
# 3. Fallback to default behavior (current working directory)
|
||||
|
||||
# Check config/.env first (go up one level to project root, then into config)
|
||||
env_path = pathlib.Path(__file__).parent.parent / 'config' / '.env'
|
||||
if env_path.exists():
|
||||
print(f"Loading environment variables from: {env_path}")
|
||||
load_dotenv(dotenv_path=env_path)
|
||||
else:
|
||||
# Fallback to default behavior
|
||||
load_dotenv()
|
||||
# Check .env in project root (go up one level to project root)
|
||||
env_path = pathlib.Path(__file__).parent.parent / '.env'
|
||||
if env_path.exists():
|
||||
print(f"Loading environment variables from: {env_path}")
|
||||
load_dotenv(dotenv_path=env_path)
|
||||
else:
|
||||
# Fallback to default behavior
|
||||
print("No .env file found, using default environment variable loading")
|
||||
load_dotenv()
|
||||
|
||||
class WanAPIBase:
|
||||
"""Base class for Wan API interactions"""
|
||||
|
||||
# API endpoints - International region (default)
|
||||
# To use Mainland China region, change these URLs:
|
||||
# Video POST: https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis
|
||||
# II2V POST: https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis
|
||||
# T2I POST: https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis
|
||||
# GET: https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}
|
||||
API_ENDPOINT_POST_VIDEO = "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis"
|
||||
API_ENDPOINT_POST_II2V = "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis"
|
||||
API_ENDPOINT_POST_T2I = "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis"
|
||||
API_ENDPOINT_GET = "https://dashscope-intl.aliyuncs.com/api/v1/tasks/{task_id}"
|
||||
# API endpoints for different regions
|
||||
ENDPOINTS = {
|
||||
"international": {
|
||||
"video_post": "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis",
|
||||
"ii2v_post": "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis",
|
||||
"t2i_post": "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis",
|
||||
"get": "https://dashscope-intl.aliyuncs.com/api/v1/tasks/{task_id}"
|
||||
},
|
||||
"mainland_china": {
|
||||
"video_post": "https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis",
|
||||
"ii2v_post": "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2video/video-synthesis",
|
||||
"t2i_post": "https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis",
|
||||
"get": "https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"
|
||||
}
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
# Load API keys for different regions
|
||||
self.api_key = os.getenv('DASHSCOPE_API_KEY')
|
||||
self.api_key_china = os.getenv('DASHSCOPE_API_KEY_CHINA')
|
||||
# Strip any extra quotes or whitespace
|
||||
if self.api_key:
|
||||
self.api_key = self.api_key.strip().strip('"\'')
|
||||
print(f"Initialized WanAPIBase with API key: {self.api_key[:8] if self.api_key else 'None'}...{self.api_key[-4:] if self.api_key else ''}")
|
||||
|
||||
def check_api_key(self):
|
||||
"""Check if API key is set in environment variables"""
|
||||
if not self.api_key:
|
||||
if self.api_key_china:
|
||||
self.api_key_china = self.api_key_china.strip().strip('"\'')
|
||||
print(f"Initialized WanAPIBase with API keys: international={self.api_key[:8] if self.api_key else 'None'}...{self.api_key[-4:] if self.api_key else ''}, china={self.api_key_china[:8] if self.api_key_china else 'None'}...{self.api_key_china[-4:] if self.api_key_china else ''}")
|
||||
|
||||
def check_api_key(self, region="international"):
|
||||
"""Check if appropriate API key is set in environment variables"""
|
||||
if region == "mainland_china" and self.api_key_china:
|
||||
return self.api_key_china
|
||||
elif self.api_key:
|
||||
return self.api_key
|
||||
else:
|
||||
raise ValueError("DASHSCOPE_API_KEY environment variable not set. "
|
||||
"Please set it before using this node.")
|
||||
return self.api_key
|
||||
|
||||
def get_api_endpoints(self, region="international"):
|
||||
"""Get the appropriate API endpoints based on region"""
|
||||
return self.ENDPOINTS.get(region, self.ENDPOINTS["international"])
|
||||
|
||||
def prepare_images(self, images):
|
||||
"""Convert images to base64 strings for API submission"""
|
||||
|
||||
+28
-15
@@ -36,11 +36,14 @@ class WanI2VGenerator(WanAPIBase):
|
||||
"1080P"
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_VIDEO in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_VIDEO
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -69,6 +72,9 @@ class WanI2VGenerator(WanAPIBase):
|
||||
"prompt": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "A cat running on the grass"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -99,10 +105,14 @@ class WanI2VGenerator(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan"
|
||||
|
||||
def generate(self, model, image_url, prompt, negative_prompt="", resolution="720P",
|
||||
def generate(self, model, image_url, prompt, region, negative_prompt="", resolution="720P",
|
||||
prompt_extend=True, watermark=False, seed=0, output_dir="./videos"):
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["video_post"]
|
||||
|
||||
# Prepare API payload for image-to-video generation
|
||||
payload = {
|
||||
@@ -126,15 +136,15 @@ class WanI2VGenerator(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
print(f"Making API request to {api_url}")
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -151,7 +161,7 @@ class WanI2VGenerator(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -181,16 +191,19 @@ class WanI2VGenerator(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
+28
-15
@@ -33,11 +33,14 @@ class WanII2VGenerator(WanAPIBase):
|
||||
"720P"
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_II2V in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_II2V
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -69,6 +72,9 @@ class WanII2VGenerator(WanAPIBase):
|
||||
"prompt": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "A black kitten looks up at the sky curiously, the camera gradually rises from eye level, and finally shoots from a top-down angle to capture the kitten's curious eyes."
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -99,10 +105,14 @@ class WanII2VGenerator(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan"
|
||||
|
||||
def generate(self, model, first_frame_url, last_frame_url, prompt, negative_prompt="",
|
||||
def generate(self, model, first_frame_url, last_frame_url, prompt, region, negative_prompt="",
|
||||
resolution="720P", prompt_extend=True, watermark=False, seed=0, output_dir="./videos"):
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["ii2v_post"]
|
||||
|
||||
# Prepare API payload for image-to-video generation with first and last frames
|
||||
payload = {
|
||||
@@ -127,15 +137,15 @@ class WanII2VGenerator(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
print(f"Making API request to {api_url}")
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -152,7 +162,7 @@ class WanII2VGenerator(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -182,16 +192,19 @@ class WanII2VGenerator(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
+32
-18
@@ -40,11 +40,14 @@ class WanT2IGenerator(WanAPIBase):
|
||||
"512*1440" # Tall portrait
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_T2I in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_T2I
|
||||
self.model = "wan2.2-t2i-flash" # Using Wan Speed Edition as default
|
||||
|
||||
@classmethod
|
||||
@@ -60,6 +63,9 @@ class WanT2IGenerator(WanAPIBase):
|
||||
}),
|
||||
"size": (cls.SIZE_OPTIONS, {
|
||||
"default": "1024*1024"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -86,17 +92,22 @@ class WanT2IGenerator(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan"
|
||||
|
||||
def generate(self, model, prompt, size, negative_prompt="", prompt_extend=True, watermark=False, seed=0):
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
def generate(self, model, prompt, size, region, negative_prompt="", prompt_extend=True, watermark=False, seed=0):
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["t2i_post"]
|
||||
|
||||
# Set the selected model
|
||||
self.model = model
|
||||
|
||||
# Debug: Print API key status
|
||||
print(f"Using API key: {self.api_key[:8]}...{self.api_key[-4:] if self.api_key else 'None'}")
|
||||
print(f"Using API key: {api_key[:8]}...{api_key[-4:] if api_key else 'None'}")
|
||||
print(f"Selected model: {self.model}")
|
||||
print(f"Using API endpoint: {self.api_url}")
|
||||
print(f"Using API endpoint: {api_url}")
|
||||
print(f"Selected region: {region}")
|
||||
|
||||
# Prepare API payload for text-to-image generation - using the Wan format
|
||||
payload = {
|
||||
@@ -120,13 +131,13 @@ class WanT2IGenerator(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
# Debug: Print request details
|
||||
print(f"Request headers: {{'Authorization': 'Bearer {self.api_key[:8]}...', 'Content-Type': 'application/json', 'X-DashScope-Async': 'enable'}}")
|
||||
print(f"Request headers: {{'Authorization': 'Bearer {api_key[:8]}...', 'Content-Type': 'application/json', 'X-DashScope-Async': 'enable'}}")
|
||||
print(f"Request payload model: {payload['model']}")
|
||||
print(f"Request payload prompt: {payload['input']['prompt'][:100]}...")
|
||||
print(f"Request payload size: {payload['parameters']['size']}")
|
||||
@@ -135,8 +146,8 @@ class WanT2IGenerator(WanAPIBase):
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
print(f"Making API request to {api_url}")
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -153,7 +164,7 @@ class WanT2IGenerator(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id)
|
||||
task_result = self.poll_task_result(task_id, region)
|
||||
return task_result
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -183,16 +194,19 @@ class WanT2IGenerator(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id):
|
||||
def poll_task_result(self, task_id, region):
|
||||
"""Poll for task result until completion"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
+28
-15
@@ -34,11 +34,14 @@ class WanT2VGenerator(WanAPIBase):
|
||||
"1080P"
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_VIDEO in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_VIDEO
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -64,6 +67,9 @@ class WanT2VGenerator(WanAPIBase):
|
||||
"prompt": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "A kitten running in the moonlight"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -94,10 +100,14 @@ class WanT2VGenerator(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan"
|
||||
|
||||
def generate(self, model, prompt, negative_prompt="", resolution="1080P",
|
||||
def generate(self, model, prompt, region, negative_prompt="", resolution="1080P",
|
||||
prompt_extend=True, watermark=False, seed=0, output_dir="./videos"):
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["video_post"]
|
||||
|
||||
# Prepare API payload for text-to-video generation
|
||||
payload = {
|
||||
@@ -140,15 +150,15 @@ class WanT2VGenerator(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
print(f"Making API request to {api_url}")
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -165,7 +175,7 @@ class WanT2VGenerator(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -195,16 +205,19 @@ class WanT2VGenerator(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 442 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 311 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 351 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 620 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 624 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 336 KiB |
+28
-15
@@ -41,11 +41,14 @@ class WanVACEImageReference(WanAPIBase):
|
||||
"1088*832" # 4:3 aspect ratio
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_VIDEO in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_VIDEO
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -76,6 +79,9 @@ class WanVACEImageReference(WanAPIBase):
|
||||
"multiline": True,
|
||||
"default": "",
|
||||
"tooltip": "Newline-separated URLs for reference images"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -107,11 +113,15 @@ class WanVACEImageReference(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan/VACE"
|
||||
|
||||
def generate(self, model, prompt, ref_images_url, obj_or_bg="", size="1280*720",
|
||||
def generate(self, model, prompt, ref_images_url, region, obj_or_bg="", size="1280*720",
|
||||
seed=0, prompt_extend=False, watermark=False, output_dir="./videos"):
|
||||
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["video_post"]
|
||||
|
||||
# Validate required inputs
|
||||
if not ref_images_url or not ref_images_url.strip():
|
||||
@@ -162,16 +172,16 @@ class WanVACEImageReference(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
print(f"Making API request to {api_url}")
|
||||
print(f"Payload: {json.dumps(payload, indent=2)}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -188,7 +198,7 @@ class WanVACEImageReference(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -218,16 +228,19 @@ class WanVACEImageReference(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
+29
-16
@@ -63,11 +63,14 @@ class WanVACEVideoEdit(WanAPIBase):
|
||||
"1088*832" # 4:3 aspect ratio
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_VIDEO in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_VIDEO
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -97,6 +100,9 @@ class WanVACEVideoEdit(WanAPIBase):
|
||||
"video_url": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "URL of the input video"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -156,13 +162,17 @@ class WanVACEVideoEdit(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan/VACE"
|
||||
|
||||
def generate(self, model, prompt, video_url, ref_images_url="", mask_image_url="",
|
||||
def generate(self, model, prompt, video_url, region, ref_images_url="", mask_image_url="",
|
||||
mask_frame_id=1, mask_video_url="", control_condition="", mask_type="tracking",
|
||||
expand_ratio=0.05, expand_mode="hull", size="1280*720", seed=0,
|
||||
prompt_extend=False, watermark=False, output_dir="./videos"):
|
||||
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["video_post"]
|
||||
|
||||
# Prepare API payload
|
||||
payload = {
|
||||
@@ -213,16 +223,16 @@ class WanVACEVideoEdit(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
print(f"Making API request to {api_url}")
|
||||
print(f"Payload: {json.dumps(payload, indent=2)}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -239,7 +249,7 @@ class WanVACEVideoEdit(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -269,16 +279,19 @@ class WanVACEVideoEdit(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
""""Poll for task result until completion and download video"""
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
+28
-15
@@ -41,11 +41,14 @@ class WanVACEVideoExtension(WanAPIBase):
|
||||
"scribble" # Extract line art structure
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_VIDEO in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_VIDEO
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -71,6 +74,9 @@ class WanVACEVideoExtension(WanAPIBase):
|
||||
"prompt": ("STRING", {
|
||||
"multiline": True,
|
||||
"default": "Extend the video with the following description"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -117,12 +123,16 @@ class WanVACEVideoExtension(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan/VACE"
|
||||
|
||||
def generate(self, model, prompt, first_frame_url="", last_frame_url="",
|
||||
def generate(self, model, prompt, region, first_frame_url="", last_frame_url="",
|
||||
first_clip_url="", last_clip_url="", video_url="", control_condition="",
|
||||
seed=0, prompt_extend=False, watermark=False, output_dir="./videos"):
|
||||
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["video_post"]
|
||||
|
||||
# Prepare API payload
|
||||
payload = {
|
||||
@@ -167,16 +177,16 @@ class WanVACEVideoExtension(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
print(f"Making API request to {api_url}")
|
||||
print(f"Payload: {json.dumps(payload, indent=2)}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -193,7 +203,7 @@ class WanVACEVideoExtension(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -223,16 +233,19 @@ class WanVACEVideoExtension(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
+28
-15
@@ -32,11 +32,14 @@ class WanVACEVideoOutpainting(WanAPIBase):
|
||||
"wan2.1-vace-plus" # Professional Edition
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_VIDEO in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_VIDEO
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -66,6 +69,9 @@ class WanVACEVideoOutpainting(WanAPIBase):
|
||||
"video_url": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "URL of the input video"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -113,12 +119,16 @@ class WanVACEVideoOutpainting(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan/VACE"
|
||||
|
||||
def generate(self, model, prompt, video_url, top_scale=1.0, bottom_scale=1.0,
|
||||
def generate(self, model, prompt, video_url, region, top_scale=1.0, bottom_scale=1.0,
|
||||
left_scale=1.0, right_scale=1.0, seed=0, prompt_extend=False,
|
||||
watermark=False, output_dir="./videos"):
|
||||
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["video_post"]
|
||||
|
||||
# Prepare API payload
|
||||
payload = {
|
||||
@@ -150,16 +160,16 @@ class WanVACEVideoOutpainting(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
print(f"Making API request to {api_url}")
|
||||
print(f"Payload: {json.dumps(payload, indent=2)}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -176,7 +186,7 @@ class WanVACEVideoOutpainting(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -206,16 +216,19 @@ class WanVACEVideoOutpainting(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
+28
-15
@@ -40,11 +40,14 @@ class WanVACEVideoRepainting(WanAPIBase):
|
||||
"scribble" # Extract line art structure
|
||||
]
|
||||
|
||||
# Define region options
|
||||
REGION_OPTIONS = [
|
||||
"international",
|
||||
"mainland_china"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
# Use the centralized API endpoint from the base class
|
||||
# To use Mainland China region, modify API_ENDPOINT_POST_VIDEO in core/base.py
|
||||
self.api_url = self.API_ENDPOINT_POST_VIDEO
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
@@ -74,6 +77,9 @@ class WanVACEVideoRepainting(WanAPIBase):
|
||||
"video_url": ("STRING", {
|
||||
"default": "",
|
||||
"tooltip": "URL of the input video"
|
||||
}),
|
||||
"region": (cls.REGION_OPTIONS, {
|
||||
"default": "international"
|
||||
})
|
||||
},
|
||||
"optional": {
|
||||
@@ -111,11 +117,15 @@ class WanVACEVideoRepainting(WanAPIBase):
|
||||
FUNCTION = "generate"
|
||||
CATEGORY = "Ru4ls/Wan/VACE"
|
||||
|
||||
def generate(self, model, prompt, video_url, ref_images_url="", control_condition="depth",
|
||||
def generate(self, model, prompt, video_url, region, ref_images_url="", control_condition="depth",
|
||||
strength=1.0, seed=0, prompt_extend=False, watermark=False, output_dir="./videos"):
|
||||
|
||||
# Check API key
|
||||
self.check_api_key()
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
api_url = endpoints["video_post"]
|
||||
|
||||
# Prepare API payload
|
||||
payload = {
|
||||
@@ -148,16 +158,16 @@ class WanVACEVideoRepainting(WanAPIBase):
|
||||
|
||||
# Set headers according to DashScope documentation
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
"X-DashScope-Async": "enable" # Wan requires async processing
|
||||
}
|
||||
|
||||
try:
|
||||
# Make API request
|
||||
print(f"Making API request to {self.api_url}")
|
||||
print(f"Making API request to {api_url}")
|
||||
print(f"Payload: {json.dumps(payload, indent=2)}")
|
||||
response = requests.post(self.api_url, headers=headers, json=payload)
|
||||
response = requests.post(api_url, headers=headers, json=payload)
|
||||
print(f"Response status code: {response.status_code}")
|
||||
if hasattr(response, 'text'):
|
||||
print(f"Response text: {response.text[:500]}...") # Print first 500 chars
|
||||
@@ -174,7 +184,7 @@ class WanVACEVideoRepainting(WanAPIBase):
|
||||
print(f"Task created with ID: {task_id}, status: {task_status}")
|
||||
|
||||
# Now we need to poll for the result
|
||||
task_result = self.poll_task_result(task_id, output_dir)
|
||||
task_result = self.poll_task_result(task_id, output_dir, region)
|
||||
return task_result # Return both path to downloaded video file and video URL
|
||||
else:
|
||||
raise ValueError(f"Unexpected API response format: {result}")
|
||||
@@ -204,16 +214,19 @@ class WanVACEVideoRepainting(WanAPIBase):
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to process API response: {str(e)}")
|
||||
|
||||
def poll_task_result(self, task_id, output_dir="./videos"):
|
||||
def poll_task_result(self, task_id, output_dir="./videos", region="international"):
|
||||
"""Poll for task result until completion and download video"""
|
||||
import time
|
||||
|
||||
# URL for querying task results
|
||||
# To use Mainland China region, modify API_ENDPOINT_GET in core/base.py
|
||||
query_url = self.API_ENDPOINT_GET.format(task_id=task_id)
|
||||
# Get the appropriate API endpoints based on region
|
||||
endpoints = self.get_api_endpoints(region)
|
||||
query_url = endpoints["get"].format(task_id=task_id)
|
||||
|
||||
# Check API key based on region
|
||||
api_key = self.check_api_key(region)
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user