elevenlabs_client 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 244f4e543adab6725041a23c4742e95b32e6352635496ecf7ea3dbb7ae518d8b
4
+ data.tar.gz: 0f4444f50015137e1627a82edc7b9a6159a5dc4bdb41de521c8d2609130d642c
5
+ SHA512:
6
+ metadata.gz: 4fda1901bc041645ef289c56bc1474ae9f5e3c9ec965dc70371271344b5412c799c8e9fb519d28d780b1c26de32b7318abc63b2d0d0681337fd004ec53e48179
7
+ data.tar.gz: 92dc43058342c80fd0c72d66d8936fac2d66f1a38c31d606481a40c244bc8c8cd1cfc452f959e1dc014b514c2a56135a40e103166c53d1cbd3c1d15e0f3849fd
data/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - Initial release of ElevenLabs Client gem
12
+ - Support for ElevenLabs Dubbing API
13
+ - Create dubbing jobs with video/audio files
14
+ - Monitor dubbing job status
15
+ - List dubbing jobs with filters
16
+ - Retrieve dubbing resources for editing
17
+ - Comprehensive error handling with specific exception types
18
+ - Support for multiple target languages
19
+ - Configurable API endpoint and authentication
20
+ - Full test coverage with RSpec
21
+ - WebMock integration for testing
22
+
23
+ ### Features
24
+ - **Dubbing API**: Complete support for ElevenLabs dubbing workflow
25
+ - **Error Handling**: Specific exceptions for different error conditions
26
+ - **File Support**: Multiple video and audio formats (MP4, MOV, MP3, WAV, etc.)
27
+ - **Language Support**: Multiple target languages for dubbing
28
+ - **Configuration**: Flexible API key and endpoint configuration
29
+ - **Testing**: Comprehensive test suite with integration tests
30
+
31
+ ## [0.1.0] - 2025-01-XX
32
+
33
+ ### Added
34
+ - Initial implementation of ElevenLabs Client
35
+ - Basic dubbing functionality
36
+ - Error handling and validation
37
+ - Documentation and examples
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 ElevenLabs Client
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # ElevenlabsClient
2
+
3
+ A Ruby client library for interacting with ElevenLabs APIs, including dubbing and voice synthesis.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'elevenlabs_client', path: 'lib/elevenlabs_client'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ ## Usage
18
+
19
+ ### Configuration
20
+
21
+ #### Rails Initializer (Recommended for Rails apps)
22
+
23
+ Create `config/initializers/elevenlabs_client.rb`:
24
+
25
+ ```ruby
26
+ ElevenlabsClient::Settings.configure do |config|
27
+ config.properties = {
28
+ elevenlabs_base_uri: ENV["ELEVENLABS_BASE_URL"],
29
+ elevenlabs_api_key: ENV["ELEVENLABS_API_KEY"],
30
+ }
31
+ end
32
+ ```
33
+
34
+ Once configured this way, you can create clients without passing any parameters:
35
+
36
+ ```ruby
37
+ client = ElevenlabsClient.new
38
+ # Uses the configured settings automatically
39
+ ```
40
+
41
+ #### Alternative Configuration Syntax
42
+
43
+ You can also use the module-level configure method:
44
+
45
+ ```ruby
46
+ ElevenlabsClient.configure do |config|
47
+ config.properties = {
48
+ elevenlabs_base_uri: "https://api.elevenlabs.io",
49
+ elevenlabs_api_key: "your_api_key_here"
50
+ }
51
+ end
52
+ ```
53
+
54
+ #### Configuration Precedence
55
+
56
+ The client uses the following precedence order for configuration:
57
+
58
+ 1. **Explicit parameters** passed to `Client.new` (highest priority)
59
+ 2. **Settings.properties** configured via initializer
60
+ 3. **Environment variables** (lowest priority)
61
+
62
+ This allows you to set defaults in your initializer while still being able to override them when needed.
63
+
64
+ ### Client Initialization
65
+
66
+ There are several ways to create a client:
67
+
68
+ ```ruby
69
+ # Using environment variables (default behavior)
70
+ client = ElevenlabsClient.new
71
+
72
+ # Passing API key directly
73
+ client = ElevenlabsClient::Client.new(api_key: "your_api_key_here")
74
+
75
+ # Custom base URL
76
+ client = ElevenlabsClient::Client.new(
77
+ api_key: "your_api_key_here",
78
+ base_url: "https://custom-api.elevenlabs.io"
79
+ )
80
+
81
+ # Custom environment variable names
82
+ client = ElevenlabsClient::Client.new(
83
+ api_key_env: "MY_CUSTOM_API_KEY_VAR",
84
+ base_url_env: "MY_CUSTOM_BASE_URL_VAR"
85
+ )
86
+ ```
87
+
88
+ ### Basic Usage
89
+
90
+ ```ruby
91
+ require 'elevenlabs_client'
92
+
93
+ # Create a client
94
+ client = ElevenlabsClient.new
95
+
96
+ # Create a dubbing job
97
+ File.open("video.mp4", "rb") do |file|
98
+ result = client.dubs.create(
99
+ file_io: file,
100
+ filename: "video.mp4",
101
+ target_languages: ["es", "pt", "fr"],
102
+ name: "My Video Dub",
103
+ drop_background_audio: true,
104
+ use_profanity_filter: false
105
+ )
106
+
107
+ puts "Dubbing job created: #{result['dubbing_id']}"
108
+ end
109
+
110
+ # Check dubbing status
111
+ dub_details = client.dubs.get("dubbing_id_here")
112
+ puts "Status: #{dub_details['status']}"
113
+
114
+ # List all dubbing jobs
115
+ dubs = client.dubs.list(dubbing_status: "dubbed")
116
+ puts "Completed dubs: #{dubs['dubs'].length}"
117
+
118
+ # Get dubbing resources (for editing)
119
+ resources = client.dubs.resources("dubbing_id_here")
120
+ puts "Audio files: #{resources['resources']['audio_files']}"
121
+ ```
122
+
123
+ ### Available Dubbing Methods
124
+
125
+ The client provides access to all dubbing endpoints through the `client.dubs` interface:
126
+
127
+ - `client.dubs.create(file_io:, filename:, target_languages:, **options)` - Create a new dubbing job
128
+ - `client.dubs.get(dubbing_id)` - Get dubbing job details
129
+ - `client.dubs.list(params = {})` - List dubbing jobs with optional filters
130
+ - `client.dubs.resources(dubbing_id)` - Get dubbing resources for editing
131
+
132
+ ## Supported Language Codes
133
+
134
+ Common target languages include:
135
+ - `es` - Spanish
136
+ - `pt` - Portuguese
137
+ - `fr` - French
138
+ - `de` - German
139
+ - `it` - Italian
140
+ - `pl` - Polish
141
+ - `ja` - Japanese
142
+ - `ko` - Korean
143
+ - `zh` - Chinese
144
+ - `hi` - Hindi
145
+
146
+ ## Error Handling
147
+
148
+ The client raises specific exceptions for different error conditions:
149
+
150
+ ```ruby
151
+ begin
152
+ client.create_dub(...)
153
+ rescue ElevenlabsClient::AuthenticationError => e
154
+ puts "Invalid API key: #{e.message}"
155
+ rescue ElevenlabsClient::RateLimitError => e
156
+ puts "Rate limit exceeded: #{e.message}"
157
+ rescue ElevenlabsClient::ValidationError => e
158
+ puts "Validation error: #{e.message}"
159
+ rescue ElevenlabsClient::APIError => e
160
+ puts "API error: #{e.message}"
161
+ end
162
+ ```
163
+
164
+ ## Development
165
+
166
+ After checking out the repo, run `bundle install` to install dependencies.
167
+
168
+ ## Contributing
169
+
170
+ Bug reports and pull requests are welcome on GitHub.
171
+
172
+ ## License
173
+
174
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "faraday/multipart"
5
+
6
+ module ElevenlabsClient
7
+ class Client
8
+ DEFAULT_BASE_URL = "https://api.elevenlabs.io"
9
+
10
+ attr_reader :base_url, :api_key, :dubs
11
+
12
+ def initialize(api_key: nil, base_url: nil, api_key_env: "ELEVENLABS_API_KEY", base_url_env: "ELEVENLABS_BASE_URL")
13
+ @api_key = api_key || fetch_api_key(api_key_env)
14
+ @base_url = base_url || fetch_base_url(base_url_env)
15
+ @conn = build_connection
16
+ @dubs = Dubs.new(self)
17
+ end
18
+
19
+ # Makes an authenticated GET request
20
+ # @param path [String] API endpoint path
21
+ # @param params [Hash] Query parameters
22
+ # @return [Hash] Response body
23
+ def get(path, params = {})
24
+ response = @conn.get(path, params) do |req|
25
+ req.headers["xi-api-key"] = api_key
26
+ end
27
+
28
+ handle_response(response)
29
+ end
30
+
31
+ # Makes an authenticated POST request
32
+ # @param path [String] API endpoint path
33
+ # @param body [Hash, nil] Request body
34
+ # @return [Hash] Response body
35
+ def post(path, body = nil)
36
+ response = @conn.post(path) do |req|
37
+ req.headers["xi-api-key"] = api_key
38
+ req.body = body if body
39
+ end
40
+
41
+ handle_response(response)
42
+ end
43
+
44
+ # Makes an authenticated multipart POST request
45
+ # @param path [String] API endpoint path
46
+ # @param payload [Hash] Multipart payload
47
+ # @return [Hash] Response body
48
+ def post_multipart(path, payload)
49
+ response = @conn.post(path) do |req|
50
+ req.headers["xi-api-key"] = api_key
51
+ req.body = payload
52
+ end
53
+
54
+ handle_response(response)
55
+ end
56
+
57
+ # Helper method to create Faraday::Multipart::FilePart
58
+ # @param file_io [IO] File IO object
59
+ # @param filename [String] Original filename
60
+ # @return [Faraday::Multipart::FilePart]
61
+ def file_part(file_io, filename)
62
+ Faraday::Multipart::FilePart.new(file_io, mime_for(filename), filename)
63
+ end
64
+
65
+ private
66
+
67
+ def fetch_api_key(env_key = "ELEVENLABS_API_KEY")
68
+ # First try Settings, then ENV, then raise error
69
+ if Settings.properties&.dig(:elevenlabs_api_key)
70
+ Settings.elevenlabs_api_key
71
+ else
72
+ ENV.fetch(env_key) do
73
+ raise AuthenticationError, "#{env_key} environment variable is required but not set and Settings.properties[:elevenlabs_api_key] is not configured"
74
+ end
75
+ end
76
+ end
77
+
78
+ def fetch_base_url(env_key = "ELEVENLABS_BASE_URL")
79
+ # First try Settings, then ENV, then default
80
+ if Settings.properties&.dig(:elevenlabs_base_uri)
81
+ Settings.elevenlabs_base_uri
82
+ else
83
+ ENV.fetch(env_key, DEFAULT_BASE_URL)
84
+ end
85
+ end
86
+
87
+ def build_connection
88
+ Faraday.new(url: base_url) do |f|
89
+ f.request :multipart
90
+ f.request :url_encoded
91
+ f.response :json, content_type: /\bjson$/
92
+ f.adapter Faraday.default_adapter
93
+ end
94
+ end
95
+
96
+ def handle_response(response)
97
+ case response.status
98
+ when 200..299
99
+ response.body
100
+ when 401
101
+ raise AuthenticationError, "Invalid API key or authentication failed"
102
+ when 429
103
+ raise RateLimitError, "Rate limit exceeded"
104
+ when 400..499
105
+ raise ValidationError, response.body.inspect
106
+ else
107
+ raise APIError, "API request failed with status #{response.status}: #{response.body.inspect}"
108
+ end
109
+ end
110
+
111
+ def mime_for(filename)
112
+ ext = File.extname(filename).downcase
113
+ case ext
114
+ when ".mp4" then "video/mp4"
115
+ when ".mov" then "video/quicktime"
116
+ when ".avi" then "video/x-msvideo"
117
+ when ".mkv" then "video/x-matroska"
118
+ when ".mp3" then "audio/mpeg"
119
+ when ".wav" then "audio/wav"
120
+ when ".flac" then "audio/flac"
121
+ when ".m4a" then "audio/mp4"
122
+ else "application/octet-stream"
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElevenlabsClient
4
+ class Dubs
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ # POST /v1/dubbing (multipart)
10
+ # Creates a new dubbing job
11
+ #
12
+ # @param file_io [IO] The audio/video file to dub
13
+ # @param filename [String] Original filename
14
+ # @param target_languages [Array<String>] Target language codes (e.g., ["es", "pt", "fr"])
15
+ # @param name [String, nil] Optional name for the dubbing job
16
+ # @param options [Hash] Additional options (drop_background_audio, use_profanity_filter, etc.)
17
+ # @return [Hash] Response containing dubbing job details
18
+ def create(file_io:, filename:, target_languages:, name: nil, **options)
19
+ payload = {
20
+ file: @client.file_part(file_io, filename),
21
+ mode: "automatic",
22
+ target_languages: target_languages,
23
+ name: name
24
+ }.compact.merge(options)
25
+
26
+ @client.post_multipart("/v1/dubbing", payload)
27
+ end
28
+
29
+ # GET /v1/dubbing/{id}
30
+ # Retrieves dubbing job details
31
+ #
32
+ # @param dubbing_id [String] The dubbing job ID
33
+ # @return [Hash] Dubbing job details
34
+ def get(dubbing_id)
35
+ @client.get("/v1/dubbing/#{dubbing_id}")
36
+ end
37
+
38
+ # GET /v1/dubbing
39
+ # Lists dubbing jobs
40
+ #
41
+ # @param params [Hash] Query parameters (dubbing_status, page_size, etc.)
42
+ # @return [Hash] List of dubbing jobs
43
+ def list(params = {})
44
+ @client.get("/v1/dubbing", params)
45
+ end
46
+
47
+ # GET /v1/dubbing/{id}/resources
48
+ # Retrieves dubbing resources for editing (if dubbing_studio: true was used)
49
+ #
50
+ # @param dubbing_id [String] The dubbing job ID
51
+ # @return [Hash] Dubbing resources
52
+ def resources(dubbing_id)
53
+ @client.get("/v1/dubbing/#{dubbing_id}/resources")
54
+ end
55
+
56
+ private
57
+
58
+ attr_reader :client
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElevenlabsClient
4
+ class Error < StandardError; end
5
+ class APIError < Error; end
6
+ class AuthenticationError < Error; end
7
+ class RateLimitError < Error; end
8
+ class ValidationError < Error; end
9
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElevenlabsClient
4
+ class Settings
5
+ class << self
6
+ attr_accessor :properties
7
+
8
+ def configure
9
+ self.properties ||= {}
10
+ yield(self) if block_given?
11
+ end
12
+
13
+ def elevenlabs_base_uri
14
+ properties&.dig(:elevenlabs_base_uri) || ENV["ELEVENLABS_BASE_URL"] || "https://api.elevenlabs.io"
15
+ end
16
+
17
+ def elevenlabs_api_key
18
+ properties&.dig(:elevenlabs_api_key) || ENV["ELEVENLABS_API_KEY"]
19
+ end
20
+
21
+ # Reset configuration (useful for testing)
22
+ def reset!
23
+ self.properties = {}
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElevenlabsClient
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "elevenlabs_client/version"
4
+ require_relative "elevenlabs_client/errors"
5
+ require_relative "elevenlabs_client/settings"
6
+ require_relative "elevenlabs_client/dubs"
7
+ require_relative "elevenlabs_client/client"
8
+
9
+ module ElevenlabsClient
10
+ class Error < StandardError; end
11
+
12
+ # Convenience method to create a new client
13
+ def self.new(**options)
14
+ Client.new(**options)
15
+ end
16
+
17
+ # Convenience method to configure the client
18
+ def self.configure(&block)
19
+ Settings.configure(&block)
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elevenlabs_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Vitor Oliveira
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-09-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday-multipart
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-core
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ description: A Ruby client library for interacting with ElevenLabs dubbing and voice
112
+ synthesis APIs
113
+ email:
114
+ - vbrazo@gmail.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - CHANGELOG.md
120
+ - LICENSE.txt
121
+ - README.md
122
+ - lib/elevenlabs_client.rb
123
+ - lib/elevenlabs_client/client.rb
124
+ - lib/elevenlabs_client/dubs.rb
125
+ - lib/elevenlabs_client/errors.rb
126
+ - lib/elevenlabs_client/settings.rb
127
+ - lib/elevenlabs_client/version.rb
128
+ homepage: https://github.com/vbrazo/elevenlabs_client
129
+ licenses:
130
+ - MIT
131
+ metadata:
132
+ homepage_uri: https://github.com/vbrazo/elevenlabs_client
133
+ source_code_uri: https://github.com/vbrazo/elevenlabs_client
134
+ changelog_uri: https://github.com/vbrazo/elevenlabs_client/CHANGELOG.md
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: 3.0.0
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubygems_version: 3.5.16
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: Ruby client for ElevenLabs API
154
+ test_files: []