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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c4f0f454f1eb15878f3c4edd3f7d958db1777e5ffb6260c0f29e0774fa587bd
4
- data.tar.gz: 0c0f9d96f07ed1d893a531df62c42f5c2896b1c61d56e751635b973d7608d6f0
3
+ metadata.gz: f6dce8cdd8d38b5c1062594b3de7c673544d2558abe8db1c616b35e81ae1c9bc
4
+ data.tar.gz: c2ab10637f4c26d08b77e6b44dc80eb51be19c99b6ba34d610656426771b6555
5
5
  SHA512:
6
- metadata.gz: 1464ac2c22e0349fdb59df6a910a8afd1ae31be12831847359182b09da136ed7e332f9a3df0d32bbe2a5ada0c711a2e78eb14f3ecb509e8f5e25640100de8490
7
- data.tar.gz: 0cc07a34f20984589248c3571a528e35085194557e5477fbed9b524ecc78dacf308511dc0a68750488ff5da5c926b454d42e7be743d51d8b061ce587fd3c6975
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 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.
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
- class Client
6
- attr_reader :text_to_video, :image_to_video, :edit_video
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
- @api_key = Core::Auth.resolve_api_key(api_key)
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
- raise Core::ValidationError, "model is required" unless param(params, :model) == Types::EDIT_VIDEO_MODEL
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
- 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)
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
- model = param(params, :model)
38
- raise Core::ValidationError, "model is required" unless Types::TEXT_TO_VIDEO_MODELS.include?(model)
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
- unless reference_image_urls.is_a?(Array) && REFERENCE_IMAGE_URLS_RANGE.cover?(reference_image_urls.size)
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
- TEXT_TO_VIDEO_MODEL = "happyhorse-text-to-video"
7
+ # Character-consistent model; requires 1-9 reference_image_urls.
7
8
  CHARACTER_MODEL = "happyhorse-character"
8
- TEXT_TO_VIDEO_MODELS = [TEXT_TO_VIDEO_MODEL, CHARACTER_MODEL].freeze
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
@@ -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.5
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.5
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.5
26
- description: The happyhorse ai api Ruby SDK is the language-specific package for HappyHorse
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.
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: