From 7562c00daed3fd08143eb055ac813fa83af688ea Mon Sep 17 00:00:00 2001 From: wellenzheng <40078093+wellenzheng@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:23:32 +0800 Subject: [PATCH] fix: update video generation params and examples (#10) Co-authored-by: zhengweijun --- .vscode/settings.json | 3 + examples/agent_examples.py | 17 +- examples/basic_usage.py | 4 +- examples/check_apikey_env.py | 14 ++ examples/glm4_example.py | 18 +- examples/video_generator.py | 19 +- examples/video_models_examples.py | 191 ++++++++++++--------- examples/web_search_example.py | 15 +- src/zai/api_resource/videos/videos.py | 27 ++- src/zai/types/video/video_create_params.py | 20 ++- 10 files changed, 176 insertions(+), 152 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 examples/check_apikey_env.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ff5300e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.languageServer": "None" +} \ No newline at end of file diff --git a/examples/agent_examples.py b/examples/agent_examples.py index 22f0c28..3db6bfa 100644 --- a/examples/agent_examples.py +++ b/examples/agent_examples.py @@ -1,26 +1,12 @@ -import os from zai import ZaiClient import asyncio import time -# Try to load .env file -try: - from dotenv import load_dotenv - load_dotenv() -except ImportError: - # If python-dotenv is not installed, continue using system environment variables - pass - -api_key = os.getenv('ZAI_API_KEY') -if not api_key: - print("Please set the ZAI_API_KEY environment variable or configure it in the .env file") - exit() -client = ZaiClient(api_key=api_key) - # ==================== General Translation Scenario ==================== def translate_text(): """General translation example""" + client = ZaiClient() response = client.agents.invoke( agent_id="general_translation", stream=True, @@ -57,6 +43,7 @@ async def async_special_effects_video_example(): # Submit async task print("Submitting async special effects video generation task...") + client = ZaiClient() response = client.agents.invoke( agent_id="vidu_template_agent", custom_variables={ diff --git a/examples/basic_usage.py b/examples/basic_usage.py index 988b7d3..00d6635 100644 --- a/examples/basic_usage.py +++ b/examples/basic_usage.py @@ -1,6 +1,5 @@ from zai import ZaiClient - def completion(): # Initialize client client = ZaiClient() @@ -161,8 +160,9 @@ def audio_transcription(): if __name__ == '__main__': + completion() # completion_with_websearch() # multi_modal_chat() # role_play() # assistant_conversation() - video_generation() + # video_generation() diff --git a/examples/check_apikey_env.py b/examples/check_apikey_env.py new file mode 100644 index 0000000..23b8f69 --- /dev/null +++ b/examples/check_apikey_env.py @@ -0,0 +1,14 @@ +import os + + +def check_apikey(): + api_key = os.getenv('ZAI_API_KEY') + if api_key and api_key.strip(): + print('ZAI_API_KEY is set.') + print(api_key) + else: + print('ZAI_API_KEY is NOT set. Please set the ZAI_API_KEY environment variable or configure it in the .env file.') + + +if __name__ == '__main__': + check_apikey() \ No newline at end of file diff --git a/examples/glm4_example.py b/examples/glm4_example.py index 6d46544..66db70a 100644 --- a/examples/glm4_example.py +++ b/examples/glm4_example.py @@ -2,20 +2,6 @@ import os import time from zai import ZaiClient -# Try to load .env file -try: - from dotenv import load_dotenv - load_dotenv() -except ImportError: - pass - -api_key = os.getenv('ZAI_API_KEY') -if not api_key: - print("Please set the ZAI_API_KEY environment variable or configure it in the .env file.") - exit() - -client = ZaiClient(api_key=api_key) - def stream_web_search_example(): print("=== GLM-4 Streaming Web Search Example ===") tools = [{ @@ -35,6 +21,7 @@ def stream_web_search_example(): "role": "user", "content": "Major financial events, policy changes, and market data in April 2025." }] + client = ZaiClient() response = client.chat.completions.create( model="glm-4-air", messages=messages, @@ -46,6 +33,7 @@ def stream_web_search_example(): def sync_example(): print("=== GLM-4 Synchronous Example ===") + client = ZaiClient() response = client.chat.completions.create( model="glm-4-plus", messages=[ @@ -57,6 +45,7 @@ def sync_example(): def async_example(): print("=== GLM-4 Async Example ===") + client = ZaiClient() response = client.chat.asyncCompletions.create( model="glm-4-plus", messages=[ @@ -73,6 +62,7 @@ def async_result_example(task_id): print("=== GLM-4 Async Result Polling Example ===") task_status = '' get_cnt = 0 + client = ZaiClient() while task_status != 'SUCCESS' and task_status != 'FAILED' and get_cnt <= 40: result_response = client.chat.asyncCompletions.retrieve_completion_result(id=task_id) print(result_response) diff --git a/examples/video_generator.py b/examples/video_generator.py index aee9933..c773397 100644 --- a/examples/video_generator.py +++ b/examples/video_generator.py @@ -4,22 +4,9 @@ import time from zai import ZaiClient -# Try to load .env file -try: - from dotenv import load_dotenv - load_dotenv() -except ImportError: - # If python-dotenv is not installed, continue using system environment variables - pass - -api_key = os.getenv('ZAI_API_KEY') -if not api_key: - print("Please set the ZAI_API_KEY environment variable or configure it in the .env file") - exit() - class VideoGenerator: - def __init__(self, api_key: str): - self.client = ZaiClient(api_key=api_key) + def __init__(self): + self.client = ZaiClient() async def video_generate( self, @@ -95,7 +82,7 @@ class VideoGenerator: # Usage example async def main(): - generator = VideoGenerator(api_key) + generator = VideoGenerator() try: result = await generator.video_generate( prompt='A beautiful sunset beach scene with a beautiful girl', diff --git a/examples/video_models_examples.py b/examples/video_models_examples.py index dd7a176..38e99a3 100644 --- a/examples/video_models_examples.py +++ b/examples/video_models_examples.py @@ -5,22 +5,9 @@ from typing import List, Optional from zai import ZaiClient -# Try to load .env file -try: - from dotenv import load_dotenv - load_dotenv() -except ImportError: - # If python-dotenv is not installed, continue using system environment variables - pass - -api_key = os.getenv('ZAI_API_KEY') -if not api_key: - print("Please set the ZAI_API_KEY environment variable or configure it in the .env file") - exit() - class VideoModelsExamples: - def __init__(self, api_key: str): - self.client = ZaiClient(api_key=api_key) + def __init__(self): + self.client = ZaiClient() async def cogvideox3_text_to_video( self, @@ -165,21 +152,26 @@ class VideoModelsExamples: async def viduq1_text_to_video( self, prompt: str, - quality: str = "quality", - with_audio: bool = True, + style: str = "general", + duration: int = 5, + aspect_ratio: str = "16:9", size: str = "1920x1080", - fps: int = 30, + movement_amplitude: str = "auto", + quality: str = None, + with_audio: bool = None, max_wait_time: int = 300, ): """ viduq1-text text-to-video generation - Args: prompt: Video generation prompt - quality: Output mode, "quality" for quality priority, "speed" for speed priority - with_audio: Whether to include audio + style: Video style (e.g., "general", "anime") + duration: Video duration in seconds + aspect_ratio: Aspect ratio (e.g., "16:9") size: Video resolution - fps: Frame rate + movement_amplitude: Movement amplitude (e.g., "auto") + quality: Output mode + with_audio: Whether to include audio max_wait_time: Maximum wait time (seconds) """ print("=== viduq1-text Text-to-Video ===") @@ -187,10 +179,13 @@ class VideoModelsExamples: response = self.client.videos.generations( model="viduq1-text", prompt=prompt, + style=style, + duration=duration, + aspect_ratio=aspect_ratio, + size=size, + movement_amplitude=movement_amplitude, quality=quality, with_audio=with_audio, - size=size, - fps=fps, ) return await self._wait_for_completion(response.id, max_wait_time) except Exception as e: @@ -201,22 +196,23 @@ class VideoModelsExamples: self, image_url: str, prompt: str, - quality: str = "quality", - with_audio: bool = True, + duration: int = 5, size: str = "1920x1080", - fps: int = 30, + movement_amplitude: str = "auto", + quality: str = None, + with_audio: bool = None, max_wait_time: int = 300, ): """ viduq1-image image-to-video generation - Args: image_url: Image URL or Base64 encoding prompt: Video generation prompt - quality: Output mode, "quality" for quality priority, "speed" for speed priority - with_audio: Whether to include audio + duration: Video duration in seconds size: Video resolution - fps: Frame rate + movement_amplitude: Movement amplitude (e.g., "auto") + quality: Output mode + with_audio: Whether to include audio max_wait_time: Maximum wait time (seconds) """ print("=== viduq1-image Image-to-Video ===") @@ -225,10 +221,11 @@ class VideoModelsExamples: model="viduq1-image", image_url=image_url, prompt=prompt, + duration=duration, + size=size, + movement_amplitude=movement_amplitude, quality=quality, with_audio=with_audio, - size=size, - fps=fps, ) return await self._wait_for_completion(response.id, max_wait_time) except Exception as e: @@ -239,34 +236,36 @@ class VideoModelsExamples: self, image_urls: List[str], prompt: str, - quality: str = "quality", - with_audio: bool = True, + duration: int = 5, size: str = "1920x1080", - fps: int = 30, + movement_amplitude: str = "auto", + quality: str = None, + with_audio: bool = None, max_wait_time: int = 300, ): """ viduq1-start-end start-end frame video generation - Args: image_urls: List of start and end frame image URLs prompt: Video generation prompt - quality: Output mode, "quality" for quality priority, "speed" for speed priority - with_audio: Whether to include audio + duration: Video duration in seconds size: Video resolution - fps: Frame rate + movement_amplitude: Movement amplitude (e.g., "auto") + quality: Output mode + with_audio: Whether to include audio max_wait_time: Maximum wait time (seconds) """ print("=== viduq1-start-end Start-End Frame Video ===") try: response = self.client.videos.generations( model="viduq1-start-end", - image_urls=image_urls, + image_url=image_urls, prompt=prompt, + duration=duration, + size=size, + movement_amplitude=movement_amplitude, quality=quality, with_audio=with_audio, - size=size, - fps=fps, ) return await self._wait_for_completion(response.id, max_wait_time) except Exception as e: @@ -277,22 +276,23 @@ class VideoModelsExamples: self, image_url: str, prompt: str, - quality: str = "quality", + duration: int = 4, + size: str = "1280x720", + movement_amplitude: str = "auto", with_audio: bool = True, - size: str = "1920x1080", - fps: int = 30, + quality: str = None, max_wait_time: int = 300, ): """ vidu2-image image-to-video generation - Args: image_url: Image URL or Base64 encoding prompt: Video generation prompt - quality: Output mode, "quality" for quality priority, "speed" for speed priority - with_audio: Whether to include audio + duration: Video duration in seconds size: Video resolution - fps: Frame rate + movement_amplitude: Movement amplitude (e.g., "auto") + with_audio: Whether to include audio + quality: Output mode max_wait_time: Maximum wait time (seconds) """ print("=== vidu2-image Image-to-Video ===") @@ -301,10 +301,11 @@ class VideoModelsExamples: model="vidu2-image", image_url=image_url, prompt=prompt, - quality=quality, - with_audio=with_audio, + duration=duration, size=size, - fps=fps, + movement_amplitude=movement_amplitude, + with_audio=with_audio, + quality=quality, ) return await self._wait_for_completion(response.id, max_wait_time) except Exception as e: @@ -315,34 +316,36 @@ class VideoModelsExamples: self, image_urls: List[str], prompt: str, - quality: str = "quality", + duration: int = 4, + size: str = "1280x720", + movement_amplitude: str = "auto", with_audio: bool = True, - size: str = "1920x1080", - fps: int = 30, + quality: str = None, max_wait_time: int = 300, ): """ vidu2-start-end start-end frame video generation - Args: image_urls: List of start and end frame image URLs prompt: Video generation prompt - quality: Output mode, "quality" for quality priority, "speed" for speed priority - with_audio: Whether to include audio + duration: Video duration in seconds size: Video resolution - fps: Frame rate + movement_amplitude: Movement amplitude (e.g., "auto") + with_audio: Whether to include audio + quality: Output mode max_wait_time: Maximum wait time (seconds) """ print("=== vidu2-start-end Start-End Frame Video ===") try: response = self.client.videos.generations( model="vidu2-start-end", - image_urls=image_urls, + image_url=image_urls, prompt=prompt, - quality=quality, - with_audio=with_audio, + duration=duration, size=size, - fps=fps, + movement_amplitude=movement_amplitude, + with_audio=with_audio, + quality=quality, ) return await self._wait_for_completion(response.id, max_wait_time) except Exception as e: @@ -351,24 +354,27 @@ class VideoModelsExamples: async def vidu2_reference_video( self, - image_url: str, + image_url: List[str], prompt: str, - quality: str = "quality", + duration: int = 4, + aspect_ratio: str = "16:9", + size: str = "1280x720", + movement_amplitude: str = "auto", with_audio: bool = True, - size: str = "1920x1080", - fps: int = 30, + quality: str = None, max_wait_time: int = 300, ): """ vidu2-reference reference video generation - Args: - image_url: Reference video URL + image_url: Reference image URLs prompt: Video generation prompt - quality: Output mode, "quality" for quality priority, "speed" for speed priority - with_audio: Whether to include audio + duration: Video duration in seconds + aspect_ratio: Aspect ratio (e.g., "16:9") size: Video resolution - fps: Frame rate + movement_amplitude: Movement amplitude (e.g., "auto") + with_audio: Whether to include audio + quality: Output mode max_wait_time: Maximum wait time (seconds) """ print("=== vidu2-reference Reference Video Generation ===") @@ -377,10 +383,12 @@ class VideoModelsExamples: model="vidu2-reference", image_url=image_url, prompt=prompt, - quality=quality, - with_audio=with_audio, + duration=duration, + aspect_ratio=aspect_ratio, size=size, - fps=fps, + movement_amplitude=movement_amplitude, + with_audio=with_audio, + quality=quality, ) return await self._wait_for_completion(response.id, max_wait_time) except Exception as e: @@ -426,7 +434,7 @@ class VideoModelsExamples: # Usage examples async def main(): # Please fill in your API Key - examples = VideoModelsExamples(api_key) + examples = VideoModelsExamples() # Sample image and video URLs (please replace with actual URLs) sample_image_url = "https://i0.sinaimg.cn/edu/2011/1125/U4999P42DT20111125164101.jpg" @@ -461,7 +469,7 @@ async def main(): # 3. cogvideox-3 start-end frame video print("\n" + "="*50) result3 = await examples.cogvideox3_start_end_video( - image_urls=[sample_first_frame, sample_last_frame], + image_url=[sample_first_frame, sample_last_frame], prompt="Make the scene come alive", quality="speed", with_audio=True, @@ -483,6 +491,11 @@ async def main(): print("\n" + "="*50) result5 = await examples.viduq1_text_to_video( prompt="Peter Rabbit driving a car, wandering on the road, with a happy and joyful expression on his face.", + style="general", + duration=5, + aspect_ratio="16:9", + size="1920x1080", + movement_amplitude="auto", quality="speed", with_audio=True, ) @@ -493,6 +506,9 @@ async def main(): result6 = await examples.viduq1_image_to_video( image_url=sample_image_url, prompt="Peter Rabbit driving a car, wandering on the road, with a happy and joyful expression on his face.", + duration=5, + size="1920x1080", + movement_amplitude="auto", quality="speed", with_audio=True, ) @@ -503,6 +519,9 @@ async def main(): result7 = await examples.viduq1_start_end_video( image_url=[sample_first_frame, sample_last_frame], prompt="Peter Rabbit driving a car, wandering on the road, with a happy and joyful expression on his face.", + duration=5, + size="1920x1080", + movement_amplitude="auto", quality="speed", with_audio=True, ) @@ -513,8 +532,11 @@ async def main(): result8 = await examples.vidu2_image_to_video( image_url=sample_image_url, prompt="Peter Rabbit driving a car, wandering on the road, with a happy and joyful expression on his face.", - quality="speed", + duration=4, + size="1280x720", + movement_amplitude="auto", with_audio=True, + quality="speed", ) print("vidu2-image image-to-video result:", result8) @@ -523,8 +545,11 @@ async def main(): result9 = await examples.vidu2_start_end_video( image_url=[sample_first_frame, sample_last_frame], prompt="Peter Rabbit driving a car, wandering on the road, with a happy and joyful expression on his face.", - quality="speed", + duration=4, + size="1280x720", + movement_amplitude="auto", with_audio=True, + quality="speed", ) print("vidu2-start-end start-end frame video result:", result9) @@ -533,8 +558,12 @@ async def main(): result10 = await examples.vidu2_reference_video( image_url=ref_image_url, prompt="Peter Rabbit driving a car, wandering on the road, with a happy and joyful expression on his face.", - quality="speed", + duration=4, + aspect_ratio="16:9", + size="1280x720", + movement_amplitude="auto", with_audio=True, + quality="speed", ) print("vidu2-reference reference video generation result:", result10) except Exception as e: diff --git a/examples/web_search_example.py b/examples/web_search_example.py index 5488416..e06901c 100644 --- a/examples/web_search_example.py +++ b/examples/web_search_example.py @@ -1,21 +1,10 @@ import os +from pydoc import cli from zai import ZaiClient -# Try to load .env file -try: - from dotenv import load_dotenv - load_dotenv() -except ImportError: - pass - -api_key = os.getenv('ZAI_API_KEY') -if not api_key: - print("Please set the ZAI_API_KEY environment variable or configure it in the .env file") - exit() - -client = ZaiClient(api_key=api_key) def web_search_example(): + client = ZaiClient() response = client.web_search.web_search( search_engine="search_pro", search_query="Search for financial news in April 2025", diff --git a/src/zai/api_resource/videos/videos.py b/src/zai/api_resource/videos/videos.py index 4328cd5..fc0298d 100644 --- a/src/zai/api_resource/videos/videos.py +++ b/src/zai/api_resource/videos/videos.py @@ -31,15 +31,18 @@ class Videos(BaseAPI): def generations( self, - model: str, *, + model: str, prompt: str = None, - image_url: str | List[str] | None = None, + image_url: str | List[str] | dict | None = None, quality: str = None, with_audio: bool = None, size: str = None, duration: int = None, fps: int = None, + style: str = None, + aspect_ratio: str = None, + movement_amplitude: str = None, sensitive_word_check: Optional[SensitiveWordCheckRequest] | NotGiven = NOT_GIVEN, request_id: str = None, user_id: str = None, @@ -53,12 +56,15 @@ class Videos(BaseAPI): Arguments: model (str): The model to use for video generation prompt (str): Text description for video generation - image_url (str): URL of image to use as video input - quality (str): Quality level of the generated video + image_url (str | List[str] | dict): Image(s) for video generation (URL, Base64, or object) + quality (str): Output mode, "quality" or "speed" with_audio (bool): Whether to include audio in the video size (str): Size/resolution of the generated video duration (int): Duration of the video in seconds fps (int): Frames per second for the video + style (str): Style, e.g., "general", "anime" + aspect_ratio (str): Aspect ratio, e.g., "16:9", "9:16", "1:1" + movement_amplitude (str): Movement amplitude, e.g., "auto", "small", "medium", "large" sensitive_word_check (Optional[SensitiveWordCheckRequest]): Sensitive word check configuration request_id (str): Unique identifier for the request user_id (str): User identifier @@ -66,21 +72,24 @@ class Videos(BaseAPI): extra_body (Body): Additional body parameters timeout (float | httpx.Timeout): Request timeout """ - if not model and not model: - raise ValueError('At least one of `model` and `prompt` must be provided.') + if not model: + raise ValueError('`model` must be provided.') body = deepcopy_minimal( { 'model': model, 'prompt': prompt, 'image_url': image_url, - 'sensitive_word_check': sensitive_word_check, - 'request_id': request_id, - 'user_id': user_id, 'quality': quality, 'with_audio': with_audio, 'size': size, 'duration': duration, 'fps': fps, + 'style': style, + 'aspect_ratio': aspect_ratio, + 'movement_amplitude': movement_amplitude, + 'sensitive_word_check': sensitive_word_check, + 'request_id': request_id, + 'user_id': user_id, } ) return self._post( diff --git a/src/zai/types/video/video_create_params.py b/src/zai/types/video/video_create_params.py index 45307cb..0b66c44 100644 --- a/src/zai/types/video/video_create_params.py +++ b/src/zai/types/video/video_create_params.py @@ -14,7 +14,15 @@ class VideoCreateParams(TypedDict, total=False): Attributes: model (str): Model encoding prompt (str): Text description of the desired video - image_url (str): Image URL for image-to-video generation (supports URL or Base64 format) + image_url (str | list | dict): Image URL(s) or object for image-to-video generation (supports URL, Base64, or object) + quality (str): Output mode, "quality" or "speed" + with_audio (bool): Whether to include audio in the video + size (str): Size/resolution of the generated video + duration (int): Duration of the video in seconds + fps (int): Frames per second for the video + style (str): Style, e.g., "general", "anime" + aspect_ratio (str): Aspect ratio, e.g., "16:9", "9:16", "1:1" + movement_amplitude (str): Movement amplitude, e.g., "auto", "small", "medium", "large" sensitive_word_check (Optional[SensitiveWordCheckRequest]): Sensitive word check configuration request_id (str): Request ID passed by client, must be unique; used to distinguish each request, platform will generate default if not provided by client @@ -22,7 +30,15 @@ class VideoCreateParams(TypedDict, total=False): """ model: str prompt: str - image_url: str + image_url: str | list | dict + quality: str + with_audio: bool + size: str + duration: int + fps: int + style: str + aspect_ratio: str + movement_amplitude: str sensitive_word_check: Optional[SensitiveWordCheckRequest] request_id: str user_id: str