runapi-suno 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 +43 -0
- data/lib/runapi/suno/client.rb +7 -1
- data/lib/runapi/suno/resources/check_voice.rb +30 -0
- data/lib/runapi/suno/resources/generate_voice.rb +40 -0
- data/lib/runapi/suno/resources/regenerate_validation_phrase.rb +40 -0
- data/lib/runapi/suno/resources/voice_to_validation_phrase.rb +40 -0
- data/lib/runapi/suno/types.rb +68 -26
- data/lib/runapi/suno/validators.rb +88 -26
- data/lib/runapi/suno.rb +4 -0
- metadata +16 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f676e53a763fe863f61cd2fbd16f0702c93f2d189f7369d1471e819dd01bfa79
|
|
4
|
+
data.tar.gz: 76e18fcc6c46fe6b0f97be04949db28868d9f4ea3bfe7efcf5aa5296ca9a6ff7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83832d65fe97b8d8bfa5eae30c1f095fe8ea13368f06242588d89e67aa31013e2cd9ef3b5b7ba14e760430b13d76cc83a942dafd7878b654f58d6a3ff0736b5a
|
|
7
|
+
data.tar.gz: 5973d5187e4c761c056f1cde61a2e68f6fab5be8d42988e66194989eaddaafda9e77b6b481d89ee5eea5d84997f86def8a6c57ac8ceebd34bd570701dbcb1866
|
data/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Suno AI API Ruby SDK for RunAPI
|
|
2
|
+
|
|
3
|
+
The suno ai api Ruby SDK is the language-specific package for Suno on RunAPI. Use this suno ai api package for song generation, lyrics, vocal, extension, and audio transformation flows when your application needs JSON request bodies, task status lookup, and consistent RunAPI errors in Ruby.
|
|
4
|
+
|
|
5
|
+
This suno ai api README is the Ruby package guide inside the public `suno-sdk` repository. For the repository overview, start at `../README.md`; for model details, use https://runapi.ai/models/suno; for API reference, use https://runapi.ai/docs#suno; for SDK docs, use https://runapi.ai/docs#sdk-suno.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
gem install runapi-suno
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
require "runapi-suno"
|
|
17
|
+
|
|
18
|
+
client = RunApi::Suno::Client.new
|
|
19
|
+
task = client.generations.create(
|
|
20
|
+
# Pass the Suno JSON request body from https://runapi.ai/docs#suno.
|
|
21
|
+
)
|
|
22
|
+
status = client.generations.get(task.id)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Use `create` when you want to submit a task and return quickly, `get` when you need the latest task state, and `run` when a script should create and poll until completion. In web request handlers, prefer `create` plus webhook or later `get` polling so a worker is not held open.
|
|
26
|
+
|
|
27
|
+
## Language notes
|
|
28
|
+
|
|
29
|
+
Use Ruby keyword arguments and the `RunApi::Suno` error classes when building music jobs, Rails workers, or scripts. The available resources include generations, extensions, upload and extensions, covers, upload and covers, instrumentals, vocals, vocal removals, midi, wav conversions, music videos, lyrics, timestamped lyrics, section replacements, mashups, sounds, personas, and styles. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
|
|
30
|
+
|
|
31
|
+
## Links
|
|
32
|
+
|
|
33
|
+
- Model page: https://runapi.ai/models/suno
|
|
34
|
+
- SDK docs: https://runapi.ai/docs#sdk-suno
|
|
35
|
+
- Product docs: https://runapi.ai/docs#suno
|
|
36
|
+
- Pricing and rate limits: https://runapi.ai/models/suno/v3.5
|
|
37
|
+
- Provider comparison: https://runapi.ai/providers/suno
|
|
38
|
+
- Full catalog: https://runapi.ai/models
|
|
39
|
+
- Repository: https://github.com/runapi-ai/suno-sdk
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
Licensed under the Apache License, Version 2.0.
|
data/lib/runapi/suno/client.rb
CHANGED
|
@@ -6,7 +6,9 @@ module RunApi
|
|
|
6
6
|
attr_reader :text_to_music, :extend_music, :generate_artwork, :cover_audio,
|
|
7
7
|
:add_instrumental, :add_vocals, :separate_audio_stems, :generate_midi,
|
|
8
8
|
:convert_audio, :visualize_music, :generate_lyrics, :get_timestamped_lyrics,
|
|
9
|
-
:replace_section, :create_mashup, :text_to_sound, :
|
|
9
|
+
:replace_section, :create_mashup, :text_to_sound, :voice_to_validation_phrase,
|
|
10
|
+
:regenerate_validation_phrase, :generate_voice, :check_voice, :generate_persona,
|
|
11
|
+
:boost_style
|
|
10
12
|
|
|
11
13
|
def initialize(api_key: nil, **options)
|
|
12
14
|
@api_key = Core::Auth.resolve_api_key(api_key)
|
|
@@ -29,6 +31,10 @@ module RunApi
|
|
|
29
31
|
@replace_section = Resources::ReplaceSection.new(http)
|
|
30
32
|
@create_mashup = Resources::CreateMashup.new(http)
|
|
31
33
|
@text_to_sound = Resources::TextToSound.new(http)
|
|
34
|
+
@voice_to_validation_phrase = Resources::VoiceToValidationPhrase.new(http)
|
|
35
|
+
@regenerate_validation_phrase = Resources::RegenerateValidationPhrase.new(http)
|
|
36
|
+
@generate_voice = Resources::GenerateVoice.new(http)
|
|
37
|
+
@check_voice = Resources::CheckVoice.new(http)
|
|
32
38
|
@generate_persona = Resources::GeneratePersona.new(http)
|
|
33
39
|
@boost_style = Resources::BoostStyle.new(http)
|
|
34
40
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
class CheckVoice
|
|
7
|
+
include RunApi::Core::ResourceHelpers
|
|
8
|
+
|
|
9
|
+
ENDPOINT = "/api/v1/suno/check_voice"
|
|
10
|
+
RESPONSE_CLASS = Types::CheckVoiceResponse
|
|
11
|
+
|
|
12
|
+
def initialize(http)
|
|
13
|
+
@http = http
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def run(**params)
|
|
17
|
+
params = compact_params(params)
|
|
18
|
+
validate_params!(params)
|
|
19
|
+
request(:post, ENDPOINT, body: params)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def validate_params!(params)
|
|
25
|
+
Validators.validate_check_voice!(params, self)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
class GenerateVoice
|
|
7
|
+
include RunApi::Core::ResourceHelpers
|
|
8
|
+
|
|
9
|
+
ENDPOINT = "/api/v1/suno/generate_voice"
|
|
10
|
+
RESPONSE_CLASS = Types::VoiceGenerationResponse
|
|
11
|
+
COMPLETED_RESPONSE_CLASS = Types::CompletedVoiceGenerationResponse
|
|
12
|
+
|
|
13
|
+
def initialize(http)
|
|
14
|
+
@http = http
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run(**params)
|
|
18
|
+
task = create(**params)
|
|
19
|
+
poll_until_complete { get(task.id) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create(**params)
|
|
23
|
+
params = compact_params(params)
|
|
24
|
+
validate_params!(params)
|
|
25
|
+
request(:post, ENDPOINT, body: params)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get(id)
|
|
29
|
+
request(:get, "#{ENDPOINT}/#{id}")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def validate_params!(params)
|
|
35
|
+
Validators.validate_generate_voice!(params, self)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
class RegenerateValidationPhrase
|
|
7
|
+
include RunApi::Core::ResourceHelpers
|
|
8
|
+
|
|
9
|
+
ENDPOINT = "/api/v1/suno/regenerate_validation_phrase"
|
|
10
|
+
RESPONSE_CLASS = Types::ValidationPhraseResponse
|
|
11
|
+
COMPLETED_RESPONSE_CLASS = Types::CompletedValidationPhraseResponse
|
|
12
|
+
|
|
13
|
+
def initialize(http)
|
|
14
|
+
@http = http
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run(**params)
|
|
18
|
+
task = create(**params)
|
|
19
|
+
poll_until_complete { get(task.id) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create(**params)
|
|
23
|
+
params = compact_params(params)
|
|
24
|
+
validate_params!(params)
|
|
25
|
+
request(:post, ENDPOINT, body: params)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get(id)
|
|
29
|
+
request(:get, "#{ENDPOINT}/#{id}")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def validate_params!(params)
|
|
35
|
+
Validators.validate_regenerate_validation_phrase!(params, self)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RunApi
|
|
4
|
+
module Suno
|
|
5
|
+
module Resources
|
|
6
|
+
class VoiceToValidationPhrase
|
|
7
|
+
include RunApi::Core::ResourceHelpers
|
|
8
|
+
|
|
9
|
+
ENDPOINT = "/api/v1/suno/voice_to_validation_phrase"
|
|
10
|
+
RESPONSE_CLASS = Types::ValidationPhraseResponse
|
|
11
|
+
COMPLETED_RESPONSE_CLASS = Types::CompletedValidationPhraseResponse
|
|
12
|
+
|
|
13
|
+
def initialize(http)
|
|
14
|
+
@http = http
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run(**params)
|
|
18
|
+
task = create(**params)
|
|
19
|
+
poll_until_complete { get(task.id) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create(**params)
|
|
23
|
+
params = compact_params(params)
|
|
24
|
+
validate_params!(params)
|
|
25
|
+
request(:post, ENDPOINT, body: params)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get(id)
|
|
29
|
+
request(:get, "#{ENDPOINT}/#{id}")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def validate_params!(params)
|
|
35
|
+
Validators.validate_voice_to_validation_phrase!(params, self)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/runapi/suno/types.rb
CHANGED
|
@@ -3,17 +3,33 @@
|
|
|
3
3
|
module RunApi
|
|
4
4
|
module Suno
|
|
5
5
|
module Types
|
|
6
|
-
MODELS = %w[suno-v5.5 suno-v5 suno-v4.5-plus suno-v4.5-all suno-v4.5 suno-v4
|
|
6
|
+
MODELS = %w[suno-v5.5 suno-v5 suno-v4.5-plus suno-v4.5-all suno-v4.5 suno-v4].freeze
|
|
7
7
|
SOUND_MODELS = %w[suno-v5 suno-v5.5].freeze
|
|
8
8
|
SOUND_KEYS = %w[
|
|
9
9
|
Cm C#m Dm D#m Em Fm F#m Gm G#m Am A#m Bm
|
|
10
10
|
C C# D D# E F F# G G# A A# B
|
|
11
11
|
].freeze
|
|
12
|
-
VOCAL_GENDERS = %w[
|
|
13
|
-
|
|
12
|
+
VOCAL_GENDERS = %w[female male].freeze
|
|
13
|
+
PERSONA_TYPES = %w[style voice].freeze
|
|
14
|
+
PARAMETER_MODES = %w[source custom].freeze
|
|
15
|
+
VOCAL_MODES = %w[auto_lyrics exact_lyrics instrumental].freeze
|
|
14
16
|
SEPARATE_AUDIO_STEMS_TYPES = %w[separate_vocal split_stem].freeze
|
|
17
|
+
VALIDATION_PHRASE_LANGUAGES = %w[en zh es fr pt de ja ko hi ru].freeze
|
|
18
|
+
SINGER_SKILL_LEVELS = %w[beginner intermediate advanced professional].freeze
|
|
15
19
|
|
|
16
20
|
class Audio < RunApi::Core::BaseModel
|
|
21
|
+
optional :id, String
|
|
22
|
+
optional :audio_url, String
|
|
23
|
+
optional :stream_audio_url, String
|
|
24
|
+
optional :image_url, String
|
|
25
|
+
optional :lyrics, String
|
|
26
|
+
optional :model_name, String
|
|
27
|
+
optional :title, String
|
|
28
|
+
optional :tags, [String]
|
|
29
|
+
optional :duration, Numeric
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class SoundAudio < RunApi::Core::BaseModel
|
|
17
33
|
optional :id, String
|
|
18
34
|
optional :audio_url, String
|
|
19
35
|
optional :stream_audio_url, String
|
|
@@ -21,7 +37,7 @@ module RunApi
|
|
|
21
37
|
optional :prompt, String
|
|
22
38
|
optional :model_name, String
|
|
23
39
|
optional :title, String
|
|
24
|
-
optional :tags, [
|
|
40
|
+
optional :tags, [String]
|
|
25
41
|
optional :duration, Numeric
|
|
26
42
|
end
|
|
27
43
|
|
|
@@ -63,7 +79,7 @@ module RunApi
|
|
|
63
79
|
|
|
64
80
|
class MidiInstrument < RunApi::Core::BaseModel
|
|
65
81
|
required :name, String
|
|
66
|
-
optional :notes, [
|
|
82
|
+
optional :notes, [-> { MidiNote }]
|
|
67
83
|
end
|
|
68
84
|
|
|
69
85
|
class Lyric < RunApi::Core::BaseModel
|
|
@@ -85,33 +101,36 @@ module RunApi
|
|
|
85
101
|
end
|
|
86
102
|
|
|
87
103
|
class TextToMusicResponse < AsyncTaskResponse
|
|
88
|
-
optional :audios, [
|
|
104
|
+
optional :audios, [-> { Audio }]
|
|
89
105
|
optional :audio_url, String
|
|
90
106
|
end
|
|
91
107
|
|
|
92
108
|
class ExtendMusicResponse < AsyncTaskResponse
|
|
93
|
-
optional :audios, [
|
|
109
|
+
optional :audios, [-> { Audio }]
|
|
94
110
|
optional :original_task_id, String
|
|
95
111
|
end
|
|
96
112
|
|
|
97
113
|
class GenerateArtworkResponse < AsyncTaskResponse
|
|
98
|
-
optional :covers, [
|
|
114
|
+
optional :covers, [-> { Cover }]
|
|
99
115
|
end
|
|
100
116
|
|
|
101
117
|
class CoverAudioResponse < AsyncTaskResponse
|
|
102
|
-
optional :audios, [
|
|
118
|
+
optional :audios, [-> { Audio }]
|
|
103
119
|
end
|
|
104
120
|
|
|
105
121
|
class AddInstrumentalResponse < TextToMusicResponse; end
|
|
106
122
|
class AddVocalsResponse < TextToMusicResponse; end
|
|
107
|
-
|
|
123
|
+
|
|
124
|
+
class TextToSoundResponse < AsyncTaskResponse
|
|
125
|
+
optional :audios, [-> { SoundAudio }]
|
|
126
|
+
end
|
|
108
127
|
|
|
109
128
|
class SeparateAudioStemsResponse < AsyncTaskResponse
|
|
110
129
|
optional :separated_audios, -> { SeparatedAudio }
|
|
111
130
|
end
|
|
112
131
|
|
|
113
132
|
class GenerateMidiResponse < AsyncTaskResponse
|
|
114
|
-
optional :instruments, [
|
|
133
|
+
optional :instruments, [-> { MidiInstrument }]
|
|
115
134
|
end
|
|
116
135
|
|
|
117
136
|
class ConvertAudioResponse < AsyncTaskResponse
|
|
@@ -125,19 +144,19 @@ module RunApi
|
|
|
125
144
|
end
|
|
126
145
|
|
|
127
146
|
class GenerateLyricsResponse < AsyncTaskResponse
|
|
128
|
-
optional :lyrics, [
|
|
147
|
+
optional :lyrics, [-> { Lyric }]
|
|
129
148
|
end
|
|
130
149
|
|
|
131
150
|
class GetTimestampedLyricsResponse < RunApi::Core::BaseModel
|
|
132
|
-
optional :aligned_words, [
|
|
133
|
-
optional :waveform_data, [
|
|
151
|
+
optional :aligned_words, [-> { AlignedWord }]
|
|
152
|
+
optional :waveform_data, [Numeric]
|
|
134
153
|
optional :hoot_cer, Numeric
|
|
135
154
|
optional :is_streamed
|
|
136
155
|
end
|
|
137
156
|
|
|
138
157
|
class ReplaceSectionResponse < AsyncTaskResponse
|
|
139
158
|
optional :track, -> { Audio }
|
|
140
|
-
optional :audios, [
|
|
159
|
+
optional :audios, [-> { Audio }]
|
|
141
160
|
end
|
|
142
161
|
|
|
143
162
|
class GeneratePersonaResponse < RunApi::Core::BaseModel
|
|
@@ -152,31 +171,46 @@ module RunApi
|
|
|
152
171
|
|
|
153
172
|
class CreateMashupResponse < AsyncTaskResponse
|
|
154
173
|
optional :audio, -> { Audio }
|
|
155
|
-
optional :audios, [
|
|
174
|
+
optional :audios, [-> { Audio }]
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
class ValidationPhraseResponse < AsyncTaskResponse
|
|
178
|
+
optional :provider_status, String
|
|
179
|
+
optional :validation_phrase, String
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
class VoiceGenerationResponse < AsyncTaskResponse
|
|
183
|
+
optional :provider_status, String
|
|
184
|
+
optional :voice_id, String
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
class CheckVoiceResponse < RunApi::Core::BaseModel
|
|
188
|
+
optional :is_available
|
|
189
|
+
optional :error, String
|
|
156
190
|
end
|
|
157
191
|
|
|
158
192
|
class CompletedTextToMusicResponse < TextToMusicResponse
|
|
159
|
-
required :audios, [
|
|
193
|
+
required :audios, [-> { Audio }]
|
|
160
194
|
end
|
|
161
195
|
|
|
162
196
|
class CompletedExtendMusicResponse < ExtendMusicResponse
|
|
163
|
-
required :audios, [
|
|
197
|
+
required :audios, [-> { Audio }]
|
|
164
198
|
end
|
|
165
199
|
|
|
166
200
|
class CompletedGenerateArtworkResponse < GenerateArtworkResponse
|
|
167
|
-
required :covers, [
|
|
201
|
+
required :covers, [-> { Cover }]
|
|
168
202
|
end
|
|
169
203
|
|
|
170
204
|
class CompletedCoverAudioResponse < CoverAudioResponse
|
|
171
|
-
required :audios, [
|
|
205
|
+
required :audios, [-> { Audio }]
|
|
172
206
|
end
|
|
173
207
|
|
|
174
208
|
class CompletedAddInstrumentalResponse < AddInstrumentalResponse
|
|
175
|
-
required :audios, [
|
|
209
|
+
required :audios, [-> { Audio }]
|
|
176
210
|
end
|
|
177
211
|
|
|
178
212
|
class CompletedAddVocalsResponse < AddVocalsResponse
|
|
179
|
-
required :audios, [
|
|
213
|
+
required :audios, [-> { Audio }]
|
|
180
214
|
end
|
|
181
215
|
|
|
182
216
|
class CompletedSeparateAudioStemsResponse < SeparateAudioStemsResponse
|
|
@@ -184,7 +218,7 @@ module RunApi
|
|
|
184
218
|
end
|
|
185
219
|
|
|
186
220
|
class CompletedGenerateMidiResponse < GenerateMidiResponse
|
|
187
|
-
required :instruments, [
|
|
221
|
+
required :instruments, [-> { MidiInstrument }]
|
|
188
222
|
end
|
|
189
223
|
|
|
190
224
|
class CompletedConvertAudioResponse < ConvertAudioResponse
|
|
@@ -196,7 +230,7 @@ module RunApi
|
|
|
196
230
|
end
|
|
197
231
|
|
|
198
232
|
class CompletedGenerateLyricsResponse < GenerateLyricsResponse
|
|
199
|
-
required :lyrics, [
|
|
233
|
+
required :lyrics, [-> { Lyric }]
|
|
200
234
|
end
|
|
201
235
|
|
|
202
236
|
class CompletedReplaceSectionResponse < ReplaceSectionResponse
|
|
@@ -204,11 +238,19 @@ module RunApi
|
|
|
204
238
|
end
|
|
205
239
|
|
|
206
240
|
class CompletedCreateMashupResponse < CreateMashupResponse
|
|
207
|
-
required :audios, [
|
|
241
|
+
required :audios, [-> { Audio }]
|
|
208
242
|
end
|
|
209
243
|
|
|
210
244
|
class CompletedTextToSoundResponse < TextToSoundResponse
|
|
211
|
-
required :audios, [
|
|
245
|
+
required :audios, [-> { SoundAudio }]
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
class CompletedValidationPhraseResponse < ValidationPhraseResponse
|
|
249
|
+
required :validation_phrase, String
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
class CompletedVoiceGenerationResponse < VoiceGenerationResponse
|
|
253
|
+
required :voice_id, String
|
|
212
254
|
end
|
|
213
255
|
end
|
|
214
256
|
end
|
|
@@ -5,34 +5,34 @@ module RunApi
|
|
|
5
5
|
module Validators
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
|
+
MUSIC_PROMPT_SHAPE_ERROR = "choose a valid vocal_mode: auto_lyrics, exact_lyrics, or instrumental"
|
|
9
|
+
|
|
8
10
|
def validate_text_to_music!(params, resource)
|
|
9
|
-
|
|
10
|
-
require_param!(resource, params, :style)
|
|
11
|
-
require_param!(resource, params, :title)
|
|
12
|
-
else
|
|
13
|
-
require_param!(resource, params, :prompt)
|
|
14
|
-
end
|
|
11
|
+
validate_music_prompt_shape!(params, resource)
|
|
15
12
|
require_param!(resource, params, :model)
|
|
13
|
+
validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
|
|
16
14
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
17
15
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
18
|
-
validate_optional!(resource, params, :
|
|
16
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
def validate_extend_music!(params, resource)
|
|
22
20
|
unless %i[task_id audio_id audio_url upload_url].any? { |key| param(resource, params, key) }
|
|
23
21
|
raise Core::ValidationError, "task_id, audio_id, audio_url, or upload_url is required"
|
|
24
22
|
end
|
|
25
|
-
require_param!(resource, params, :
|
|
23
|
+
require_param!(resource, params, :parameter_mode)
|
|
26
24
|
require_param!(resource, params, :model)
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
validate_optional!(resource, params, :parameter_mode, Types::PARAMETER_MODES)
|
|
27
|
+
if param(resource, params, :parameter_mode) == "custom"
|
|
29
28
|
require_param!(resource, params, :style)
|
|
30
29
|
require_param!(resource, params, :title)
|
|
31
30
|
require_param!(resource, params, :continue_at)
|
|
32
31
|
end
|
|
32
|
+
validate_extend_music_prompt_shape!(params, resource)
|
|
33
33
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
34
34
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
35
|
-
validate_optional!(resource, params, :
|
|
35
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def validate_generate_artwork!(params, resource)
|
|
@@ -42,15 +42,11 @@ module RunApi
|
|
|
42
42
|
def validate_cover_audio!(params, resource)
|
|
43
43
|
require_param!(resource, params, :upload_url)
|
|
44
44
|
require_param!(resource, params, :model)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
require_param!(resource, params, :title)
|
|
48
|
-
else
|
|
49
|
-
require_param!(resource, params, :prompt)
|
|
50
|
-
end
|
|
45
|
+
validate_music_prompt_shape!(params, resource)
|
|
46
|
+
validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
|
|
51
47
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
52
48
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
53
|
-
validate_optional!(resource, params, :
|
|
49
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
54
50
|
end
|
|
55
51
|
|
|
56
52
|
def validate_add_instrumental!(params, resource)
|
|
@@ -60,7 +56,7 @@ module RunApi
|
|
|
60
56
|
end
|
|
61
57
|
|
|
62
58
|
def validate_add_vocals!(params, resource)
|
|
63
|
-
require_all!(resource, params, :upload_url, :
|
|
59
|
+
require_all!(resource, params, :upload_url, :lyrics, :title, :negative_tags, :style, :model)
|
|
64
60
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
65
61
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
66
62
|
end
|
|
@@ -91,7 +87,7 @@ module RunApi
|
|
|
91
87
|
end
|
|
92
88
|
|
|
93
89
|
def validate_replace_section!(params, resource)
|
|
94
|
-
require_all!(resource, params, :task_id, :audio_id, :
|
|
90
|
+
require_all!(resource, params, :task_id, :audio_id, :lyrics, :tags, :title, :infill_start_time, :infill_end_time)
|
|
95
91
|
if param(resource, params, :infill_end_time).to_f <= param(resource, params, :infill_start_time).to_f
|
|
96
92
|
raise Core::ValidationError, "infill_end_time must be greater than infill_start_time"
|
|
97
93
|
end
|
|
@@ -103,14 +99,11 @@ module RunApi
|
|
|
103
99
|
raise Core::ValidationError, "upload_url_list must contain exactly 2 URLs"
|
|
104
100
|
end
|
|
105
101
|
require_param!(resource, params, :model)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
require_param!(resource, params, :prompt) unless truthy?(param(resource, params, :instrumental))
|
|
109
|
-
else
|
|
110
|
-
require_param!(resource, params, :prompt)
|
|
111
|
-
end
|
|
102
|
+
validate_music_prompt_shape!(params, resource)
|
|
103
|
+
validate_optional!(resource, params, :vocal_mode, Types::VOCAL_MODES)
|
|
112
104
|
validate_optional!(resource, params, :model, Types::MODELS)
|
|
113
105
|
validate_optional!(resource, params, :vocal_gender, Types::VOCAL_GENDERS)
|
|
106
|
+
validate_optional!(resource, params, :persona_type, Types::PERSONA_TYPES)
|
|
114
107
|
end
|
|
115
108
|
|
|
116
109
|
def validate_text_to_sound!(params, resource)
|
|
@@ -123,6 +116,30 @@ module RunApi
|
|
|
123
116
|
end
|
|
124
117
|
end
|
|
125
118
|
|
|
119
|
+
def validate_voice_to_validation_phrase!(params, resource)
|
|
120
|
+
require_all!(resource, params, :voice_url, :vocal_start_seconds, :vocal_end_seconds)
|
|
121
|
+
validate_optional!(resource, params, :language, Types::VALIDATION_PHRASE_LANGUAGES)
|
|
122
|
+
|
|
123
|
+
start_seconds = param(resource, params, :vocal_start_seconds).to_i
|
|
124
|
+
end_seconds = param(resource, params, :vocal_end_seconds).to_i
|
|
125
|
+
return if end_seconds > start_seconds
|
|
126
|
+
|
|
127
|
+
raise Core::ValidationError, "vocal_end_seconds must be greater than vocal_start_seconds"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def validate_regenerate_validation_phrase!(params, resource)
|
|
131
|
+
require_param!(resource, params, :task_id)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def validate_generate_voice!(params, resource)
|
|
135
|
+
require_all!(resource, params, :task_id, :verify_url)
|
|
136
|
+
validate_optional!(resource, params, :singer_skill_level, Types::SINGER_SKILL_LEVELS)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def validate_check_voice!(params, resource)
|
|
140
|
+
require_param!(resource, params, :task_id)
|
|
141
|
+
end
|
|
142
|
+
|
|
126
143
|
def validate_generate_persona!(params, resource)
|
|
127
144
|
require_all!(resource, params, :task_id, :audio_id, :name, :description)
|
|
128
145
|
end
|
|
@@ -131,6 +148,45 @@ module RunApi
|
|
|
131
148
|
require_param!(resource, params, :description)
|
|
132
149
|
end
|
|
133
150
|
|
|
151
|
+
def validate_music_prompt_shape!(params, resource)
|
|
152
|
+
mode = param(resource, params, :vocal_mode).to_s
|
|
153
|
+
has_prompt = truthy_presence?(param(resource, params, :prompt))
|
|
154
|
+
has_lyrics = truthy_presence?(param(resource, params, :lyrics))
|
|
155
|
+
has_style = truthy_presence?(param(resource, params, :style))
|
|
156
|
+
has_title = truthy_presence?(param(resource, params, :title))
|
|
157
|
+
|
|
158
|
+
valid_shape = case mode
|
|
159
|
+
when "auto_lyrics"
|
|
160
|
+
has_prompt && !has_lyrics && !has_style && !has_title
|
|
161
|
+
when "exact_lyrics"
|
|
162
|
+
!has_prompt && has_lyrics && has_style && has_title
|
|
163
|
+
when "instrumental"
|
|
164
|
+
!has_prompt && !has_lyrics && has_style && has_title
|
|
165
|
+
else
|
|
166
|
+
false
|
|
167
|
+
end
|
|
168
|
+
return if valid_shape
|
|
169
|
+
|
|
170
|
+
raise Core::ValidationError, MUSIC_PROMPT_SHAPE_ERROR
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def validate_extend_music_prompt_shape!(params, resource)
|
|
174
|
+
return unless truthy_presence?(param(resource, params, :lyrics))
|
|
175
|
+
|
|
176
|
+
if truthy_presence?(param(resource, params, :prompt))
|
|
177
|
+
raise Core::ValidationError, "prompt cannot be combined with lyrics"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
if truthy?(param(resource, params, :instrumental))
|
|
181
|
+
raise Core::ValidationError, "lyrics cannot be used when instrumental is true"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
upload_mode = %i[audio_url upload_url].any? { |key| truthy_presence?(param(resource, params, key)) }
|
|
185
|
+
return if param(resource, params, :parameter_mode) == "custom" && upload_mode
|
|
186
|
+
|
|
187
|
+
raise Core::ValidationError, "lyrics can only be used when extending uploaded audio with custom parameters"
|
|
188
|
+
end
|
|
189
|
+
|
|
134
190
|
def require_all!(resource, params, *keys)
|
|
135
191
|
keys.each { |key| require_param!(resource, params, key) }
|
|
136
192
|
end
|
|
@@ -148,7 +204,13 @@ module RunApi
|
|
|
148
204
|
end
|
|
149
205
|
|
|
150
206
|
def truthy?(value)
|
|
151
|
-
[
|
|
207
|
+
[true, 1, "1", "true", "TRUE", "True"].include?(value)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def truthy_presence?(value)
|
|
211
|
+
return !value.empty? if value.respond_to?(:empty?)
|
|
212
|
+
|
|
213
|
+
!value.nil?
|
|
152
214
|
end
|
|
153
215
|
end
|
|
154
216
|
end
|
data/lib/runapi/suno.rb
CHANGED
|
@@ -18,6 +18,10 @@ require_relative "suno/resources/get_timestamped_lyrics"
|
|
|
18
18
|
require_relative "suno/resources/replace_section"
|
|
19
19
|
require_relative "suno/resources/create_mashup"
|
|
20
20
|
require_relative "suno/resources/text_to_sound"
|
|
21
|
+
require_relative "suno/resources/voice_to_validation_phrase"
|
|
22
|
+
require_relative "suno/resources/regenerate_validation_phrase"
|
|
23
|
+
require_relative "suno/resources/generate_voice"
|
|
24
|
+
require_relative "suno/resources/check_voice"
|
|
21
25
|
require_relative "suno/resources/generate_persona"
|
|
22
26
|
require_relative "suno/resources/boost_style"
|
|
23
27
|
require_relative "suno/client"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: runapi-suno
|
|
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,28 +15,34 @@ 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.
|
|
26
|
-
description:
|
|
25
|
+
version: 0.2.5
|
|
26
|
+
description: The suno ai api Ruby SDK is the language-specific package for Suno on
|
|
27
|
+
RunAPI. Use this suno ai api package for song generation, lyrics, vocal, extension,
|
|
28
|
+
and audio transformation flows when your application needs JSON request bodies,
|
|
29
|
+
task status lookup, and consistent RunAPI errors in Ruby.
|
|
27
30
|
email:
|
|
28
31
|
- contact@runapi.ai
|
|
29
32
|
executables: []
|
|
30
33
|
extensions: []
|
|
31
|
-
extra_rdoc_files:
|
|
34
|
+
extra_rdoc_files:
|
|
35
|
+
- README.md
|
|
32
36
|
files:
|
|
33
37
|
- LICENSE
|
|
38
|
+
- README.md
|
|
34
39
|
- lib/runapi-suno.rb
|
|
35
40
|
- lib/runapi/suno.rb
|
|
36
41
|
- lib/runapi/suno/client.rb
|
|
37
42
|
- lib/runapi/suno/resources/add_instrumental.rb
|
|
38
43
|
- lib/runapi/suno/resources/add_vocals.rb
|
|
39
44
|
- lib/runapi/suno/resources/boost_style.rb
|
|
45
|
+
- lib/runapi/suno/resources/check_voice.rb
|
|
40
46
|
- lib/runapi/suno/resources/convert_audio.rb
|
|
41
47
|
- lib/runapi/suno/resources/cover_audio.rb
|
|
42
48
|
- lib/runapi/suno/resources/create_mashup.rb
|
|
@@ -45,12 +51,15 @@ files:
|
|
|
45
51
|
- lib/runapi/suno/resources/generate_lyrics.rb
|
|
46
52
|
- lib/runapi/suno/resources/generate_midi.rb
|
|
47
53
|
- lib/runapi/suno/resources/generate_persona.rb
|
|
54
|
+
- lib/runapi/suno/resources/generate_voice.rb
|
|
48
55
|
- lib/runapi/suno/resources/get_timestamped_lyrics.rb
|
|
56
|
+
- lib/runapi/suno/resources/regenerate_validation_phrase.rb
|
|
49
57
|
- lib/runapi/suno/resources/replace_section.rb
|
|
50
58
|
- lib/runapi/suno/resources/separate_audio_stems.rb
|
|
51
59
|
- lib/runapi/suno/resources/text_to_music.rb
|
|
52
60
|
- lib/runapi/suno/resources/text_to_sound.rb
|
|
53
61
|
- lib/runapi/suno/resources/visualize_music.rb
|
|
62
|
+
- lib/runapi/suno/resources/voice_to_validation_phrase.rb
|
|
54
63
|
- lib/runapi/suno/types.rb
|
|
55
64
|
- lib/runapi/suno/validators.rb
|
|
56
65
|
homepage: https://runapi.ai/models/suno
|
|
@@ -58,7 +67,7 @@ licenses:
|
|
|
58
67
|
- Apache-2.0
|
|
59
68
|
metadata:
|
|
60
69
|
homepage_uri: https://runapi.ai/models/suno
|
|
61
|
-
documentation_uri: https://github.com/runapi-ai/suno-sdk/blob/main/README.md
|
|
70
|
+
documentation_uri: https://github.com/runapi-ai/suno-sdk/blob/main/ruby/README.md
|
|
62
71
|
source_code_uri: https://github.com/runapi-ai/suno-sdk
|
|
63
72
|
changelog_uri: https://github.com/runapi-ai/suno-sdk/blob/main/CHANGELOG.md
|
|
64
73
|
rdoc_options: []
|
|
@@ -77,5 +86,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
86
|
requirements: []
|
|
78
87
|
rubygems_version: 4.0.10
|
|
79
88
|
specification_version: 4
|
|
80
|
-
summary: Suno API
|
|
89
|
+
summary: Suno AI API Ruby SDK for RunAPI
|
|
81
90
|
test_files: []
|