songbrain 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.
- songbrain-0.1.0/.gitignore +33 -0
- songbrain-0.1.0/LICENSE +21 -0
- songbrain-0.1.0/PKG-INFO +154 -0
- songbrain-0.1.0/README.md +121 -0
- songbrain-0.1.0/pyproject.toml +61 -0
- songbrain-0.1.0/src/songbrain/__init__.py +42 -0
- songbrain-0.1.0/src/songbrain/_client.py +437 -0
- songbrain-0.1.0/src/songbrain/_version.py +1 -0
- songbrain-0.1.0/src/songbrain/errors.py +105 -0
- songbrain-0.1.0/src/songbrain/py.typed +0 -0
- songbrain-0.1.0/src/songbrain/types.py +431 -0
- songbrain-0.1.0/src/songbrain/webhooks.py +112 -0
- songbrain-0.1.0/tests/conftest.py +11 -0
- songbrain-0.1.0/tests/test_client.py +212 -0
- songbrain-0.1.0/tests/test_live.py +63 -0
- songbrain-0.1.0/tests/test_webhooks.py +76 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# OS / editors
|
|
2
|
+
.DS_Store
|
|
3
|
+
Thumbs.db
|
|
4
|
+
.vscode/
|
|
5
|
+
.idea/
|
|
6
|
+
|
|
7
|
+
# Secrets
|
|
8
|
+
.env
|
|
9
|
+
.env.*
|
|
10
|
+
!.env.example
|
|
11
|
+
|
|
12
|
+
# Python
|
|
13
|
+
__pycache__/
|
|
14
|
+
*.py[cod]
|
|
15
|
+
*.egg-info/
|
|
16
|
+
.venv/
|
|
17
|
+
venv/
|
|
18
|
+
build/
|
|
19
|
+
dist/
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.mypy_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
|
|
24
|
+
# Node
|
|
25
|
+
node_modules/
|
|
26
|
+
js/dist/
|
|
27
|
+
*.tgz
|
|
28
|
+
npm-debug.log*
|
|
29
|
+
|
|
30
|
+
# MCP publisher
|
|
31
|
+
mcp-publisher
|
|
32
|
+
mcp-publisher.exe
|
|
33
|
+
.mcpregistry_*
|
songbrain-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Songbrain
|
|
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.
|
songbrain-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: songbrain
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python client for the Songbrain API: song in, video plan out. Song DNA, beat grid, best moments, timed lyrics, story and a beat-synced shot plan.
|
|
5
|
+
Project-URL: Homepage, https://www.songbrain.ai/api-access
|
|
6
|
+
Project-URL: Documentation, https://www.songbrain.ai/docs/api
|
|
7
|
+
Project-URL: Source, https://github.com/songbrain-ai/songbrain
|
|
8
|
+
Project-URL: Issues, https://github.com/songbrain-ai/songbrain/issues
|
|
9
|
+
Author-email: Songbrain <support@songbrain.ai>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: ai music video,beat detection,lyrics timestamps,mcp,music analysis api,shot plan,song structure,songbrain
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
25
|
+
Classifier: Topic :: Multimedia :: Video
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Requires-Dist: requests>=2.25
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: build>=1; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# songbrain
|
|
35
|
+
|
|
36
|
+
**Song in, video plan out.** The official Python client for the [Songbrain API](https://www.songbrain.ai/docs/api), the music analysis API for AI video.
|
|
37
|
+
|
|
38
|
+
One call returns the song DNA (genre, tempo, key, mood, instruments, loudness), a beat grid, sections, the best moments with reasons, word-timed lyrics, the story, world and palette, and a beat-synced shot plan with a ready prompt for every scene.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install songbrain
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Python 3.9+. One dependency: `requests`.
|
|
45
|
+
|
|
46
|
+
## Quickstart
|
|
47
|
+
|
|
48
|
+
Get a key at [app.songbrain.ai/developers](https://app.songbrain.ai/developers). 5 songs a month are free.
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from songbrain import Songbrain
|
|
52
|
+
|
|
53
|
+
sb = Songbrain() # reads SONGBRAIN_API_KEY
|
|
54
|
+
|
|
55
|
+
song = sb.analyze("song.mp3") # or analyze(audio_url="https://…/song.mp3")
|
|
56
|
+
|
|
57
|
+
print(song["song_dna"]["genre"], song["song_dna"]["tempo_bpm"], song["song_dna"]["key"])
|
|
58
|
+
for scene in song["shot_plan"]["clip"]["scenes"]:
|
|
59
|
+
print(f'{scene["start_sec"]:.2f}-{scene["end_sec"]:.2f} [{scene["act"]}] {scene["prompt"]}')
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`analyze()` uploads the song, waits until the analysis is done (typically 60–90 s) and returns the full document.
|
|
63
|
+
|
|
64
|
+
## Try it without a key
|
|
65
|
+
|
|
66
|
+
The example endpoints return real analyses of Songbrain's own songs, in exactly the format your songs get.
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from songbrain import Songbrain
|
|
70
|
+
|
|
71
|
+
sb = Songbrain()
|
|
72
|
+
print([e["id"] for e in sb.examples()["data"]])
|
|
73
|
+
plan = sb.example_shot_plan("old-truck-home")
|
|
74
|
+
print(plan["shot_plan"]["clip"]["scenes"][0]["prompt"])
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Methods
|
|
78
|
+
|
|
79
|
+
Every method returns the JSON body of the response as a `dict`. Types for editors live in `songbrain.types` (`Song`, `SongDNA`, `Timeline`, `BestMoment`, `Lyrics`, `Scores`, `Story`, `ShotPlan`, `Scene`, …).
|
|
80
|
+
|
|
81
|
+
| Method | API call | Key |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| `analyze(file=None, *, audio_url=None, title=None, artist=None, webhook_url=None, external_ref=None, filename=None, wait=True, poll_interval=5, timeout=300)` | `POST /songs`, then polls `GET /songs/{id}` | yes |
|
|
84
|
+
| `wait_for(song_id, *, poll_interval=5, timeout=300)` | polls `GET /songs/{id}` | yes |
|
|
85
|
+
| `get_song(id, view=None, include=None)` | `GET /songs/{id}` | yes |
|
|
86
|
+
| `shot_plan(id)` | `GET /songs/{id}/shot-plan` | yes |
|
|
87
|
+
| `list_songs(limit=20)` | `GET /songs` | yes |
|
|
88
|
+
| `delete_song(id)` | `DELETE /songs/{id}` | yes |
|
|
89
|
+
| `account()` | `GET /account` | yes |
|
|
90
|
+
| `pricing()` | `GET /pricing` | no |
|
|
91
|
+
| `examples()` | `GET /examples` | no |
|
|
92
|
+
| `example(id, view=None, include=None)` | `GET /examples/{id}` | no |
|
|
93
|
+
| `example_shot_plan(id)` | `GET /examples/{id}/shot-plan` | no |
|
|
94
|
+
|
|
95
|
+
- `file` can be a path, `bytes` or an open binary file. MP3, WAV, FLAC, M4A, AAC, OGG or AIFF, up to 100 MB, 30 s to 10 min. The file name's extension has to match the audio; for bytes without a name the client detects the format or you pass `filename="song.mp3"`.
|
|
96
|
+
- `wait=False` returns the 202 body right away: `{"id", "status": "processing", "eta_sec", "billing"}`. Use `wait_for(id)` or a webhook later.
|
|
97
|
+
- `view="summary"` drops word timings and beat arrays (about 3x smaller). `include=["song_dna", "shot_plan"]` returns only those sections.
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
sb = Songbrain(api_key="sb_live_…", timeout=60, max_retries=3)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Errors
|
|
104
|
+
|
|
105
|
+
API errors raise `SongbrainError` with `.status`, `.code` and `.message`. Subclasses:
|
|
106
|
+
|
|
107
|
+
| Exception | When |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `AuthenticationError` | 401 `missing_api_key`, `invalid_api_key` |
|
|
110
|
+
| `InsufficientCredits` | 402: free songs used up and fewer than 25 credits |
|
|
111
|
+
| `NotFound` | 404: unknown id, or not yours |
|
|
112
|
+
| `RateLimited` | 429, with `.retry_after` in seconds |
|
|
113
|
+
| `AnalysisFailed` | the song was accepted but failed (credits are refunded) |
|
|
114
|
+
| `WaitTimeout` | `analyze(wait=True)` gave up; the song keeps processing |
|
|
115
|
+
|
|
116
|
+
The client retries 429 and 5xx responses up to 3 times with backoff and honours `Retry-After` (up to 60 s). Uploads are only retried when nothing can have been created (429, 502, 503).
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from songbrain import Songbrain, InsufficientCredits, RateLimited
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
song = Songbrain().analyze(audio_url="https://example.com/song.mp3")
|
|
123
|
+
except InsufficientCredits:
|
|
124
|
+
print("Top up at https://app.songbrain.ai/developers/billing")
|
|
125
|
+
except RateLimited as e:
|
|
126
|
+
print("Try again in", e.retry_after, "s")
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Webhooks
|
|
130
|
+
|
|
131
|
+
Pass `webhook_url` and Songbrain POSTs `song.done` or `song.failed` (and `account.low_balance`). Verify the `Songbrain-Signature` header against the raw body:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from songbrain import webhooks
|
|
135
|
+
|
|
136
|
+
ok = webhooks.verify(raw_body, request.headers["Songbrain-Signature"], secret) # bool
|
|
137
|
+
event = webhooks.construct_event(raw_body, header, secret) # verified dict, or raises
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The default tolerance is 300 s. A full Flask receiver is in [examples/python/webhook_server.py](https://github.com/songbrain-ai/songbrain/blob/main/examples/python/webhook_server.py).
|
|
141
|
+
|
|
142
|
+
## Pricing
|
|
143
|
+
|
|
144
|
+
5 free songs per account per month. Then 25 credits per song (about $0.50). No subscription. Everything is included: analysis, story and shot plan. Results are yours, also in a paid or white-label product. See [Terms §17](https://www.songbrain.ai/terms#api).
|
|
145
|
+
|
|
146
|
+
## Links
|
|
147
|
+
|
|
148
|
+
- API docs: https://www.songbrain.ai/docs/api
|
|
149
|
+
- OpenAPI: https://api.songbrain.ai/v1/openapi.json
|
|
150
|
+
- MCP server: https://api.songbrain.ai/mcp
|
|
151
|
+
- Get a key: https://app.songbrain.ai/developers
|
|
152
|
+
- Source: https://github.com/songbrain-ai/songbrain
|
|
153
|
+
|
|
154
|
+
MIT License.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# songbrain
|
|
2
|
+
|
|
3
|
+
**Song in, video plan out.** The official Python client for the [Songbrain API](https://www.songbrain.ai/docs/api), the music analysis API for AI video.
|
|
4
|
+
|
|
5
|
+
One call returns the song DNA (genre, tempo, key, mood, instruments, loudness), a beat grid, sections, the best moments with reasons, word-timed lyrics, the story, world and palette, and a beat-synced shot plan with a ready prompt for every scene.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install songbrain
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Python 3.9+. One dependency: `requests`.
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
Get a key at [app.songbrain.ai/developers](https://app.songbrain.ai/developers). 5 songs a month are free.
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from songbrain import Songbrain
|
|
19
|
+
|
|
20
|
+
sb = Songbrain() # reads SONGBRAIN_API_KEY
|
|
21
|
+
|
|
22
|
+
song = sb.analyze("song.mp3") # or analyze(audio_url="https://…/song.mp3")
|
|
23
|
+
|
|
24
|
+
print(song["song_dna"]["genre"], song["song_dna"]["tempo_bpm"], song["song_dna"]["key"])
|
|
25
|
+
for scene in song["shot_plan"]["clip"]["scenes"]:
|
|
26
|
+
print(f'{scene["start_sec"]:.2f}-{scene["end_sec"]:.2f} [{scene["act"]}] {scene["prompt"]}')
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`analyze()` uploads the song, waits until the analysis is done (typically 60–90 s) and returns the full document.
|
|
30
|
+
|
|
31
|
+
## Try it without a key
|
|
32
|
+
|
|
33
|
+
The example endpoints return real analyses of Songbrain's own songs, in exactly the format your songs get.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from songbrain import Songbrain
|
|
37
|
+
|
|
38
|
+
sb = Songbrain()
|
|
39
|
+
print([e["id"] for e in sb.examples()["data"]])
|
|
40
|
+
plan = sb.example_shot_plan("old-truck-home")
|
|
41
|
+
print(plan["shot_plan"]["clip"]["scenes"][0]["prompt"])
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Methods
|
|
45
|
+
|
|
46
|
+
Every method returns the JSON body of the response as a `dict`. Types for editors live in `songbrain.types` (`Song`, `SongDNA`, `Timeline`, `BestMoment`, `Lyrics`, `Scores`, `Story`, `ShotPlan`, `Scene`, …).
|
|
47
|
+
|
|
48
|
+
| Method | API call | Key |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `analyze(file=None, *, audio_url=None, title=None, artist=None, webhook_url=None, external_ref=None, filename=None, wait=True, poll_interval=5, timeout=300)` | `POST /songs`, then polls `GET /songs/{id}` | yes |
|
|
51
|
+
| `wait_for(song_id, *, poll_interval=5, timeout=300)` | polls `GET /songs/{id}` | yes |
|
|
52
|
+
| `get_song(id, view=None, include=None)` | `GET /songs/{id}` | yes |
|
|
53
|
+
| `shot_plan(id)` | `GET /songs/{id}/shot-plan` | yes |
|
|
54
|
+
| `list_songs(limit=20)` | `GET /songs` | yes |
|
|
55
|
+
| `delete_song(id)` | `DELETE /songs/{id}` | yes |
|
|
56
|
+
| `account()` | `GET /account` | yes |
|
|
57
|
+
| `pricing()` | `GET /pricing` | no |
|
|
58
|
+
| `examples()` | `GET /examples` | no |
|
|
59
|
+
| `example(id, view=None, include=None)` | `GET /examples/{id}` | no |
|
|
60
|
+
| `example_shot_plan(id)` | `GET /examples/{id}/shot-plan` | no |
|
|
61
|
+
|
|
62
|
+
- `file` can be a path, `bytes` or an open binary file. MP3, WAV, FLAC, M4A, AAC, OGG or AIFF, up to 100 MB, 30 s to 10 min. The file name's extension has to match the audio; for bytes without a name the client detects the format or you pass `filename="song.mp3"`.
|
|
63
|
+
- `wait=False` returns the 202 body right away: `{"id", "status": "processing", "eta_sec", "billing"}`. Use `wait_for(id)` or a webhook later.
|
|
64
|
+
- `view="summary"` drops word timings and beat arrays (about 3x smaller). `include=["song_dna", "shot_plan"]` returns only those sections.
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
sb = Songbrain(api_key="sb_live_…", timeout=60, max_retries=3)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Errors
|
|
71
|
+
|
|
72
|
+
API errors raise `SongbrainError` with `.status`, `.code` and `.message`. Subclasses:
|
|
73
|
+
|
|
74
|
+
| Exception | When |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `AuthenticationError` | 401 `missing_api_key`, `invalid_api_key` |
|
|
77
|
+
| `InsufficientCredits` | 402: free songs used up and fewer than 25 credits |
|
|
78
|
+
| `NotFound` | 404: unknown id, or not yours |
|
|
79
|
+
| `RateLimited` | 429, with `.retry_after` in seconds |
|
|
80
|
+
| `AnalysisFailed` | the song was accepted but failed (credits are refunded) |
|
|
81
|
+
| `WaitTimeout` | `analyze(wait=True)` gave up; the song keeps processing |
|
|
82
|
+
|
|
83
|
+
The client retries 429 and 5xx responses up to 3 times with backoff and honours `Retry-After` (up to 60 s). Uploads are only retried when nothing can have been created (429, 502, 503).
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from songbrain import Songbrain, InsufficientCredits, RateLimited
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
song = Songbrain().analyze(audio_url="https://example.com/song.mp3")
|
|
90
|
+
except InsufficientCredits:
|
|
91
|
+
print("Top up at https://app.songbrain.ai/developers/billing")
|
|
92
|
+
except RateLimited as e:
|
|
93
|
+
print("Try again in", e.retry_after, "s")
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Webhooks
|
|
97
|
+
|
|
98
|
+
Pass `webhook_url` and Songbrain POSTs `song.done` or `song.failed` (and `account.low_balance`). Verify the `Songbrain-Signature` header against the raw body:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from songbrain import webhooks
|
|
102
|
+
|
|
103
|
+
ok = webhooks.verify(raw_body, request.headers["Songbrain-Signature"], secret) # bool
|
|
104
|
+
event = webhooks.construct_event(raw_body, header, secret) # verified dict, or raises
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The default tolerance is 300 s. A full Flask receiver is in [examples/python/webhook_server.py](https://github.com/songbrain-ai/songbrain/blob/main/examples/python/webhook_server.py).
|
|
108
|
+
|
|
109
|
+
## Pricing
|
|
110
|
+
|
|
111
|
+
5 free songs per account per month. Then 25 credits per song (about $0.50). No subscription. Everything is included: analysis, story and shot plan. Results are yours, also in a paid or white-label product. See [Terms §17](https://www.songbrain.ai/terms#api).
|
|
112
|
+
|
|
113
|
+
## Links
|
|
114
|
+
|
|
115
|
+
- API docs: https://www.songbrain.ai/docs/api
|
|
116
|
+
- OpenAPI: https://api.songbrain.ai/v1/openapi.json
|
|
117
|
+
- MCP server: https://api.songbrain.ai/mcp
|
|
118
|
+
- Get a key: https://app.songbrain.ai/developers
|
|
119
|
+
- Source: https://github.com/songbrain-ai/songbrain
|
|
120
|
+
|
|
121
|
+
MIT License.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "songbrain"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Official Python client for the Songbrain API: song in, video plan out. Song DNA, beat grid, best moments, timed lyrics, story and a beat-synced shot plan."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
authors = [{ name = "Songbrain", email = "support@songbrain.ai" }]
|
|
14
|
+
keywords = [
|
|
15
|
+
"music analysis api",
|
|
16
|
+
"ai music video",
|
|
17
|
+
"shot plan",
|
|
18
|
+
"beat detection",
|
|
19
|
+
"song structure",
|
|
20
|
+
"lyrics timestamps",
|
|
21
|
+
"songbrain",
|
|
22
|
+
"mcp",
|
|
23
|
+
]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"License :: OSI Approved :: MIT License",
|
|
28
|
+
"Operating System :: OS Independent",
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
31
|
+
"Programming Language :: Python :: 3.9",
|
|
32
|
+
"Programming Language :: Python :: 3.10",
|
|
33
|
+
"Programming Language :: Python :: 3.11",
|
|
34
|
+
"Programming Language :: Python :: 3.12",
|
|
35
|
+
"Programming Language :: Python :: 3.13",
|
|
36
|
+
"Topic :: Multimedia :: Sound/Audio :: Analysis",
|
|
37
|
+
"Topic :: Multimedia :: Video",
|
|
38
|
+
"Typing :: Typed",
|
|
39
|
+
]
|
|
40
|
+
dependencies = ["requests>=2.25"]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
dev = ["pytest>=7", "build>=1"]
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
Homepage = "https://www.songbrain.ai/api-access"
|
|
47
|
+
Documentation = "https://www.songbrain.ai/docs/api"
|
|
48
|
+
Source = "https://github.com/songbrain-ai/songbrain"
|
|
49
|
+
Issues = "https://github.com/songbrain-ai/songbrain/issues"
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.wheel]
|
|
52
|
+
packages = ["src/songbrain"]
|
|
53
|
+
|
|
54
|
+
[tool.hatch.build.targets.sdist]
|
|
55
|
+
include = ["src/songbrain", "tests", "README.md", "LICENSE", "pyproject.toml"]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
testpaths = ["tests"]
|
|
59
|
+
markers = [
|
|
60
|
+
"live: calls the real Songbrain API (no-key example endpoints). Skip with -m 'not live' or SONGBRAIN_OFFLINE=1.",
|
|
61
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Songbrain: song in, video plan out.
|
|
2
|
+
|
|
3
|
+
The official Python client for the Songbrain API (https://www.songbrain.ai/docs/api).
|
|
4
|
+
|
|
5
|
+
from songbrain import Songbrain
|
|
6
|
+
|
|
7
|
+
sb = Songbrain() # reads SONGBRAIN_API_KEY
|
|
8
|
+
song = sb.analyze("song.mp3")
|
|
9
|
+
for scene in song["shot_plan"]["clip"]["scenes"]:
|
|
10
|
+
print(scene["start_sec"], scene["end_sec"], scene["prompt"])
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from . import types, webhooks
|
|
14
|
+
from ._client import DEFAULT_BASE_URL, SECTIONS, FileInput, Include, Songbrain
|
|
15
|
+
from ._version import __version__
|
|
16
|
+
from .errors import (
|
|
17
|
+
AnalysisFailed,
|
|
18
|
+
AuthenticationError,
|
|
19
|
+
InsufficientCredits,
|
|
20
|
+
NotFound,
|
|
21
|
+
RateLimited,
|
|
22
|
+
SongbrainError,
|
|
23
|
+
WaitTimeout,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"Songbrain",
|
|
28
|
+
"DEFAULT_BASE_URL",
|
|
29
|
+
"SECTIONS",
|
|
30
|
+
"FileInput",
|
|
31
|
+
"Include",
|
|
32
|
+
"SongbrainError",
|
|
33
|
+
"AuthenticationError",
|
|
34
|
+
"InsufficientCredits",
|
|
35
|
+
"NotFound",
|
|
36
|
+
"RateLimited",
|
|
37
|
+
"AnalysisFailed",
|
|
38
|
+
"WaitTimeout",
|
|
39
|
+
"types",
|
|
40
|
+
"webhooks",
|
|
41
|
+
"__version__",
|
|
42
|
+
]
|