runapi-happyhorse 0.2.5 → 0.2.7
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.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/lib/runapi/happyhorse/client.rb +15 -6
- data/lib/runapi/happyhorse/contract_gen.rb +82 -0
- data/lib/runapi/happyhorse/resources/edit_video.rb +16 -4
- data/lib/runapi/happyhorse/resources/image_to_video.rb +15 -3
- data/lib/runapi/happyhorse/resources/text_to_video.rb +18 -6
- data/lib/runapi/happyhorse/types.rb +7 -7
- data/lib/runapi/happyhorse.rb +1 -0
- metadata +10 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f6dce8cdd8d38b5c1062594b3de7c673544d2558abe8db1c616b35e81ae1c9bc
|
|
4
|
+
data.tar.gz: c2ab10637f4c26d08b77e6b44dc80eb51be19c99b6ba34d610656426771b6555
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6e19584b1a78ef79a9d869b5eef458afd4fb5b7b7d87d395db073e7654caf27bdc0a656b97851796cc0d7eb979113c9a1aa555cfa0c67d875c395dc2c6ee5be6
|
|
7
|
+
data.tar.gz: cd1e0d2335573a8ac73d3df65640555fc0afb3f4bc1427c1bf1386d232a209769f3a7a94a68eee82c86d9910be40b5927427beb3f07e535ee6f993ab30c5c8e6
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# HappyHorse API Ruby SDK for RunAPI
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The HappyHorse Ruby SDK is the language-specific package for HappyHorse on RunAPI. Use this package for video generation, animation, and video editing workflows when your application needs request bodies, task status lookup, and consistent RunAPI errors in Ruby.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -26,6 +26,8 @@ video = client.text_to_video.run(
|
|
|
26
26
|
|
|
27
27
|
For image-to-video, call `client.image_to_video.run` with `model: "happyhorse-image-to-video"` and exactly one `image_urls` entry. For character-guided text-to-video, call `client.text_to_video.run` with `model: "happyhorse-character"` and 1-9 `reference_image_urls` entries. For edit-video, call `client.edit_video.run` with `model: "happyhorse-edit-video"`, one `video_url`, and optional `reference_image` entries.
|
|
28
28
|
|
|
29
|
+
RunAPI-generated file URLs are temporary. Download and store generated images, videos, audio, or other files in your own durable storage within 7 days; do not treat returned URLs as long-term assets.
|
|
30
|
+
|
|
29
31
|
## Links
|
|
30
32
|
|
|
31
33
|
- Model page: https://runapi.ai/models/happyhorse
|
|
@@ -2,14 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module HappyHorse
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
# HappyHorse video generation and editing API client.
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# client = RunApi::HappyHorse::Client.new(api_key: "your-api-key")
|
|
9
|
+
# result = client.text_to_video.run(
|
|
10
|
+
# model: "happyhorse-text-to-video", prompt: "A horse galloping across a sunset beach"
|
|
11
|
+
# )
|
|
12
|
+
class Client < RunApi::Core::Client
|
|
13
|
+
# @return [Resources::TextToVideo] Text-to-video generation with optional character consistency.
|
|
14
|
+
attr_reader :text_to_video
|
|
15
|
+
# @return [Resources::ImageToVideo] Image-to-video animation from a first-frame image.
|
|
16
|
+
attr_reader :image_to_video
|
|
17
|
+
# @return [Resources::EditVideo] Video editing with text prompts and reference images.
|
|
18
|
+
attr_reader :edit_video
|
|
7
19
|
|
|
8
20
|
def initialize(api_key: nil, **options)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
client_options = Core::ClientOptions.new(api_key: @api_key, **options)
|
|
12
|
-
http = client_options.http_client || Core::HttpClient.new(client_options)
|
|
21
|
+
super
|
|
13
22
|
@text_to_video = Resources::TextToVideo.new(http)
|
|
14
23
|
@image_to_video = Resources::ImageToVideo.new(http)
|
|
15
24
|
@edit_video = Resources::EditVideo.new(http)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module HappyHorse
|
|
5
|
+
CONTRACT = {
|
|
6
|
+
"edit-video" => {
|
|
7
|
+
"models" => ["happyhorse-edit-video"],
|
|
8
|
+
"fields_by_model" => {
|
|
9
|
+
"happyhorse-edit-video" => {
|
|
10
|
+
"audio_setting" => {
|
|
11
|
+
"enum" => ["auto", "original"]
|
|
12
|
+
},
|
|
13
|
+
"output_resolution" => {
|
|
14
|
+
"enum" => ["720p", "1080p"]
|
|
15
|
+
},
|
|
16
|
+
"seed" => {
|
|
17
|
+
"type" => "integer"
|
|
18
|
+
},
|
|
19
|
+
"source_video_url" => {
|
|
20
|
+
"required" => true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"image-to-video" => {
|
|
26
|
+
"models" => ["happyhorse-image-to-video"],
|
|
27
|
+
"fields_by_model" => {
|
|
28
|
+
"happyhorse-image-to-video" => {
|
|
29
|
+
"duration_seconds" => {
|
|
30
|
+
"type" => "integer"
|
|
31
|
+
},
|
|
32
|
+
"first_frame_image_url" => {
|
|
33
|
+
"required" => true
|
|
34
|
+
},
|
|
35
|
+
"output_resolution" => {
|
|
36
|
+
"enum" => ["720p", "1080p"]
|
|
37
|
+
},
|
|
38
|
+
"seed" => {
|
|
39
|
+
"type" => "integer"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"text-to-video" => {
|
|
45
|
+
"models" => ["happyhorse-character", "happyhorse-text-to-video"],
|
|
46
|
+
"fields_by_model" => {
|
|
47
|
+
"happyhorse-character" => {
|
|
48
|
+
"aspect_ratio" => {
|
|
49
|
+
"enum" => ["16:9", "9:16", "1:1", "4:3", "3:4"]
|
|
50
|
+
},
|
|
51
|
+
"duration_seconds" => {
|
|
52
|
+
"type" => "integer"
|
|
53
|
+
},
|
|
54
|
+
"output_resolution" => {
|
|
55
|
+
"enum" => ["720p", "1080p"]
|
|
56
|
+
},
|
|
57
|
+
"reference_image_urls" => {
|
|
58
|
+
"required" => true
|
|
59
|
+
},
|
|
60
|
+
"seed" => {
|
|
61
|
+
"type" => "integer"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"happyhorse-text-to-video" => {
|
|
65
|
+
"aspect_ratio" => {
|
|
66
|
+
"enum" => ["16:9", "9:16", "1:1", "4:3", "3:4"]
|
|
67
|
+
},
|
|
68
|
+
"duration_seconds" => {
|
|
69
|
+
"type" => "integer"
|
|
70
|
+
},
|
|
71
|
+
"output_resolution" => {
|
|
72
|
+
"enum" => ["720p", "1080p"]
|
|
73
|
+
},
|
|
74
|
+
"seed" => {
|
|
75
|
+
"type" => "integer"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}.freeze
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module HappyHorse
|
|
5
5
|
module Resources
|
|
6
|
+
# HappyHorse edit-video resource.
|
|
7
|
+
# Transform an existing video with a text prompt and optional reference images.
|
|
6
8
|
class EditVideo
|
|
7
9
|
include RunApi::Core::ResourceHelpers
|
|
8
10
|
|
|
@@ -16,17 +18,29 @@ module RunApi
|
|
|
16
18
|
@http = http
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
# Create an edit-video task and wait until complete.
|
|
22
|
+
#
|
|
23
|
+
# @param params [Hash] edit-video parameters
|
|
24
|
+
# @return [RunApi::HappyHorse::Types::CompletedEditVideoResponse] completed task with videos
|
|
19
25
|
def run(**params)
|
|
20
26
|
task = create(**params)
|
|
21
27
|
poll_until_complete { get(task.id) }
|
|
22
28
|
end
|
|
23
29
|
|
|
30
|
+
# Create an edit-video task.
|
|
31
|
+
#
|
|
32
|
+
# @param params [Hash] edit-video parameters
|
|
33
|
+
# @return [RunApi::HappyHorse::Types::EditVideoResponse] task creation result with id
|
|
24
34
|
def create(**params)
|
|
25
35
|
params = compact_params(params)
|
|
26
36
|
validate_params!(params)
|
|
27
37
|
request(:post, ENDPOINT, body: params)
|
|
28
38
|
end
|
|
29
39
|
|
|
40
|
+
# Get edit-video task status by task ID.
|
|
41
|
+
#
|
|
42
|
+
# @param id [String] task ID
|
|
43
|
+
# @return [RunApi::HappyHorse::Types::EditVideoResponse] current task status
|
|
30
44
|
def get(id)
|
|
31
45
|
request(:get, "#{ENDPOINT}/#{id}")
|
|
32
46
|
end
|
|
@@ -34,17 +48,15 @@ module RunApi
|
|
|
34
48
|
private
|
|
35
49
|
|
|
36
50
|
def validate_params!(params)
|
|
37
|
-
|
|
51
|
+
validate_contract!(CONTRACT["edit-video"], params)
|
|
52
|
+
|
|
38
53
|
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
39
|
-
raise Core::ValidationError, "source_video_url is required" unless param(params, :source_video_url)
|
|
40
54
|
|
|
41
55
|
reference_image_urls = param(params, :reference_image_urls)
|
|
42
56
|
if reference_image_urls && (!reference_image_urls.is_a?(Array) || !REFERENCE_IMAGE_RANGE.cover?(reference_image_urls.size))
|
|
43
57
|
raise Core::ValidationError, "reference_image_urls must include at most #{REFERENCE_IMAGE_RANGE.max} entries"
|
|
44
58
|
end
|
|
45
59
|
|
|
46
|
-
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
47
|
-
validate_optional!(params, :audio_setting, Types::AUDIO_SETTINGS)
|
|
48
60
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
49
61
|
end
|
|
50
62
|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module HappyHorse
|
|
5
5
|
module Resources
|
|
6
|
+
# HappyHorse image-to-video resource.
|
|
7
|
+
# Animate a still first-frame image into video, guided by an optional text prompt.
|
|
6
8
|
class ImageToVideo
|
|
7
9
|
include RunApi::Core::ResourceHelpers
|
|
8
10
|
|
|
@@ -15,17 +17,29 @@ module RunApi
|
|
|
15
17
|
@http = http
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
# Create an image-to-video task and wait until complete.
|
|
21
|
+
#
|
|
22
|
+
# @param params [Hash] image-to-video parameters
|
|
23
|
+
# @return [RunApi::HappyHorse::Types::CompletedImageToVideoResponse] completed task with videos
|
|
18
24
|
def run(**params)
|
|
19
25
|
task = create(**params)
|
|
20
26
|
poll_until_complete { get(task.id) }
|
|
21
27
|
end
|
|
22
28
|
|
|
29
|
+
# Create an image-to-video task.
|
|
30
|
+
#
|
|
31
|
+
# @param params [Hash] image-to-video parameters
|
|
32
|
+
# @return [RunApi::HappyHorse::Types::ImageToVideoResponse] task creation result with id
|
|
23
33
|
def create(**params)
|
|
24
34
|
params = compact_params(params)
|
|
25
35
|
validate_params!(params)
|
|
26
36
|
request(:post, ENDPOINT, body: params)
|
|
27
37
|
end
|
|
28
38
|
|
|
39
|
+
# Get image-to-video task status by task ID.
|
|
40
|
+
#
|
|
41
|
+
# @param id [String] task ID
|
|
42
|
+
# @return [RunApi::HappyHorse::Types::ImageToVideoResponse] current task status
|
|
29
43
|
def get(id)
|
|
30
44
|
request(:get, "#{ENDPOINT}/#{id}")
|
|
31
45
|
end
|
|
@@ -33,10 +47,8 @@ module RunApi
|
|
|
33
47
|
private
|
|
34
48
|
|
|
35
49
|
def validate_params!(params)
|
|
36
|
-
|
|
37
|
-
raise Core::ValidationError, "first_frame_image_url is required" unless param(params, :first_frame_image_url)
|
|
50
|
+
validate_contract!(CONTRACT["image-to-video"], params)
|
|
38
51
|
|
|
39
|
-
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
40
52
|
validate_integer_range!(params, :duration_seconds, Types::DURATION_RANGE)
|
|
41
53
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
42
54
|
end
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module HappyHorse
|
|
5
5
|
module Resources
|
|
6
|
+
# HappyHorse text-to-video resource.
|
|
7
|
+
# Generate video from a text prompt, with optional character consistency via happyhorse-character.
|
|
6
8
|
class TextToVideo
|
|
7
9
|
include RunApi::Core::ResourceHelpers
|
|
8
10
|
|
|
@@ -16,17 +18,29 @@ module RunApi
|
|
|
16
18
|
@http = http
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
# Create a text-to-video task and wait until complete.
|
|
22
|
+
#
|
|
23
|
+
# @param params [Hash] text-to-video parameters
|
|
24
|
+
# @return [RunApi::HappyHorse::Types::CompletedTextToVideoResponse] completed task with videos
|
|
19
25
|
def run(**params)
|
|
20
26
|
task = create(**params)
|
|
21
27
|
poll_until_complete { get(task.id) }
|
|
22
28
|
end
|
|
23
29
|
|
|
30
|
+
# Create a text-to-video task.
|
|
31
|
+
#
|
|
32
|
+
# @param params [Hash] text-to-video parameters
|
|
33
|
+
# @return [RunApi::HappyHorse::Types::TextToVideoResponse] task creation result with id
|
|
24
34
|
def create(**params)
|
|
25
35
|
params = compact_params(params)
|
|
26
36
|
validate_params!(params)
|
|
27
37
|
request(:post, ENDPOINT, body: params)
|
|
28
38
|
end
|
|
29
39
|
|
|
40
|
+
# Get text-to-video task status by task ID.
|
|
41
|
+
#
|
|
42
|
+
# @param id [String] task ID
|
|
43
|
+
# @return [RunApi::HappyHorse::Types::TextToVideoResponse] current task status
|
|
30
44
|
def get(id)
|
|
31
45
|
request(:get, "#{ENDPOINT}/#{id}")
|
|
32
46
|
end
|
|
@@ -34,21 +48,19 @@ module RunApi
|
|
|
34
48
|
private
|
|
35
49
|
|
|
36
50
|
def validate_params!(params)
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
validate_contract!(CONTRACT["text-to-video"], params)
|
|
52
|
+
|
|
39
53
|
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
40
54
|
|
|
41
55
|
reference_image_urls = param(params, :reference_image_urls)
|
|
42
|
-
if model == Types::CHARACTER_MODEL
|
|
43
|
-
|
|
56
|
+
if param(params, :model) == Types::CHARACTER_MODEL
|
|
57
|
+
if reference_image_urls && !(reference_image_urls.is_a?(Array) && REFERENCE_IMAGE_URLS_RANGE.cover?(reference_image_urls.size))
|
|
44
58
|
raise Core::ValidationError, "reference_image_urls must include between #{REFERENCE_IMAGE_URLS_RANGE.min} and #{REFERENCE_IMAGE_URLS_RANGE.max} entries"
|
|
45
59
|
end
|
|
46
60
|
elsif reference_image_urls
|
|
47
61
|
raise Core::ValidationError, "reference_image_urls is only supported for #{Types::CHARACTER_MODEL}"
|
|
48
62
|
end
|
|
49
63
|
|
|
50
|
-
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
51
|
-
validate_optional!(params, :aspect_ratio, Types::ASPECT_RATIOS)
|
|
52
64
|
validate_integer_range!(params, :duration_seconds, Types::DURATION_RANGE)
|
|
53
65
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
54
66
|
end
|
|
@@ -2,18 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module HappyHorse
|
|
5
|
+
# Type definitions and constants for HappyHorse video generation and editing.
|
|
5
6
|
module Types
|
|
6
|
-
|
|
7
|
+
# Character-consistent model; requires 1-9 reference_image_urls.
|
|
7
8
|
CHARACTER_MODEL = "happyhorse-character"
|
|
8
|
-
|
|
9
|
-
IMAGE_TO_VIDEO_MODEL = "happyhorse-image-to-video"
|
|
10
|
-
EDIT_VIDEO_MODEL = "happyhorse-edit-video"
|
|
11
|
-
OUTPUT_RESOLUTIONS = %w[720p 1080p].freeze
|
|
12
|
-
ASPECT_RATIOS = %w[16:9 9:16 1:1 4:3 3:4].freeze
|
|
13
|
-
AUDIO_SETTINGS = %w[auto original].freeze
|
|
9
|
+
# Duration range in seconds (3-15). Defaults to 5.
|
|
14
10
|
DURATION_RANGE = (3..15)
|
|
11
|
+
# Reproducibility seed range.
|
|
15
12
|
SEED_RANGE = (0..2_147_483_647)
|
|
16
13
|
|
|
14
|
+
# A generated video file with a download URL.
|
|
17
15
|
class MediaUrl < RunApi::Core::BaseModel
|
|
18
16
|
optional :url, String
|
|
19
17
|
end
|
|
@@ -25,6 +23,8 @@ module RunApi
|
|
|
25
23
|
optional :error, String
|
|
26
24
|
end
|
|
27
25
|
|
|
26
|
+
# Narrowed response returned by +run()+ once polling observes +status: "completed"+.
|
|
27
|
+
# +videos+ is required so consumers never have to null-check it on a successful task.
|
|
28
28
|
class CompletedTextToVideoResponse < TextToVideoResponse
|
|
29
29
|
required :videos, [-> { MediaUrl }]
|
|
30
30
|
end
|
data/lib/runapi/happyhorse.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "runapi/core"
|
|
4
4
|
require_relative "happyhorse/types"
|
|
5
|
+
require_relative "happyhorse/contract_gen"
|
|
5
6
|
require_relative "happyhorse/resources/edit_video"
|
|
6
7
|
require_relative "happyhorse/resources/image_to_video"
|
|
7
8
|
require_relative "happyhorse/resources/text_to_video"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: runapi-happyhorse
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- RunAPI
|
|
@@ -15,17 +15,18 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.2.
|
|
18
|
+
version: 0.2.7
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.2.
|
|
26
|
-
description: The
|
|
27
|
-
on RunAPI. Use this package for
|
|
28
|
-
|
|
25
|
+
version: 0.2.7
|
|
26
|
+
description: The HappyHorse Ruby SDK is the language-specific package for HappyHorse
|
|
27
|
+
on RunAPI. Use this package for video generation, animation, and video editing workflows
|
|
28
|
+
when your application needs request bodies, task status lookup, and consistent RunAPI
|
|
29
|
+
errors in Ruby.
|
|
29
30
|
email:
|
|
30
31
|
- contact@runapi.ai
|
|
31
32
|
executables: []
|
|
@@ -38,6 +39,7 @@ files:
|
|
|
38
39
|
- lib/runapi-happyhorse.rb
|
|
39
40
|
- lib/runapi/happyhorse.rb
|
|
40
41
|
- lib/runapi/happyhorse/client.rb
|
|
42
|
+
- lib/runapi/happyhorse/contract_gen.rb
|
|
41
43
|
- lib/runapi/happyhorse/resources/edit_video.rb
|
|
42
44
|
- lib/runapi/happyhorse/resources/image_to_video.rb
|
|
43
45
|
- lib/runapi/happyhorse/resources/text_to_video.rb
|
|
@@ -46,9 +48,11 @@ homepage: https://runapi.ai/models/happyhorse
|
|
|
46
48
|
licenses:
|
|
47
49
|
- Apache-2.0
|
|
48
50
|
metadata:
|
|
51
|
+
runapi_slug: happyhorse
|
|
49
52
|
homepage_uri: https://runapi.ai/models/happyhorse
|
|
50
53
|
documentation_uri: https://github.com/runapi-ai/happyhorse-sdk/blob/main/ruby/README.md
|
|
51
54
|
source_code_uri: https://github.com/runapi-ai/happyhorse-sdk
|
|
55
|
+
bug_tracker_uri: https://github.com/runapi-ai/happyhorse-sdk/issues
|
|
52
56
|
changelog_uri: https://github.com/runapi-ai/happyhorse-sdk/blob/main/CHANGELOG.md
|
|
53
57
|
rdoc_options: []
|
|
54
58
|
require_paths:
|