Merge branch 'main' into feature/glm-4.5
This commit is contained in:
commit
0a19179428
17 changed files with 230 additions and 191 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -173,7 +173,7 @@ cython_debug/
|
|||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
.idea/
|
||||
|
||||
# Abstra
|
||||
# Abstra is an AI-powered process automation framework.
|
||||
|
|
@ -186,7 +186,7 @@ cython_debug/
|
|||
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
||||
# you could uncomment the following to ignore the entire vscode folder
|
||||
# .vscode/
|
||||
.vscode/
|
||||
|
||||
# Ruff stuff:
|
||||
.ruff_cache/
|
||||
|
|
|
|||
|
|
@ -116,12 +116,18 @@ export ZAI_BASE_URL="https://api.z.ai/api/paas/v4/" # Optional
|
|||
#### Code Configuration
|
||||
|
||||
```python
|
||||
from zai import ZaiClient
|
||||
from zai import ZaiClient, ZhipuAiClient
|
||||
|
||||
client = ZaiClient(
|
||||
api_key="your-api-key",
|
||||
base_url="https://api.z.ai/api/paas/v4/" # Optional
|
||||
)
|
||||
|
||||
# if you want to use ZhipuAiClient
|
||||
zhipu_client = ZhipuAiClient(
|
||||
api_key="your-api-key",
|
||||
base_url="https://open.bigmodel.cn/api/paas/v4/" # Optional
|
||||
)
|
||||
```
|
||||
|
||||
### Advanced Configuration
|
||||
|
|
|
|||
10
README_CN.md
10
README_CN.md
|
|
@ -97,12 +97,20 @@ export ZAI_BASE_URL="https://api.z.ai/api/paas/v4/" # 可选
|
|||
|
||||
**代码配置:**
|
||||
```python
|
||||
from zai import ZaiClient
|
||||
from zai import ZaiClient, ZhipuAiClient
|
||||
|
||||
client = ZaiClient(
|
||||
api_key="your_api_key_here", # 填写您的 APIKey
|
||||
base_url="https://api.z.ai/api/paas/v4/" # 可选
|
||||
)
|
||||
|
||||
# if you want to use ZhipuAiClient
|
||||
zhipu_client = ZhipuAiClient(
|
||||
api_key="your_api_key_here", # 填写您的 APIKey
|
||||
base_url="https://open.bigmodel.cn/api/paas/v4/" # 可选
|
||||
)
|
||||
```
|
||||
|
||||
**高级配置:**
|
||||
|
||||
SDK提供了灵活的客户端配置选项:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Release Notes
|
||||
|
||||
## v0.0.1b1 - Major Enhancements & Restructuring (2025-07-22)
|
||||
## v0.0.1b2 - Major Enhancements & Restructuring (2025-07-22)
|
||||
|
||||
🚀 **A comprehensive update focusing on developer experience, code organization, and expanded examples!**
|
||||
|
||||
|
|
@ -311,7 +311,7 @@ This initial release establishes the foundation for Z.ai's Python SDK. Future re
|
|||
|
||||
## Migration Guide
|
||||
|
||||
### From v0.0.1a1 to v0.0.1b1
|
||||
### From v0.0.1a1 to v0.0.1b2
|
||||
*No breaking changes - all existing code continues to work!*
|
||||
|
||||
**Optional Enhancements:**
|
||||
|
|
|
|||
|
|
@ -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={
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
from zai import ZaiClient
|
||||
|
||||
from zai import ZaiClient, ZhipuAiClient
|
||||
|
||||
def completion():
|
||||
# Initialize client
|
||||
|
|
@ -159,10 +158,33 @@ def audio_transcription():
|
|||
)
|
||||
print(response.text)
|
||||
|
||||
def ofZai():
|
||||
client = ZaiClient()
|
||||
print(client.base_url)
|
||||
response = client.chat.completions.create(
|
||||
model='glm-4',
|
||||
messages=[{'role': 'user', 'content': 'Hello, Z.ai!'}],
|
||||
temperature=0.7,
|
||||
)
|
||||
print(response.choices[0].message.content)
|
||||
|
||||
def ofZhipu():
|
||||
client = ZhipuAiClient()
|
||||
print(client.base_url)
|
||||
response = client.chat.completions.create(
|
||||
model='glm-4',
|
||||
messages=[{'role': 'user', 'content': 'Hello, Z.ai!'}],
|
||||
temperature=0.7,
|
||||
)
|
||||
print(response.choices[0].message.content)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# completion()
|
||||
# completion_with_websearch()
|
||||
# multi_modal_chat()
|
||||
# role_play()
|
||||
# assistant_conversation()
|
||||
video_generation()
|
||||
# video_generation()
|
||||
ofZai()
|
||||
ofZhipu()
|
||||
|
||||
|
|
|
|||
13
examples/check_apikey_env.py
Normal file
13
examples/check_apikey_env.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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()
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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,24 @@ 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",
|
||||
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 +177,11 @@ class VideoModelsExamples:
|
|||
response = self.client.videos.generations(
|
||||
model="viduq1-text",
|
||||
prompt=prompt,
|
||||
quality=quality,
|
||||
with_audio=with_audio,
|
||||
style=style,
|
||||
duration=duration,
|
||||
aspect_ratio=aspect_ratio,
|
||||
size=size,
|
||||
fps=fps,
|
||||
movement_amplitude=movement_amplitude,
|
||||
)
|
||||
return await self._wait_for_completion(response.id, max_wait_time)
|
||||
except Exception as e:
|
||||
|
|
@ -201,22 +192,21 @@ 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",
|
||||
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 +215,9 @@ class VideoModelsExamples:
|
|||
model="viduq1-image",
|
||||
image_url=image_url,
|
||||
prompt=prompt,
|
||||
quality=quality,
|
||||
with_audio=with_audio,
|
||||
duration=duration,
|
||||
size=size,
|
||||
fps=fps,
|
||||
movement_amplitude=movement_amplitude,
|
||||
)
|
||||
return await self._wait_for_completion(response.id, max_wait_time)
|
||||
except Exception as e:
|
||||
|
|
@ -239,34 +228,32 @@ 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",
|
||||
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,
|
||||
quality=quality,
|
||||
with_audio=with_audio,
|
||||
duration=duration,
|
||||
size=size,
|
||||
fps=fps,
|
||||
movement_amplitude=movement_amplitude,
|
||||
)
|
||||
return await self._wait_for_completion(response.id, max_wait_time)
|
||||
except Exception as e:
|
||||
|
|
@ -277,22 +264,21 @@ class VideoModelsExamples:
|
|||
self,
|
||||
image_url: str,
|
||||
prompt: str,
|
||||
quality: str = "quality",
|
||||
with_audio: bool = True,
|
||||
size: str = "1920x1080",
|
||||
fps: int = 30,
|
||||
duration: int = 4,
|
||||
size: str = "1280x720",
|
||||
movement_amplitude: str = "auto",
|
||||
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 +287,9 @@ 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,
|
||||
)
|
||||
return await self._wait_for_completion(response.id, max_wait_time)
|
||||
except Exception as e:
|
||||
|
|
@ -315,34 +300,32 @@ class VideoModelsExamples:
|
|||
self,
|
||||
image_urls: List[str],
|
||||
prompt: str,
|
||||
quality: str = "quality",
|
||||
with_audio: bool = True,
|
||||
size: str = "1920x1080",
|
||||
fps: int = 30,
|
||||
duration: int = 4,
|
||||
size: str = "1280x720",
|
||||
movement_amplitude: str = "auto",
|
||||
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,
|
||||
)
|
||||
return await self._wait_for_completion(response.id, max_wait_time)
|
||||
except Exception as e:
|
||||
|
|
@ -351,24 +334,26 @@ class VideoModelsExamples:
|
|||
|
||||
async def vidu2_reference_video(
|
||||
self,
|
||||
image_url: str,
|
||||
image_url: List[str],
|
||||
prompt: str,
|
||||
quality: str = "quality",
|
||||
with_audio: bool = True,
|
||||
size: str = "1920x1080",
|
||||
fps: int = 30,
|
||||
duration: int = 4,
|
||||
aspect_ratio: str = "16:9",
|
||||
size: str = "1280x720",
|
||||
movement_amplitude: str = "auto",
|
||||
max_wait_time: int = 300,
|
||||
with_audio: bool = True,
|
||||
):
|
||||
"""
|
||||
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 +362,11 @@ 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,
|
||||
)
|
||||
return await self._wait_for_completion(response.id, max_wait_time)
|
||||
except Exception as e:
|
||||
|
|
@ -426,13 +412,17 @@ 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"
|
||||
sample_first_frame = "https://gd-hbimg.huaban.com/ccee58d77afe8f5e17a572246b1994f7e027657fe9e6-qD66In_fw1200webp"
|
||||
sample_last_frame = "https://gd-hbimg.huaban.com/cc2601d568a72d18d90b2cc7f1065b16b2d693f7fa3f7-hDAwNq_fw1200webp"
|
||||
ref_image_url = ["ref1", "ref2", "ref3"]
|
||||
ref_image_url = [
|
||||
"https://gd-hbimg.huaban.com/ccee58d77afe8f5e17a572246b1994f7e027657fe9e6-qD66In_fw1200webp",
|
||||
"https://gd-hbimg.huaban.com/cc2601d568a72d18d90b2cc7f1065b16b2d693f7fa3f7-hDAwNq_fw1200webp",
|
||||
"https://gd-hbimg.huaban.com/cc2601d568a72d18d90b2cc7f1065b16b2d693f7fa3f7-hDAwNq_fw1200webp"
|
||||
]
|
||||
|
||||
try:
|
||||
# 1. cogvideox-3 text-to-video
|
||||
|
|
@ -481,10 +471,14 @@ async def main():
|
|||
|
||||
# 5. viduq1-text text-to-video
|
||||
print("\n" + "="*50)
|
||||
print(os.environ.get("ZAI_API_KEY"))
|
||||
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.",
|
||||
quality="speed",
|
||||
with_audio=True,
|
||||
style="general",
|
||||
duration=5,
|
||||
aspect_ratio="16:9",
|
||||
size="1920x1080",
|
||||
movement_amplitude="auto",
|
||||
)
|
||||
print("viduq1-text text-to-video result:", result5)
|
||||
|
||||
|
|
@ -493,18 +487,20 @@ 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.",
|
||||
quality="speed",
|
||||
with_audio=True,
|
||||
duration=5,
|
||||
size="1920x1080",
|
||||
movement_amplitude="auto",
|
||||
)
|
||||
print("viduq1-image image-to-video result:", result6)
|
||||
|
||||
# 7. viduq1-start-end start-end frame video
|
||||
print("\n" + "="*50)
|
||||
result7 = await examples.viduq1_start_end_video(
|
||||
image_url=[sample_first_frame, sample_last_frame],
|
||||
image_urls=[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",
|
||||
with_audio=True,
|
||||
duration=5,
|
||||
size="1920x1080",
|
||||
movement_amplitude="auto",
|
||||
)
|
||||
print("viduq1-start-end start-end frame video result:", result7)
|
||||
|
||||
|
|
@ -513,18 +509,20 @@ 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",
|
||||
with_audio=True,
|
||||
duration=4,
|
||||
size="1280x720",
|
||||
movement_amplitude="auto",
|
||||
)
|
||||
print("vidu2-image image-to-video result:", result8)
|
||||
|
||||
# 9. vidu2-start-end start-end frame video
|
||||
print("\n" + "="*50)
|
||||
result9 = await examples.vidu2_start_end_video(
|
||||
image_url=[sample_first_frame, sample_last_frame],
|
||||
image_urls=[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",
|
||||
with_audio=True,
|
||||
duration=4,
|
||||
size="1280x720",
|
||||
movement_amplitude="auto",
|
||||
)
|
||||
print("vidu2-start-end start-end frame video result:", result9)
|
||||
|
||||
|
|
@ -533,7 +531,10 @@ 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,
|
||||
)
|
||||
print("vidu2-reference reference video generation result:", result10)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "zai-sdk"
|
||||
version = "0.0.1b1"
|
||||
version = "0.0.1b2"
|
||||
description = "A SDK library for accessing big model apis from Z.ai"
|
||||
authors = ["Z.ai"]
|
||||
readme = "README.md"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from ._client import ZaiClient
|
||||
from ._client import ZaiClient, ZhipuAiClient
|
||||
from ._version import __version__
|
||||
|
||||
__all__ = ['ZaiClient', '__version__']
|
||||
__all__ = ['ZaiClient', 'ZhipuAiClient', '__version__']
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ from .core import (
|
|||
_jwt_token,
|
||||
)
|
||||
|
||||
|
||||
class ZaiClient(HttpClient):
|
||||
class BaseClient(HttpClient):
|
||||
"""
|
||||
Main client for interacting with the ZAI API
|
||||
|
||||
|
|
@ -47,7 +46,8 @@ class ZaiClient(HttpClient):
|
|||
|
||||
chat: Chat
|
||||
api_key: str
|
||||
_disable_token_cache: bool = True
|
||||
base_url: str
|
||||
disable_token_cache: bool = True
|
||||
source_channel: str
|
||||
|
||||
def __init__(
|
||||
|
|
@ -62,7 +62,6 @@ class ZaiClient(HttpClient):
|
|||
disable_token_cache: bool = True,
|
||||
_strict_response_validation: bool = False,
|
||||
source_channel: str | None = None,
|
||||
switch_to_zhipu: bool = False,
|
||||
) -> None:
|
||||
"""
|
||||
Initialize the ZAI client
|
||||
|
|
@ -79,7 +78,6 @@ class ZaiClient(HttpClient):
|
|||
disable_token_cache (bool): Whether to disable JWT token caching
|
||||
_strict_response_validation (bool): Whether to enable strict response validation
|
||||
source_channel (str | None): Source channel identifier
|
||||
switch_to_zhipu (bool): Whether to switch to Zhipu base_url
|
||||
"""
|
||||
if api_key is None:
|
||||
api_key = os.environ.get('ZAI_API_KEY')
|
||||
|
|
@ -87,16 +85,15 @@ class ZaiClient(HttpClient):
|
|||
raise ZaiError('api_key not provided, please provide it through parameters or environment variables')
|
||||
self.api_key = api_key
|
||||
self.source_channel = source_channel
|
||||
self._disable_token_cache = disable_token_cache
|
||||
self.disable_token_cache = disable_token_cache
|
||||
|
||||
if base_url is None:
|
||||
base_url = os.environ.get('ZAI_BASE_URL')
|
||||
if base_url is None:
|
||||
base_url = 'https://api.z.ai/api/paas/v4'
|
||||
if switch_to_zhipu:
|
||||
base_url = 'https://open.bigmodel.cn/api/paas/v4'
|
||||
from ._version import __version__
|
||||
base_url = self.default_base_url
|
||||
self.base_url = base_url
|
||||
|
||||
from ._version import __version__
|
||||
super().__init__(
|
||||
version=__version__,
|
||||
base_url=base_url,
|
||||
|
|
@ -107,6 +104,10 @@ class ZaiClient(HttpClient):
|
|||
_strict_response_validation=_strict_response_validation,
|
||||
)
|
||||
|
||||
@property
|
||||
def default_base_url(self):
|
||||
raise NotImplementedError("Subclasses must define default_base_url")
|
||||
|
||||
@cached_property
|
||||
def chat(self) -> Chat:
|
||||
from zai.api_resource.chat import Chat
|
||||
|
|
@ -196,7 +197,7 @@ class ZaiClient(HttpClient):
|
|||
def auth_headers(self) -> dict[str, str]:
|
||||
api_key = self.api_key
|
||||
source_channel = self.source_channel or 'python-sdk'
|
||||
if self._disable_token_cache:
|
||||
if self.disable_token_cache:
|
||||
return {
|
||||
'Authorization': f'Bearer {api_key}',
|
||||
'x-source-channel': source_channel,
|
||||
|
|
@ -216,3 +217,13 @@ class ZaiClient(HttpClient):
|
|||
return
|
||||
|
||||
self.close()
|
||||
|
||||
class ZaiClient(BaseClient):
|
||||
@property
|
||||
def default_base_url(self):
|
||||
return 'https://api.z.ai/api/paas/v4'
|
||||
|
||||
class ZhipuAiClient(BaseClient):
|
||||
@property
|
||||
def default_base_url(self):
|
||||
return 'https://open.bigmodel.cn/api/paas/v4'
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
__title__ = 'Z.ai'
|
||||
__version__ = '0.0.1b1'
|
||||
__version__ = '0.0.1b2'
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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[str] | 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue