runapi-happyhorse 0.2.4 → 0.2.5
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 +9 -8
- data/lib/runapi/happyhorse/client.rb +1 -2
- data/lib/runapi/happyhorse/resources/edit_video.rb +6 -7
- data/lib/runapi/happyhorse/resources/image_to_video.rb +4 -9
- data/lib/runapi/happyhorse/resources/text_to_video.rb +15 -5
- data/lib/runapi/happyhorse/types.rb +5 -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: 2c4f0f454f1eb15878f3c4edd3f7d958db1777e5ffb6260c0f29e0774fa587bd
|
|
4
|
+
data.tar.gz: 0c0f9d96f07ed1d893a531df62c42f5c2896b1c61d56e751635b973d7608d6f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1464ac2c22e0349fdb59df6a910a8afd1ae31be12831847359182b09da136ed7e332f9a3df0d32bbe2a5ada0c711a2e78eb14f3ecb509e8f5e25640100de8490
|
|
7
|
+
data.tar.gz: 0cc07a34f20984589248c3571a528e35085194557e5477fbed9b524ecc78dacf308511dc0a68750488ff5da5c926b454d42e7be743d51d8b061ce587fd3c6975
|
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,16 @@ 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.
|
|
27
28
|
|
|
28
29
|
## Links
|
|
29
30
|
|
|
@@ -31,8 +32,8 @@ For image-to-video, call `client.image_to_video.run` with `model: "happyhorse-im
|
|
|
31
32
|
- SDK docs: https://runapi.ai/docs#sdk-happyhorse
|
|
32
33
|
- Product docs: https://runapi.ai/docs#happyhorse
|
|
33
34
|
- 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
|
|
35
|
+
- Character pricing and rate limits: https://runapi.ai/models/happyhorse/character
|
|
36
|
+
- Edit-video pricing and rate limits: https://runapi.ai/models/happyhorse/edit-video
|
|
36
37
|
- Pricing and rate limits: https://runapi.ai/models/happyhorse/text-to-video
|
|
37
38
|
- Provider comparison: https://runapi.ai/providers/alibaba
|
|
38
39
|
- Full catalog: https://runapi.ai/models
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module HappyHorse
|
|
5
5
|
class Client
|
|
6
|
-
attr_reader :text_to_video, :image_to_video, :
|
|
6
|
+
attr_reader :text_to_video, :image_to_video, :edit_video
|
|
7
7
|
|
|
8
8
|
def initialize(api_key: nil, **options)
|
|
9
9
|
@api_key = Core::Auth.resolve_api_key(api_key)
|
|
@@ -12,7 +12,6 @@ module RunApi
|
|
|
12
12
|
http = client_options.http_client || Core::HttpClient.new(client_options)
|
|
13
13
|
@text_to_video = Resources::TextToVideo.new(http)
|
|
14
14
|
@image_to_video = Resources::ImageToVideo.new(http)
|
|
15
|
-
@reference_to_video = Resources::ReferenceToVideo.new(http)
|
|
16
15
|
@edit_video = Resources::EditVideo.new(http)
|
|
17
16
|
end
|
|
18
17
|
end
|
|
@@ -36,14 +36,14 @@ module RunApi
|
|
|
36
36
|
def validate_params!(params)
|
|
37
37
|
raise Core::ValidationError, "model is required" unless param(params, :model) == Types::EDIT_VIDEO_MODEL
|
|
38
38
|
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
39
|
-
raise Core::ValidationError, "
|
|
39
|
+
raise Core::ValidationError, "source_video_url is required" unless param(params, :source_video_url)
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
if
|
|
43
|
-
raise Core::ValidationError, "
|
|
41
|
+
reference_image_urls = param(params, :reference_image_urls)
|
|
42
|
+
if reference_image_urls && (!reference_image_urls.is_a?(Array) || !REFERENCE_IMAGE_RANGE.cover?(reference_image_urls.size))
|
|
43
|
+
raise Core::ValidationError, "reference_image_urls must include at most #{REFERENCE_IMAGE_RANGE.max} entries"
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
validate_optional!(params, :
|
|
46
|
+
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
47
47
|
validate_optional!(params, :audio_setting, Types::AUDIO_SETTINGS)
|
|
48
48
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
49
49
|
end
|
|
@@ -52,8 +52,7 @@ module RunApi
|
|
|
52
52
|
value = param(params, key)
|
|
53
53
|
return unless value
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
return if integer && range.cover?(integer)
|
|
55
|
+
return if value.is_a?(Integer) && range.cover?(value)
|
|
57
56
|
|
|
58
57
|
raise Core::ValidationError, "#{key} must be an integer between #{range.min} and #{range.max}"
|
|
59
58
|
end
|
|
@@ -10,7 +10,6 @@ module RunApi
|
|
|
10
10
|
|
|
11
11
|
RESPONSE_CLASS = Types::ImageToVideoResponse
|
|
12
12
|
COMPLETED_RESPONSE_CLASS = Types::CompletedImageToVideoResponse
|
|
13
|
-
IMAGE_URLS_MAX = 1
|
|
14
13
|
|
|
15
14
|
def initialize(http)
|
|
16
15
|
@http = http
|
|
@@ -35,13 +34,10 @@ module RunApi
|
|
|
35
34
|
|
|
36
35
|
def validate_params!(params)
|
|
37
36
|
raise Core::ValidationError, "model is required" unless param(params, :model) == Types::IMAGE_TO_VIDEO_MODEL
|
|
37
|
+
raise Core::ValidationError, "first_frame_image_url is required" unless param(params, :first_frame_image_url)
|
|
38
38
|
|
|
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)
|
|
39
|
+
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
40
|
+
validate_integer_range!(params, :duration_seconds, Types::DURATION_RANGE)
|
|
45
41
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
46
42
|
end
|
|
47
43
|
|
|
@@ -49,8 +45,7 @@ module RunApi
|
|
|
49
45
|
value = param(params, key)
|
|
50
46
|
return unless value
|
|
51
47
|
|
|
52
|
-
|
|
53
|
-
return if integer && range.cover?(integer)
|
|
48
|
+
return if value.is_a?(Integer) && range.cover?(value)
|
|
54
49
|
|
|
55
50
|
raise Core::ValidationError, "#{key} must be an integer between #{range.min} and #{range.max}"
|
|
56
51
|
end
|
|
@@ -10,6 +10,7 @@ module RunApi
|
|
|
10
10
|
|
|
11
11
|
RESPONSE_CLASS = Types::TextToVideoResponse
|
|
12
12
|
COMPLETED_RESPONSE_CLASS = Types::CompletedTextToVideoResponse
|
|
13
|
+
REFERENCE_IMAGE_URLS_RANGE = (1..9)
|
|
13
14
|
|
|
14
15
|
def initialize(http)
|
|
15
16
|
@http = http
|
|
@@ -33,12 +34,22 @@ module RunApi
|
|
|
33
34
|
private
|
|
34
35
|
|
|
35
36
|
def validate_params!(params)
|
|
36
|
-
|
|
37
|
+
model = param(params, :model)
|
|
38
|
+
raise Core::ValidationError, "model is required" unless Types::TEXT_TO_VIDEO_MODELS.include?(model)
|
|
37
39
|
raise Core::ValidationError, "prompt is required" unless param(params, :prompt)
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
reference_image_urls = param(params, :reference_image_urls)
|
|
42
|
+
if model == Types::CHARACTER_MODEL
|
|
43
|
+
unless reference_image_urls.is_a?(Array) && REFERENCE_IMAGE_URLS_RANGE.cover?(reference_image_urls.size)
|
|
44
|
+
raise Core::ValidationError, "reference_image_urls must include between #{REFERENCE_IMAGE_URLS_RANGE.min} and #{REFERENCE_IMAGE_URLS_RANGE.max} entries"
|
|
45
|
+
end
|
|
46
|
+
elsif reference_image_urls
|
|
47
|
+
raise Core::ValidationError, "reference_image_urls is only supported for #{Types::CHARACTER_MODEL}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
validate_optional!(params, :output_resolution, Types::OUTPUT_RESOLUTIONS)
|
|
40
51
|
validate_optional!(params, :aspect_ratio, Types::ASPECT_RATIOS)
|
|
41
|
-
validate_integer_range!(params, :
|
|
52
|
+
validate_integer_range!(params, :duration_seconds, Types::DURATION_RANGE)
|
|
42
53
|
validate_integer_range!(params, :seed, Types::SEED_RANGE)
|
|
43
54
|
end
|
|
44
55
|
|
|
@@ -46,8 +57,7 @@ module RunApi
|
|
|
46
57
|
value = param(params, key)
|
|
47
58
|
return unless value
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
return if integer && range.cover?(integer)
|
|
60
|
+
return if value.is_a?(Integer) && range.cover?(value)
|
|
51
61
|
|
|
52
62
|
raise Core::ValidationError, "#{key} must be an integer between #{range.min} and #{range.max}"
|
|
53
63
|
end
|
|
@@ -4,12 +4,13 @@ module RunApi
|
|
|
4
4
|
module HappyHorse
|
|
5
5
|
module Types
|
|
6
6
|
TEXT_TO_VIDEO_MODEL = "happyhorse-text-to-video"
|
|
7
|
+
CHARACTER_MODEL = "happyhorse-character"
|
|
8
|
+
TEXT_TO_VIDEO_MODELS = [TEXT_TO_VIDEO_MODEL, CHARACTER_MODEL].freeze
|
|
7
9
|
IMAGE_TO_VIDEO_MODEL = "happyhorse-image-to-video"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
RESOLUTIONS = %w[720p 1080p].freeze
|
|
10
|
+
EDIT_VIDEO_MODEL = "happyhorse-edit-video"
|
|
11
|
+
OUTPUT_RESOLUTIONS = %w[720p 1080p].freeze
|
|
11
12
|
ASPECT_RATIOS = %w[16:9 9:16 1:1 4:3 3:4].freeze
|
|
12
|
-
AUDIO_SETTINGS = %w[auto
|
|
13
|
+
AUDIO_SETTINGS = %w[auto original].freeze
|
|
13
14
|
DURATION_RANGE = (3..15)
|
|
14
15
|
SEED_RANGE = (0..2_147_483_647)
|
|
15
16
|
|
|
@@ -30,8 +31,6 @@ module RunApi
|
|
|
30
31
|
|
|
31
32
|
ImageToVideoResponse = TextToVideoResponse
|
|
32
33
|
CompletedImageToVideoResponse = CompletedTextToVideoResponse
|
|
33
|
-
ReferenceToVideoResponse = TextToVideoResponse
|
|
34
|
-
CompletedReferenceToVideoResponse = CompletedTextToVideoResponse
|
|
35
34
|
EditVideoResponse = TextToVideoResponse
|
|
36
35
|
CompletedEditVideoResponse = CompletedTextToVideoResponse
|
|
37
36
|
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.5
|
|
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.5
|
|
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.5
|
|
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
|