runapi-heygen-video 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runapi_heygen_video-0.1.0/LICENSE +21 -0
- runapi_heygen_video-0.1.0/PKG-INFO +45 -0
- runapi_heygen_video-0.1.0/README.md +27 -0
- runapi_heygen_video-0.1.0/pyproject.toml +34 -0
- runapi_heygen_video-0.1.0/src/runapi/heygen_video/__init__.py +24 -0
- runapi_heygen_video-0.1.0/src/runapi/heygen_video/client.py +28 -0
- runapi_heygen_video-0.1.0/src/runapi/heygen_video/py.typed +0 -0
- runapi_heygen_video-0.1.0/src/runapi/heygen_video/resources/__init__.py +4 -0
- runapi_heygen_video-0.1.0/src/runapi/heygen_video/resources/image_to_video.py +56 -0
- runapi_heygen_video-0.1.0/src/runapi/heygen_video/resources/text_to_video.py +56 -0
- runapi_heygen_video-0.1.0/src/runapi/heygen_video/types.py +24 -0
- runapi_heygen_video-0.1.0/tests/test_client.py +47 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 RunAPI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: runapi-heygen-video
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: RunAPI HeyGen Video SDK for text-to-video, reference-guided, and image-to-video workflows with generated sound in JavaScript, Python, Ruby, Go, Java, and PHP
|
|
5
|
+
Project-URL: Homepage, https://runapi.ai/models/heygen-video
|
|
6
|
+
Project-URL: Documentation, https://runapi.ai/docs/resources/sdks
|
|
7
|
+
Project-URL: Source, https://github.com/runapi-ai/heygen-video-sdk
|
|
8
|
+
Project-URL: Issues, https://github.com/runapi-ai/heygen-video-sdk/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/runapi-ai/heygen-video-sdk/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Release Notes, https://github.com/runapi-ai/heygen-video-sdk/releases/tag/python%2Fv0.1.0
|
|
11
|
+
Author-email: RunAPI <contact@runapi.ai>
|
|
12
|
+
License-Expression: Apache-2.0
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: api,golang,gradle,heygen-video,image-to-video,java,maven,python,ruby,runapi,runapi-ai,sdk,text-to-video,typescript,video-generation
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Requires-Dist: runapi-core~=0.10.1
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# HeyGen Video API Python SDK for RunAPI
|
|
20
|
+
|
|
21
|
+
Use `runapi-heygen-video` for HeyGen Video video tasks in Python.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install runapi-heygen-video
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from runapi.heygen_video import HeyGenVideoClient
|
|
29
|
+
|
|
30
|
+
client = HeyGenVideoClient()
|
|
31
|
+
result = client.text_to_video.run(
|
|
32
|
+
model="heygen-video-1",
|
|
33
|
+
prompt="A cinematic tracking shot through a rain-soaked city",
|
|
34
|
+
aspect_ratio="16:9",
|
|
35
|
+
)
|
|
36
|
+
print(result.videos[0].url)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Use `text_to_video` for prompt-only or reference-media generation. Use `image_to_video` with a first-frame image. Each resource provides `create`, `get`, and `run`.
|
|
40
|
+
|
|
41
|
+
- [Model reference](https://runapi.ai/models/heygen-video)
|
|
42
|
+
- [API reference](https://runapi.ai/docs/api/heygen-video/text-to-video)
|
|
43
|
+
- [Pricing and rate limits](https://runapi.ai/models/heygen-video)
|
|
44
|
+
|
|
45
|
+
Licensed under the Apache License, Version 2.0.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# HeyGen Video API Python SDK for RunAPI
|
|
2
|
+
|
|
3
|
+
Use `runapi-heygen-video` for HeyGen Video video tasks in Python.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install runapi-heygen-video
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from runapi.heygen_video import HeyGenVideoClient
|
|
11
|
+
|
|
12
|
+
client = HeyGenVideoClient()
|
|
13
|
+
result = client.text_to_video.run(
|
|
14
|
+
model="heygen-video-1",
|
|
15
|
+
prompt="A cinematic tracking shot through a rain-soaked city",
|
|
16
|
+
aspect_ratio="16:9",
|
|
17
|
+
)
|
|
18
|
+
print(result.videos[0].url)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Use `text_to_video` for prompt-only or reference-media generation. Use `image_to_video` with a first-frame image. Each resource provides `create`, `get`, and `run`.
|
|
22
|
+
|
|
23
|
+
- [Model reference](https://runapi.ai/models/heygen-video)
|
|
24
|
+
- [API reference](https://runapi.ai/docs/api/heygen-video/text-to-video)
|
|
25
|
+
- [Pricing and rate limits](https://runapi.ai/models/heygen-video)
|
|
26
|
+
|
|
27
|
+
Licensed under the Apache License, Version 2.0.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "runapi-heygen-video"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "RunAPI HeyGen Video SDK for text-to-video, reference-guided, and image-to-video workflows with generated sound in JavaScript, Python, Ruby, Go, Java, and PHP"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
authors = [{ name = "RunAPI", email = "contact@runapi.ai" }]
|
|
13
|
+
keywords = ["runapi", "runapi-ai", "heygen-video", "api", "sdk", "typescript", "python", "ruby", "golang", "java", "maven", "gradle", "video-generation", "text-to-video", "image-to-video"]
|
|
14
|
+
dependencies = ["runapi-core~=0.10.1"]
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Homepage = "https://runapi.ai/models/heygen-video"
|
|
18
|
+
Documentation = "https://runapi.ai/docs/resources/sdks"
|
|
19
|
+
Source = "https://github.com/runapi-ai/heygen-video-sdk"
|
|
20
|
+
Issues = "https://github.com/runapi-ai/heygen-video-sdk/issues"
|
|
21
|
+
Changelog = "https://github.com/runapi-ai/heygen-video-sdk/blob/main/CHANGELOG.md"
|
|
22
|
+
"Release Notes" = "https://github.com/runapi-ai/heygen-video-sdk/releases/tag/python%2Fv0.1.0"
|
|
23
|
+
|
|
24
|
+
[tool.hatch.build.targets.wheel]
|
|
25
|
+
packages = ["src/runapi"]
|
|
26
|
+
|
|
27
|
+
[tool.uv]
|
|
28
|
+
package = true
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = ["pytest>=8"]
|
|
32
|
+
|
|
33
|
+
[tool.runapi]
|
|
34
|
+
slug = "heygen-video"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""HeyGen Video client for RunAPI."""
|
|
2
|
+
|
|
3
|
+
from runapi.core import (
|
|
4
|
+
AuthenticationError,
|
|
5
|
+
InsufficientCreditsError,
|
|
6
|
+
NotFoundError,
|
|
7
|
+
RateLimitError,
|
|
8
|
+
TaskFailedError,
|
|
9
|
+
TaskTimeoutError,
|
|
10
|
+
ValidationError,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from .client import HeyGenVideoClient
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"HeyGenVideoClient",
|
|
17
|
+
"AuthenticationError",
|
|
18
|
+
"RateLimitError",
|
|
19
|
+
"InsufficientCreditsError",
|
|
20
|
+
"NotFoundError",
|
|
21
|
+
"ValidationError",
|
|
22
|
+
"TaskFailedError",
|
|
23
|
+
"TaskTimeoutError",
|
|
24
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""HeyGen Video client."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
from runapi.core import ProviderClient
|
|
8
|
+
|
|
9
|
+
from .resources.image_to_video import ImageToVideo
|
|
10
|
+
from .resources.text_to_video import TextToVideo
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class HeyGenVideoClient(ProviderClient):
|
|
14
|
+
"""HeyGen Video text-to-video and image-to-video client.
|
|
15
|
+
|
|
16
|
+
Example::
|
|
17
|
+
|
|
18
|
+
client = HeyGenVideoClient(api_key="sk-...")
|
|
19
|
+
result = client.text_to_video.run(
|
|
20
|
+
model="heygen-video-1", prompt="A neon city street"
|
|
21
|
+
)
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, api_key: Optional[str] = None, **options: Any) -> None:
|
|
25
|
+
super().__init__(api_key, **options)
|
|
26
|
+
http = self._http
|
|
27
|
+
self.text_to_video = TextToVideo(http)
|
|
28
|
+
self.image_to_video = ImageToVideo(http)
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""HeyGen Video image-to-video resource."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
from runapi.core import Resource, RequestOptions
|
|
8
|
+
|
|
9
|
+
from ..types import (
|
|
10
|
+
CompletedVideoTaskResponse,
|
|
11
|
+
VideoTaskResponse,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ImageToVideo(Resource):
|
|
16
|
+
"""Generate videos from a source image with HeyGen Video models."""
|
|
17
|
+
|
|
18
|
+
ENDPOINT = "/api/v1/heygen_video/image_to_video"
|
|
19
|
+
|
|
20
|
+
RESPONSE_CLASS = VideoTaskResponse
|
|
21
|
+
COMPLETED_RESPONSE_CLASS = CompletedVideoTaskResponse
|
|
22
|
+
|
|
23
|
+
def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
24
|
+
"""Create an image-to-video task and poll until it completes.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
**params: Image-to-video parameters (model, prompt, ...).
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
The completed task with videos.
|
|
31
|
+
"""
|
|
32
|
+
task = self.create(options=options, **params)
|
|
33
|
+
return self._poll_until_complete(lambda: self.get(task.id, options=options))
|
|
34
|
+
|
|
35
|
+
def create(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
36
|
+
"""Create an image-to-video task and return immediately with an ``id``.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
**params: Image-to-video parameters (model, prompt, ...).
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
The task creation result with an id.
|
|
43
|
+
"""
|
|
44
|
+
compacted = self._compact_params(params)
|
|
45
|
+
return self._request("post", self.ENDPOINT, body=compacted, options=options)
|
|
46
|
+
|
|
47
|
+
def get(self, id: str, options: Optional[RequestOptions] = None) -> Any:
|
|
48
|
+
"""Fetch the current status of an image-to-video task.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
id: The task id.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
The current task status.
|
|
55
|
+
"""
|
|
56
|
+
return self._request("get", f"{self.ENDPOINT}/{id}", options=options)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""HeyGen Video text-to-video resource."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
from runapi.core import Resource, RequestOptions
|
|
8
|
+
|
|
9
|
+
from ..types import (
|
|
10
|
+
CompletedVideoTaskResponse,
|
|
11
|
+
VideoTaskResponse,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TextToVideo(Resource):
|
|
16
|
+
"""Generate videos from text prompts with HeyGen Video models."""
|
|
17
|
+
|
|
18
|
+
ENDPOINT = "/api/v1/heygen_video/text_to_video"
|
|
19
|
+
|
|
20
|
+
RESPONSE_CLASS = VideoTaskResponse
|
|
21
|
+
COMPLETED_RESPONSE_CLASS = CompletedVideoTaskResponse
|
|
22
|
+
|
|
23
|
+
def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
24
|
+
"""Create a text-to-video task and poll until it completes.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
**params: Text-to-video parameters (model, prompt, ...).
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
The completed task with videos.
|
|
31
|
+
"""
|
|
32
|
+
task = self.create(options=options, **params)
|
|
33
|
+
return self._poll_until_complete(lambda: self.get(task.id, options=options))
|
|
34
|
+
|
|
35
|
+
def create(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
36
|
+
"""Create a text-to-video task and return immediately with an ``id``.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
**params: Text-to-video parameters (model, prompt, ...).
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
The task creation result with an id.
|
|
43
|
+
"""
|
|
44
|
+
compacted = self._compact_params(params)
|
|
45
|
+
return self._request("post", self.ENDPOINT, body=compacted, options=options)
|
|
46
|
+
|
|
47
|
+
def get(self, id: str, options: Optional[RequestOptions] = None) -> Any:
|
|
48
|
+
"""Fetch the current status of a text-to-video task.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
id: The task id.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
The current task status.
|
|
55
|
+
"""
|
|
56
|
+
return self._request("get", f"{self.ENDPOINT}/{id}", options=options)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""HeyGen Video model lists, enums, and response models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from runapi.core import BaseModel, TaskResponse, optional, required
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MediaUrl(BaseModel):
|
|
9
|
+
url = optional(str)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VideoTaskResponse(TaskResponse):
|
|
13
|
+
"""Response for a video generation task."""
|
|
14
|
+
|
|
15
|
+
id = required(str)
|
|
16
|
+
status = optional(str, enum=lambda: TaskResponse.Status.ALL)
|
|
17
|
+
videos = optional([lambda: MediaUrl])
|
|
18
|
+
error = optional(str)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CompletedVideoTaskResponse(VideoTaskResponse):
|
|
22
|
+
"""Narrowed response from ``run()`` once polling observes completion."""
|
|
23
|
+
|
|
24
|
+
videos = required([lambda: MediaUrl])
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from runapi.heygen_video import HeyGenVideoClient
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class FakeHttp:
|
|
5
|
+
def __init__(self, response=None):
|
|
6
|
+
self.response = response or {"id": "task_1", "status": "pending"}
|
|
7
|
+
self.calls = []
|
|
8
|
+
|
|
9
|
+
def request(self, method, path, body=None, options=None):
|
|
10
|
+
self.calls.append((method, path, body))
|
|
11
|
+
return self.response
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_posts_reference_media_through_text_to_video():
|
|
15
|
+
fake = FakeHttp()
|
|
16
|
+
client = HeyGenVideoClient(api_key="k", http_client=fake)
|
|
17
|
+
client.text_to_video.create(
|
|
18
|
+
model="heygen-video-1",
|
|
19
|
+
prompt="Continue the performance",
|
|
20
|
+
reference_image_urls=["https://cdn.runapi.ai/public/samples/image.jpg"],
|
|
21
|
+
reference_audio_urls=["https://cdn.runapi.ai/public/samples/voice.mp3"],
|
|
22
|
+
aspect_ratio="adaptive",
|
|
23
|
+
)
|
|
24
|
+
assert fake.calls == [("post", "/api/v1/heygen_video/text_to_video", {
|
|
25
|
+
"model": "heygen-video-1",
|
|
26
|
+
"prompt": "Continue the performance",
|
|
27
|
+
"reference_image_urls": ["https://cdn.runapi.ai/public/samples/image.jpg"],
|
|
28
|
+
"reference_audio_urls": ["https://cdn.runapi.ai/public/samples/voice.mp3"],
|
|
29
|
+
"aspect_ratio": "adaptive",
|
|
30
|
+
})]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_posts_first_frame_and_seed_through_image_to_video():
|
|
34
|
+
fake = FakeHttp()
|
|
35
|
+
client = HeyGenVideoClient(api_key="k", http_client=fake)
|
|
36
|
+
client.image_to_video.create(
|
|
37
|
+
model="heygen-video-1",
|
|
38
|
+
prompt="Animate",
|
|
39
|
+
first_frame_image_url="https://cdn.runapi.ai/public/samples/image.jpg",
|
|
40
|
+
seed=42,
|
|
41
|
+
)
|
|
42
|
+
assert fake.calls == [("post", "/api/v1/heygen_video/image_to_video", {
|
|
43
|
+
"model": "heygen-video-1",
|
|
44
|
+
"prompt": "Animate",
|
|
45
|
+
"first_frame_image_url": "https://cdn.runapi.ai/public/samples/image.jpg",
|
|
46
|
+
"seed": 42,
|
|
47
|
+
})]
|