suno-easy 0.1.0__tar.gz
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.
- suno_easy-0.1.0/LICENSE +21 -0
- suno_easy-0.1.0/PKG-INFO +216 -0
- suno_easy-0.1.0/README.md +195 -0
- suno_easy-0.1.0/pyproject.toml +33 -0
- suno_easy-0.1.0/setup.cfg +4 -0
- suno_easy-0.1.0/suno_easy/__init__.py +25 -0
- suno_easy-0.1.0/suno_easy/audio.py +380 -0
- suno_easy-0.1.0/suno_easy/client.py +147 -0
- suno_easy-0.1.0/suno_easy/exceptions.py +19 -0
- suno_easy-0.1.0/suno_easy/lyrics.py +56 -0
- suno_easy-0.1.0/suno_easy/models.py +209 -0
- suno_easy-0.1.0/suno_easy/music.py +182 -0
- suno_easy-0.1.0/suno_easy/persona.py +30 -0
- suno_easy-0.1.0/suno_easy/utils.py +5 -0
- suno_easy-0.1.0/suno_easy.egg-info/PKG-INFO +216 -0
- suno_easy-0.1.0/suno_easy.egg-info/SOURCES.txt +18 -0
- suno_easy-0.1.0/suno_easy.egg-info/dependency_links.txt +1 -0
- suno_easy-0.1.0/suno_easy.egg-info/requires.txt +1 -0
- suno_easy-0.1.0/suno_easy.egg-info/top_level.txt +1 -0
- suno_easy-0.1.0/tests/test_client.py +73 -0
suno_easy-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fred
|
|
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 all
|
|
13
|
+
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 THE
|
|
21
|
+
SOFTWARE.
|
suno_easy-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: suno-easy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight, modern, and fully-typed Python SDK for the Suno AI API (sunoapi.org)
|
|
5
|
+
Author-email: Fred <frederic.dymko@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Onnonoka/suno-easy
|
|
8
|
+
Project-URL: Documentation, https://github.com/Onnonoka/suno-easy#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/Onnonoka/suno-easy.git
|
|
10
|
+
Project-URL: Issues, https://github.com/Onnonoka/suno-easy/issues
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: requests>=2.25.0
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# suno-easy 🎵
|
|
23
|
+
|
|
24
|
+
> [!IMPORTANT]
|
|
25
|
+
> **Disclaimer**: This is an unofficial, community-driven Python SDK wrapper for the Suno API (`sunoapi.org`). It is not affiliated with, endorsed, sponsored, or supported by Suno, Inc. or the official Suno AI platform.
|
|
26
|
+
|
|
27
|
+
`suno-easy` is a lightweight, modern, and fully-typed Python SDK for the Suno AI API ([sunoapi.org](https://docs.sunoapi.org/)).
|
|
28
|
+
|
|
29
|
+
It provides an intuitive, object-oriented interface to generate music, write lyrics, create voice personas, separate audio stems, and generate MIDI notes from audio files.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- **Clean Namespace Organization**: Resources are grouped logically (`client.music`, `client.lyrics`, `client.audio`, `client.persona`).
|
|
36
|
+
- **Fully Typed**: Rich python dataclasses for responses (`Song`, `Lyrics`, `SeparatedStems`, `MIDIData`, `CoverImage`).
|
|
37
|
+
- **Smart Polling**: Methods can either block and return the processed result (`wait=True`) or instantly return a `taskId` for asynchronous workflows (`wait=False`).
|
|
38
|
+
- **Built-in Downloads**: Download audio tracks, cover images, and isolated stems with built-in streaming helpers.
|
|
39
|
+
- **Robust Error Handling**: Distinct exceptions for HTTP failures (`SunoAPIError`) and generation failures (`TaskFailed`).
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Repository Structure
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
suno-easy/
|
|
47
|
+
├── suno_easy/ # Core SDK library source code
|
|
48
|
+
│ ├── __init__.py # Exposed client, models, and exceptions
|
|
49
|
+
│ ├── client.py # Main SunoClient orchestrator
|
|
50
|
+
│ ├── models.py # Strongly typed dataclasses representing API payloads
|
|
51
|
+
│ ├── audio.py # Audio processing sub-resource (stems, MIDI, covers)
|
|
52
|
+
│ ├── music.py # Music generation and extension sub-resource
|
|
53
|
+
│ ├── lyrics.py # Lyrics generation sub-resource
|
|
54
|
+
│ ├── persona.py # Voice/style persona sub-resource
|
|
55
|
+
│ ├── exceptions.py # SDK custom exception classes
|
|
56
|
+
│ └── utils.py # Internal utility and polling helpers
|
|
57
|
+
├── tests/ # Test suite
|
|
58
|
+
│ ├── __init__.py
|
|
59
|
+
│ └── test_client.py # Mocked HTTP interface unit tests
|
|
60
|
+
├── examples/ # Basic usage examples
|
|
61
|
+
│ └── quickstart.py # Quickstart example script
|
|
62
|
+
├── pyproject.toml # PEP 621 compliant project packaging configuration
|
|
63
|
+
├── requirements.txt # Runtime dependencies
|
|
64
|
+
├── requirements-dev.txt# Development and testing requirements
|
|
65
|
+
├── LICENSE # MIT License file
|
|
66
|
+
└── README.md # Project documentation
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
This SDK requires `requests`. You can install the package directly from source:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or for development (editable mode):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install -e .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Quickstart
|
|
88
|
+
|
|
89
|
+
### 1. Initialize the Client
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from suno_easy import SunoClient
|
|
93
|
+
|
|
94
|
+
client = SunoClient(api_key="your_suno_api_key_here")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 2. Generate Music
|
|
98
|
+
|
|
99
|
+
Generate a track in custom mode (requires prompt, style, and title). By default, this blocks until the songs are generated (usually 2-3 minutes) and returns a list containing two song variations.
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
songs = client.music.generate(
|
|
103
|
+
prompt="A peaceful acoustic guitar melody with soft strings",
|
|
104
|
+
style="Folk, Acoustic",
|
|
105
|
+
title="Morning Breeze",
|
|
106
|
+
instrumental=True
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
for song in songs:
|
|
110
|
+
print(f"Song generated: {song.title} (ID: {song.id})")
|
|
111
|
+
print(f"Audio URL: {song.audio_url}")
|
|
112
|
+
|
|
113
|
+
# Download the track and its cover image
|
|
114
|
+
song.download(f"{song.title}.mp3")
|
|
115
|
+
song.download_image(f"{song.title}.jpg")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 3. Generate Lyrics
|
|
119
|
+
|
|
120
|
+
Create AI-generated lyrics structure markers like `[Verse]` or `[Chorus]`.
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
lyrics_list = client.lyrics.generate(prompt="a song about embarking on a journey to Mars")
|
|
124
|
+
|
|
125
|
+
for lyrics in lyrics_list:
|
|
126
|
+
print(f"Title Idea: {lyrics.title}")
|
|
127
|
+
print(lyrics.text)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 4. Separate Vocals (Stem Separation)
|
|
131
|
+
|
|
132
|
+
Separate an existing song task into vocals and instrumental tracks. Supports 2-stem (`separate_vocal`) and up to 12-stem (`split_stem`) separation.
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
stems = client.audio.separate_vocals(
|
|
136
|
+
task_id="original_music_task_id",
|
|
137
|
+
mode="separate_vocal" # or "split_stem"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
print(f"Vocal URL: {stems.vocal_url}")
|
|
141
|
+
print(f"Instrumental URL: {stems.instrumental_url}")
|
|
142
|
+
|
|
143
|
+
# Download isolated files
|
|
144
|
+
stems.download_vocal("vocals.mp3")
|
|
145
|
+
stems.download_instrumental("instrumental.mp3")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 5. Convert Audio to MIDI
|
|
149
|
+
|
|
150
|
+
Convert separated audio tracks into MIDI note structures.
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
midi_data = client.audio.generate_midi(task_id="vocal_removal_task_id")
|
|
154
|
+
|
|
155
|
+
print(f"MIDI Generation State: {midi_data.state}")
|
|
156
|
+
for instrument in midi_data.instruments:
|
|
157
|
+
print(f"Instrument: {instrument.name}")
|
|
158
|
+
for note in instrument.notes[:5]: # Print first 5 notes
|
|
159
|
+
print(f" Note pitch: {note.pitch}, start: {note.start}s, end: {note.end}s")
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Asynchronous Workflows (Webhooks & Background Tasks)
|
|
165
|
+
|
|
166
|
+
If you don't want the methods to block your program execution, set `wait=False`. The client will instantly return the `taskId` string. You can then poll later or receive webhook callbacks on your server.
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
# Starts music generation and returns instantly
|
|
170
|
+
task_id = client.music.generate(
|
|
171
|
+
prompt="Lo-fi hip hop beat for studying",
|
|
172
|
+
style="Lo-Fi",
|
|
173
|
+
title="Study Session",
|
|
174
|
+
wait=False,
|
|
175
|
+
callback_url="https://yourdomain.com/webhook"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
print(f"Music generation started. Task ID: {task_id}")
|
|
179
|
+
|
|
180
|
+
# Manually retrieve info later
|
|
181
|
+
task_info = client.music.get_task_info(task_id)
|
|
182
|
+
print(f"Status: {task_info.get('status')}")
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## API Reference
|
|
188
|
+
|
|
189
|
+
### `client.music`
|
|
190
|
+
* `generate(...) -> list[Song] | str`: Generates songs from prompts.
|
|
191
|
+
* `extend(...) -> list[Song] | str`: Extends an existing song from a timestamp.
|
|
192
|
+
* `generate_instrumental(...) -> list[Song] | str`: Generates instrumentals.
|
|
193
|
+
* `remaster(music_id, ...) -> list[Song] | str`: Improves the quality of a song.
|
|
194
|
+
|
|
195
|
+
### `client.lyrics`
|
|
196
|
+
* `generate(prompt, ...) -> list[Lyrics] | str`: Generates lyrics.
|
|
197
|
+
* `get(task_id) -> list[Lyrics]`: Retrieves lyrics from a completed task.
|
|
198
|
+
|
|
199
|
+
### `client.audio`
|
|
200
|
+
* `cover(upload_url, style, title, ...) -> list[Song] | str`: Applies a style cover to an uploaded audio.
|
|
201
|
+
* `extend(upload_url, continue_at, prompt, ...) -> list[Song] | str`: Extends an uploaded audio track.
|
|
202
|
+
* `separate_vocals(task_id, mode, ...) -> SeparatedStems | str`: Split vocals and instrumentation.
|
|
203
|
+
* `get_separated_stems(task_id) -> SeparatedStems`: Retrieves separated stems.
|
|
204
|
+
* `generate_midi(task_id, ...) -> MIDIData | str`: Converts audio stems to MIDI notes.
|
|
205
|
+
* `get_midi(task_id) -> MIDIData`: Retrieves MIDI notes.
|
|
206
|
+
* `add_vocals(upload_url, prompt, ...) -> list[Song] | str`: Adds vocals to an instrumental track.
|
|
207
|
+
* `add_instrumental(upload_url, title, tags, ...) -> list[Song] | str`: Adds backing instruments to vocals.
|
|
208
|
+
|
|
209
|
+
### `client.persona`
|
|
210
|
+
* `create(music_id, name) -> dict`: Creates a voice/style persona from a track.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# suno-easy 🎵
|
|
2
|
+
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> **Disclaimer**: This is an unofficial, community-driven Python SDK wrapper for the Suno API (`sunoapi.org`). It is not affiliated with, endorsed, sponsored, or supported by Suno, Inc. or the official Suno AI platform.
|
|
5
|
+
|
|
6
|
+
`suno-easy` is a lightweight, modern, and fully-typed Python SDK for the Suno AI API ([sunoapi.org](https://docs.sunoapi.org/)).
|
|
7
|
+
|
|
8
|
+
It provides an intuitive, object-oriented interface to generate music, write lyrics, create voice personas, separate audio stems, and generate MIDI notes from audio files.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Clean Namespace Organization**: Resources are grouped logically (`client.music`, `client.lyrics`, `client.audio`, `client.persona`).
|
|
15
|
+
- **Fully Typed**: Rich python dataclasses for responses (`Song`, `Lyrics`, `SeparatedStems`, `MIDIData`, `CoverImage`).
|
|
16
|
+
- **Smart Polling**: Methods can either block and return the processed result (`wait=True`) or instantly return a `taskId` for asynchronous workflows (`wait=False`).
|
|
17
|
+
- **Built-in Downloads**: Download audio tracks, cover images, and isolated stems with built-in streaming helpers.
|
|
18
|
+
- **Robust Error Handling**: Distinct exceptions for HTTP failures (`SunoAPIError`) and generation failures (`TaskFailed`).
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Repository Structure
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
suno-easy/
|
|
26
|
+
├── suno_easy/ # Core SDK library source code
|
|
27
|
+
│ ├── __init__.py # Exposed client, models, and exceptions
|
|
28
|
+
│ ├── client.py # Main SunoClient orchestrator
|
|
29
|
+
│ ├── models.py # Strongly typed dataclasses representing API payloads
|
|
30
|
+
│ ├── audio.py # Audio processing sub-resource (stems, MIDI, covers)
|
|
31
|
+
│ ├── music.py # Music generation and extension sub-resource
|
|
32
|
+
│ ├── lyrics.py # Lyrics generation sub-resource
|
|
33
|
+
│ ├── persona.py # Voice/style persona sub-resource
|
|
34
|
+
│ ├── exceptions.py # SDK custom exception classes
|
|
35
|
+
│ └── utils.py # Internal utility and polling helpers
|
|
36
|
+
├── tests/ # Test suite
|
|
37
|
+
│ ├── __init__.py
|
|
38
|
+
│ └── test_client.py # Mocked HTTP interface unit tests
|
|
39
|
+
├── examples/ # Basic usage examples
|
|
40
|
+
│ └── quickstart.py # Quickstart example script
|
|
41
|
+
├── pyproject.toml # PEP 621 compliant project packaging configuration
|
|
42
|
+
├── requirements.txt # Runtime dependencies
|
|
43
|
+
├── requirements-dev.txt# Development and testing requirements
|
|
44
|
+
├── LICENSE # MIT License file
|
|
45
|
+
└── README.md # Project documentation
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
This SDK requires `requests`. You can install the package directly from source:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install .
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or for development (editable mode):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install -e .
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Quickstart
|
|
67
|
+
|
|
68
|
+
### 1. Initialize the Client
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from suno_easy import SunoClient
|
|
72
|
+
|
|
73
|
+
client = SunoClient(api_key="your_suno_api_key_here")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2. Generate Music
|
|
77
|
+
|
|
78
|
+
Generate a track in custom mode (requires prompt, style, and title). By default, this blocks until the songs are generated (usually 2-3 minutes) and returns a list containing two song variations.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
songs = client.music.generate(
|
|
82
|
+
prompt="A peaceful acoustic guitar melody with soft strings",
|
|
83
|
+
style="Folk, Acoustic",
|
|
84
|
+
title="Morning Breeze",
|
|
85
|
+
instrumental=True
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
for song in songs:
|
|
89
|
+
print(f"Song generated: {song.title} (ID: {song.id})")
|
|
90
|
+
print(f"Audio URL: {song.audio_url}")
|
|
91
|
+
|
|
92
|
+
# Download the track and its cover image
|
|
93
|
+
song.download(f"{song.title}.mp3")
|
|
94
|
+
song.download_image(f"{song.title}.jpg")
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3. Generate Lyrics
|
|
98
|
+
|
|
99
|
+
Create AI-generated lyrics structure markers like `[Verse]` or `[Chorus]`.
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
lyrics_list = client.lyrics.generate(prompt="a song about embarking on a journey to Mars")
|
|
103
|
+
|
|
104
|
+
for lyrics in lyrics_list:
|
|
105
|
+
print(f"Title Idea: {lyrics.title}")
|
|
106
|
+
print(lyrics.text)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 4. Separate Vocals (Stem Separation)
|
|
110
|
+
|
|
111
|
+
Separate an existing song task into vocals and instrumental tracks. Supports 2-stem (`separate_vocal`) and up to 12-stem (`split_stem`) separation.
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
stems = client.audio.separate_vocals(
|
|
115
|
+
task_id="original_music_task_id",
|
|
116
|
+
mode="separate_vocal" # or "split_stem"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
print(f"Vocal URL: {stems.vocal_url}")
|
|
120
|
+
print(f"Instrumental URL: {stems.instrumental_url}")
|
|
121
|
+
|
|
122
|
+
# Download isolated files
|
|
123
|
+
stems.download_vocal("vocals.mp3")
|
|
124
|
+
stems.download_instrumental("instrumental.mp3")
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 5. Convert Audio to MIDI
|
|
128
|
+
|
|
129
|
+
Convert separated audio tracks into MIDI note structures.
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
midi_data = client.audio.generate_midi(task_id="vocal_removal_task_id")
|
|
133
|
+
|
|
134
|
+
print(f"MIDI Generation State: {midi_data.state}")
|
|
135
|
+
for instrument in midi_data.instruments:
|
|
136
|
+
print(f"Instrument: {instrument.name}")
|
|
137
|
+
for note in instrument.notes[:5]: # Print first 5 notes
|
|
138
|
+
print(f" Note pitch: {note.pitch}, start: {note.start}s, end: {note.end}s")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Asynchronous Workflows (Webhooks & Background Tasks)
|
|
144
|
+
|
|
145
|
+
If you don't want the methods to block your program execution, set `wait=False`. The client will instantly return the `taskId` string. You can then poll later or receive webhook callbacks on your server.
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
# Starts music generation and returns instantly
|
|
149
|
+
task_id = client.music.generate(
|
|
150
|
+
prompt="Lo-fi hip hop beat for studying",
|
|
151
|
+
style="Lo-Fi",
|
|
152
|
+
title="Study Session",
|
|
153
|
+
wait=False,
|
|
154
|
+
callback_url="https://yourdomain.com/webhook"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
print(f"Music generation started. Task ID: {task_id}")
|
|
158
|
+
|
|
159
|
+
# Manually retrieve info later
|
|
160
|
+
task_info = client.music.get_task_info(task_id)
|
|
161
|
+
print(f"Status: {task_info.get('status')}")
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## API Reference
|
|
167
|
+
|
|
168
|
+
### `client.music`
|
|
169
|
+
* `generate(...) -> list[Song] | str`: Generates songs from prompts.
|
|
170
|
+
* `extend(...) -> list[Song] | str`: Extends an existing song from a timestamp.
|
|
171
|
+
* `generate_instrumental(...) -> list[Song] | str`: Generates instrumentals.
|
|
172
|
+
* `remaster(music_id, ...) -> list[Song] | str`: Improves the quality of a song.
|
|
173
|
+
|
|
174
|
+
### `client.lyrics`
|
|
175
|
+
* `generate(prompt, ...) -> list[Lyrics] | str`: Generates lyrics.
|
|
176
|
+
* `get(task_id) -> list[Lyrics]`: Retrieves lyrics from a completed task.
|
|
177
|
+
|
|
178
|
+
### `client.audio`
|
|
179
|
+
* `cover(upload_url, style, title, ...) -> list[Song] | str`: Applies a style cover to an uploaded audio.
|
|
180
|
+
* `extend(upload_url, continue_at, prompt, ...) -> list[Song] | str`: Extends an uploaded audio track.
|
|
181
|
+
* `separate_vocals(task_id, mode, ...) -> SeparatedStems | str`: Split vocals and instrumentation.
|
|
182
|
+
* `get_separated_stems(task_id) -> SeparatedStems`: Retrieves separated stems.
|
|
183
|
+
* `generate_midi(task_id, ...) -> MIDIData | str`: Converts audio stems to MIDI notes.
|
|
184
|
+
* `get_midi(task_id) -> MIDIData`: Retrieves MIDI notes.
|
|
185
|
+
* `add_vocals(upload_url, prompt, ...) -> list[Song] | str`: Adds vocals to an instrumental track.
|
|
186
|
+
* `add_instrumental(upload_url, title, tags, ...) -> list[Song] | str`: Adds backing instruments to vocals.
|
|
187
|
+
|
|
188
|
+
### `client.persona`
|
|
189
|
+
* `create(music_id, name) -> dict`: Creates a voice/style persona from a track.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## License
|
|
194
|
+
|
|
195
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "suno-easy"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A lightweight, modern, and fully-typed Python SDK for the Suno AI API (sunoapi.org)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [
|
|
11
|
+
{ name = "Fred", email = "frederic.dymko@gmail.com" }
|
|
12
|
+
]
|
|
13
|
+
license = { text = "MIT" }
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
20
|
+
]
|
|
21
|
+
requires-python = ">=3.8"
|
|
22
|
+
dependencies = [
|
|
23
|
+
"requests>=2.25.0",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/Onnonoka/suno-easy"
|
|
28
|
+
Documentation = "https://github.com/Onnonoka/suno-easy#readme"
|
|
29
|
+
Repository = "https://github.com/Onnonoka/suno-easy.git"
|
|
30
|
+
Issues = "https://github.com/Onnonoka/suno-easy/issues"
|
|
31
|
+
|
|
32
|
+
[tool.setuptools]
|
|
33
|
+
packages = ["suno_easy"]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .client import SunoClient
|
|
2
|
+
from .models import (
|
|
3
|
+
Song,
|
|
4
|
+
Lyrics,
|
|
5
|
+
CoverImage,
|
|
6
|
+
SeparatedStems,
|
|
7
|
+
MIDIData,
|
|
8
|
+
MIDINote,
|
|
9
|
+
MIDIInstrument,
|
|
10
|
+
)
|
|
11
|
+
from .exceptions import SunoError, TaskFailed, SunoAPIError
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"SunoClient",
|
|
15
|
+
"Song",
|
|
16
|
+
"Lyrics",
|
|
17
|
+
"CoverImage",
|
|
18
|
+
"SeparatedStems",
|
|
19
|
+
"MIDIData",
|
|
20
|
+
"MIDINote",
|
|
21
|
+
"MIDIInstrument",
|
|
22
|
+
"SunoError",
|
|
23
|
+
"TaskFailed",
|
|
24
|
+
"SunoAPIError",
|
|
25
|
+
]
|