runapi-happyhorse 0.2.4 → 0.2.6
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 +11 -8
- data/lib/runapi/happyhorse/client.rb +15 -7
- data/lib/runapi/happyhorse/resources/edit_video.rb +20 -7
- data/lib/runapi/happyhorse/resources/image_to_video.rb +18 -9
- data/lib/runapi/happyhorse/resources/text_to_video.rb +29 -5
- data/lib/runapi/happyhorse/types.rb +17 -6
- data/lib/runapi/happyhorse.rb +0 -1
- metadata +5 -7
- data/lib/runapi/happyhorse/resources/reference_to_video.rb +0 -63
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8420f63d7f99ed90385490503c24de7fcb1057aafe9c7d2e707e0509df9daeb2
|
|
4
|
+
data.tar.gz: 76648efbe65479f2c4c042ae4e5d11b2fc51e8f76c0fe113836f784e797c4f98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f7e08714a1d7b8ffb5f22ac49c0d652876eeedff7c8e0a460cb9114db6604d9a98c275cb56d8244b46a0602891f62bf2ab9af652afa824476de778dc9ef6acbf
|
|
7
|
+
data.tar.gz: fefb8e30365b1d577314ef2de5dcda68bce75f85125fd0734128a5f648f255a5f2a3bdd26fc1078d637631662265ce7ab49ed197deb071cc1cfbbe5b6411c701
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# HappyHorse API Ruby SDK for RunAPI
|
|
2
2
|
|
|
3
|
-
The happyhorse ai api Ruby SDK is the language-specific package for HappyHorse on RunAPI. Use this package for text, image,
|
|
3
|
+
The happyhorse ai api Ruby SDK is the language-specific package for HappyHorse on RunAPI. Use this package for text, image, and edit-video workflows that need JSON request bodies, task status lookup, and consistent RunAPI errors in Ruby.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -15,15 +15,18 @@ require "runapi-happyhorse"
|
|
|
15
15
|
|
|
16
16
|
client = RunApi::HappyHorse::Client.new
|
|
17
17
|
video = client.text_to_video.run(
|
|
18
|
-
model: "happyhorse-
|
|
19
|
-
prompt: "
|
|
20
|
-
|
|
18
|
+
model: "happyhorse-character",
|
|
19
|
+
prompt: "Character1 walks through a miniature cardboard city at night.",
|
|
20
|
+
reference_image_urls: ["https://cdn.runapi.ai/public/samples/reference-1.jpg"],
|
|
21
|
+
output_resolution: "1080p",
|
|
21
22
|
aspect_ratio: "16:9",
|
|
22
|
-
|
|
23
|
+
duration_seconds: 5
|
|
23
24
|
)
|
|
24
25
|
```
|
|
25
26
|
|
|
26
|
-
For image-to-video, call `client.image_to_video.run` with `model: "happyhorse-image-to-video"` and exactly one `image_urls` entry. For
|
|
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
|
+
|
|
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.
|
|
27
30
|
|
|
28
31
|
## Links
|
|
29
32
|
|
|
@@ -31,8 +34,8 @@ For image-to-video, call `client.image_to_video.run` with `model: "happyhorse-im
|
|
|
31
34
|
- SDK docs: https://runapi.ai/docs#sdk-happyhorse
|
|
32
35
|
- Product docs: https://runapi.ai/docs#happyhorse
|
|
33
36
|
- Image-to-video pricing and rate limits: https://runapi.ai/models/happyhorse/image-to-video
|
|
34
|
-
-
|
|
35
|
-
- Edit-video pricing and rate limits: https://runapi.ai/models/happyhorse/video
|
|
37
|
+
- Character pricing and rate limits: https://runapi.ai/models/happyhorse/character
|
|
38
|
+
- Edit-video pricing and rate limits: https://runapi.ai/models/happyhorse/edit-video
|
|
36
39
|
- Pricing and rate limits: https://runapi.ai/models/happyhorse/text-to-video
|
|
37
40
|
- Provider comparison: https://runapi.ai/providers/alibaba
|
|
38
41
|
- Full catalog: https://runapi.ai/models
|
|
@@ -2,17 +2,25 @@
|
|
|
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
|
-
@reference_to_video = Resources::ReferenceToVideo.new(http)
|
|
16
24
|
@edit_video = Resources::EditVideo.new(http)
|
|
17
25
|
end
|
|
18
26
|
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
|
|
@@ -36,14 +50,14 @@ module RunApi
|
|
|
36
50
|
def validate_params!(params)
|
|
37
51
|
raise Core::ValidationError, "model is required" unless param(params, :model) == Types::EDIT_VIDEO_MODEL
|
|
38
52
|
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
39
|
-
raise Core::ValidationError, "
|
|
53
|
+
raise Core::ValidationError, "source_video_url is required" unless param(params, :source_video_url)
|
|
40
54
|
|
|
41
|
-
|
|
42
|
-
if
|
|
43
|
-
raise Core::ValidationError, "
|
|
55
|
+
reference_image_urls = param(params, :reference_image_urls)
|
|
56
|
+
if reference_image_urls && (!reference_image_urls.is_a?(Array) || !REFERENCE_IMAGE_RANGE.cover?(reference_image_urls.size))
|
|
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, :
|
|
60
|
+
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
47
61
|
validate_optional!(params, :audio_setting, Types::AUDIO_SETTINGS)
|
|
48
62
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
49
63
|
end
|
|
@@ -52,8 +66,7 @@ module RunApi
|
|
|
52
66
|
value = param(params, key)
|
|
53
67
|
return unless value
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
return if integer && range.cover?(integer)
|
|
69
|
+
return if value.is_a?(Integer) && range.cover?(value)
|
|
57
70
|
|
|
58
71
|
raise Core::ValidationError, "#{key} must be an integer between #{range.min} and #{range.max}"
|
|
59
72
|
end
|
|
@@ -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
|
|
|
@@ -10,23 +12,34 @@ module RunApi
|
|
|
10
12
|
|
|
11
13
|
RESPONSE_CLASS = Types::ImageToVideoResponse
|
|
12
14
|
COMPLETED_RESPONSE_CLASS = Types::CompletedImageToVideoResponse
|
|
13
|
-
IMAGE_URLS_MAX = 1
|
|
14
15
|
|
|
15
16
|
def initialize(http)
|
|
16
17
|
@http = http
|
|
17
18
|
end
|
|
18
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
|
|
19
24
|
def run(**params)
|
|
20
25
|
task = create(**params)
|
|
21
26
|
poll_until_complete { get(task.id) }
|
|
22
27
|
end
|
|
23
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
|
|
24
33
|
def create(**params)
|
|
25
34
|
params = compact_params(params)
|
|
26
35
|
validate_params!(params)
|
|
27
36
|
request(:post, ENDPOINT, body: params)
|
|
28
37
|
end
|
|
29
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
|
|
30
43
|
def get(id)
|
|
31
44
|
request(:get, "#{ENDPOINT}/#{id}")
|
|
32
45
|
end
|
|
@@ -35,13 +48,10 @@ module RunApi
|
|
|
35
48
|
|
|
36
49
|
def validate_params!(params)
|
|
37
50
|
raise Core::ValidationError, "model is required" unless param(params, :model) == Types::IMAGE_TO_VIDEO_MODEL
|
|
51
|
+
raise Core::ValidationError, "first_frame_image_url is required" unless param(params, :first_frame_image_url)
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
raise Core::ValidationError, "image_urls supports at most #{IMAGE_URLS_MAX} entry" if image_urls.size > IMAGE_URLS_MAX
|
|
42
|
-
|
|
43
|
-
validate_optional!(params, :resolution, Types::RESOLUTIONS)
|
|
44
|
-
validate_integer_range!(params, :duration, Types::DURATION_RANGE)
|
|
53
|
+
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
54
|
+
validate_integer_range!(params, :duration_seconds, Types::DURATION_RANGE)
|
|
45
55
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
46
56
|
end
|
|
47
57
|
|
|
@@ -49,8 +59,7 @@ module RunApi
|
|
|
49
59
|
value = param(params, key)
|
|
50
60
|
return unless value
|
|
51
61
|
|
|
52
|
-
|
|
53
|
-
return if integer && range.cover?(integer)
|
|
62
|
+
return if value.is_a?(Integer) && range.cover?(value)
|
|
54
63
|
|
|
55
64
|
raise Core::ValidationError, "#{key} must be an integer between #{range.min} and #{range.max}"
|
|
56
65
|
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
|
|
|
@@ -10,22 +12,35 @@ module RunApi
|
|
|
10
12
|
|
|
11
13
|
RESPONSE_CLASS = Types::TextToVideoResponse
|
|
12
14
|
COMPLETED_RESPONSE_CLASS = Types::CompletedTextToVideoResponse
|
|
15
|
+
REFERENCE_IMAGE_URLS_RANGE = (1..9)
|
|
13
16
|
|
|
14
17
|
def initialize(http)
|
|
15
18
|
@http = http
|
|
16
19
|
end
|
|
17
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
|
|
18
25
|
def run(**params)
|
|
19
26
|
task = create(**params)
|
|
20
27
|
poll_until_complete { get(task.id) }
|
|
21
28
|
end
|
|
22
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
|
|
23
34
|
def create(**params)
|
|
24
35
|
params = compact_params(params)
|
|
25
36
|
validate_params!(params)
|
|
26
37
|
request(:post, ENDPOINT, body: params)
|
|
27
38
|
end
|
|
28
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
|
|
29
44
|
def get(id)
|
|
30
45
|
request(:get, "#{ENDPOINT}/#{id}")
|
|
31
46
|
end
|
|
@@ -33,12 +48,22 @@ module RunApi
|
|
|
33
48
|
private
|
|
34
49
|
|
|
35
50
|
def validate_params!(params)
|
|
36
|
-
|
|
51
|
+
model = param(params, :model)
|
|
52
|
+
raise Core::ValidationError, "model is required" unless Types::TEXT_TO_VIDEO_MODELS.include?(model)
|
|
37
53
|
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
38
54
|
|
|
39
|
-
|
|
55
|
+
reference_image_urls = param(params, :reference_image_urls)
|
|
56
|
+
if model == Types::CHARACTER_MODEL
|
|
57
|
+
unless reference_image_urls.is_a?(Array) && REFERENCE_IMAGE_URLS_RANGE.cover?(reference_image_urls.size)
|
|
58
|
+
raise Core::ValidationError, "reference_image_urls must include between #{REFERENCE_IMAGE_URLS_RANGE.min} and #{REFERENCE_IMAGE_URLS_RANGE.max} entries"
|
|
59
|
+
end
|
|
60
|
+
elsif reference_image_urls
|
|
61
|
+
raise Core::ValidationError, "reference_image_urls is only supported for #{Types::CHARACTER_MODEL}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
40
65
|
validate_optional!(params, :aspect_ratio, Types::ASPECT_RATIOS)
|
|
41
|
-
validate_integer_range!(params, :
|
|
66
|
+
validate_integer_range!(params, :duration_seconds, Types::DURATION_RANGE)
|
|
42
67
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
43
68
|
end
|
|
44
69
|
|
|
@@ -46,8 +71,7 @@ module RunApi
|
|
|
46
71
|
value = param(params, key)
|
|
47
72
|
return unless value
|
|
48
73
|
|
|
49
|
-
|
|
50
|
-
return if integer && range.cover?(integer)
|
|
74
|
+
return if value.is_a?(Integer) && range.cover?(value)
|
|
51
75
|
|
|
52
76
|
raise Core::ValidationError, "#{key} must be an integer between #{range.min} and #{range.max}"
|
|
53
77
|
end
|
|
@@ -2,17 +2,28 @@
|
|
|
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
|
|
7
|
+
# Standard text-to-video model.
|
|
6
8
|
TEXT_TO_VIDEO_MODEL = "happyhorse-text-to-video"
|
|
9
|
+
# Character-consistent model; requires 1-9 reference_image_urls.
|
|
10
|
+
CHARACTER_MODEL = "happyhorse-character"
|
|
11
|
+
# All text-to-video model variants.
|
|
12
|
+
TEXT_TO_VIDEO_MODELS = [TEXT_TO_VIDEO_MODEL, CHARACTER_MODEL].freeze
|
|
7
13
|
IMAGE_TO_VIDEO_MODEL = "happyhorse-image-to-video"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
EDIT_VIDEO_MODEL = "happyhorse-edit-video"
|
|
15
|
+
# Output resolution options. Defaults to 1080p.
|
|
16
|
+
OUTPUT_RESOLUTIONS = %w[720p 1080p].freeze
|
|
17
|
+
# Aspect ratio options. Defaults to 16:9.
|
|
11
18
|
ASPECT_RATIOS = %w[16:9 9:16 1:1 4:3 3:4].freeze
|
|
12
|
-
|
|
19
|
+
# Audio handling for video editing: "auto" lets the model decide, "original" preserves source audio.
|
|
20
|
+
AUDIO_SETTINGS = %w[auto original].freeze
|
|
21
|
+
# Duration range in seconds (3-15). Defaults to 5.
|
|
13
22
|
DURATION_RANGE = (3..15)
|
|
23
|
+
# Reproducibility seed range.
|
|
14
24
|
SEED_RANGE = (0..2_147_483_647)
|
|
15
25
|
|
|
26
|
+
# A generated video file with a download URL.
|
|
16
27
|
class MediaUrl < RunApi::Core::BaseModel
|
|
17
28
|
optional :url, String
|
|
18
29
|
end
|
|
@@ -24,14 +35,14 @@ module RunApi
|
|
|
24
35
|
optional :error, String
|
|
25
36
|
end
|
|
26
37
|
|
|
38
|
+
# Narrowed response returned by +run()+ once polling observes +status: "completed"+.
|
|
39
|
+
# +videos+ is required so consumers never have to null-check it on a successful task.
|
|
27
40
|
class CompletedTextToVideoResponse < TextToVideoResponse
|
|
28
41
|
required :videos, [-> { MediaUrl }]
|
|
29
42
|
end
|
|
30
43
|
|
|
31
44
|
ImageToVideoResponse = TextToVideoResponse
|
|
32
45
|
CompletedImageToVideoResponse = CompletedTextToVideoResponse
|
|
33
|
-
ReferenceToVideoResponse = TextToVideoResponse
|
|
34
|
-
CompletedReferenceToVideoResponse = CompletedTextToVideoResponse
|
|
35
46
|
EditVideoResponse = TextToVideoResponse
|
|
36
47
|
CompletedEditVideoResponse = CompletedTextToVideoResponse
|
|
37
48
|
end
|
data/lib/runapi/happyhorse.rb
CHANGED
|
@@ -4,7 +4,6 @@ require "runapi/core"
|
|
|
4
4
|
require_relative "happyhorse/types"
|
|
5
5
|
require_relative "happyhorse/resources/edit_video"
|
|
6
6
|
require_relative "happyhorse/resources/image_to_video"
|
|
7
|
-
require_relative "happyhorse/resources/reference_to_video"
|
|
8
7
|
require_relative "happyhorse/resources/text_to_video"
|
|
9
8
|
require_relative "happyhorse/client"
|
|
10
9
|
|
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.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- RunAPI
|
|
@@ -15,18 +15,17 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.2.
|
|
18
|
+
version: 0.2.6
|
|
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.
|
|
25
|
+
version: 0.2.6
|
|
26
26
|
description: The happyhorse ai api Ruby SDK is the language-specific package for HappyHorse
|
|
27
|
-
on RunAPI. Use this package for text, image,
|
|
28
|
-
|
|
29
|
-
errors in Ruby.
|
|
27
|
+
on RunAPI. Use this package for text, image, and edit-video workflows that need
|
|
28
|
+
JSON request bodies, task status lookup, and consistent RunAPI errors in Ruby.
|
|
30
29
|
email:
|
|
31
30
|
- contact@runapi.ai
|
|
32
31
|
executables: []
|
|
@@ -41,7 +40,6 @@ files:
|
|
|
41
40
|
- lib/runapi/happyhorse/client.rb
|
|
42
41
|
- lib/runapi/happyhorse/resources/edit_video.rb
|
|
43
42
|
- lib/runapi/happyhorse/resources/image_to_video.rb
|
|
44
|
-
- lib/runapi/happyhorse/resources/reference_to_video.rb
|
|
45
43
|
- lib/runapi/happyhorse/resources/text_to_video.rb
|
|
46
44
|
- lib/runapi/happyhorse/types.rb
|
|
47
45
|
homepage: https://runapi.ai/models/happyhorse
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RunApi
|
|
4
|
-
module HappyHorse
|
|
5
|
-
module Resources
|
|
6
|
-
class ReferenceToVideo
|
|
7
|
-
include RunApi::Core::ResourceHelpers
|
|
8
|
-
|
|
9
|
-
ENDPOINT = "/api/v1/happyhorse/reference_to_video"
|
|
10
|
-
|
|
11
|
-
RESPONSE_CLASS = Types::ReferenceToVideoResponse
|
|
12
|
-
COMPLETED_RESPONSE_CLASS = Types::CompletedReferenceToVideoResponse
|
|
13
|
-
REFERENCE_IMAGE_RANGE = (1..9)
|
|
14
|
-
|
|
15
|
-
def initialize(http)
|
|
16
|
-
@http = http
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def run(**params)
|
|
20
|
-
task = create(**params)
|
|
21
|
-
poll_until_complete { get(task.id) }
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def create(**params)
|
|
25
|
-
params = compact_params(params)
|
|
26
|
-
validate_params!(params)
|
|
27
|
-
request(:post, ENDPOINT, body: params)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def get(id)
|
|
31
|
-
request(:get, "#{ENDPOINT}/#{id}")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def validate_params!(params)
|
|
37
|
-
raise Core::ValidationError, "model is required" unless param(params, :model) == Types::REFERENCE_TO_VIDEO_MODEL
|
|
38
|
-
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
39
|
-
|
|
40
|
-
reference_image = param(params, :reference_image)
|
|
41
|
-
unless reference_image.is_a?(Array) && REFERENCE_IMAGE_RANGE.cover?(reference_image.size)
|
|
42
|
-
raise Core::ValidationError, "reference_image must include between #{REFERENCE_IMAGE_RANGE.min} and #{REFERENCE_IMAGE_RANGE.max} entries"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
validate_optional!(params, :resolution, Types::RESOLUTIONS)
|
|
46
|
-
validate_optional!(params, :aspect_ratio, Types::ASPECT_RATIOS)
|
|
47
|
-
validate_integer_range!(params, :duration, Types::DURATION_RANGE)
|
|
48
|
-
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def validate_integer_range!(params, key, range)
|
|
52
|
-
value = param(params, key)
|
|
53
|
-
return unless value
|
|
54
|
-
|
|
55
|
-
integer = Integer(value, exception: false)
|
|
56
|
-
return if integer && range.cover?(integer)
|
|
57
|
-
|
|
58
|
-
raise Core::ValidationError, "#{key} must be an integer between #{range.min} and #{range.max}"
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|