spotantic 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.
- spotantic-0.1.0/.gitignore +16 -0
- spotantic-0.1.0/LICENSE +21 -0
- spotantic-0.1.0/PKG-INFO +312 -0
- spotantic-0.1.0/README.md +289 -0
- spotantic-0.1.0/pyproject.toml +111 -0
- spotantic-0.1.0/src/spotantic/py.typed +0 -0
spotantic-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sebastian Domagała
|
|
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.
|
spotantic-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: spotantic
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async Spotify API client
|
|
5
|
+
Project-URL: Homepage, https://github.com/domagalasebastian/spotantic
|
|
6
|
+
Project-URL: Documentation, https://spotantic.readthedocs.io
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/domagalasebastian/spotantic/issues
|
|
8
|
+
Project-URL: Questions, https://github.com/domagalasebastian/spotantic/discussions
|
|
9
|
+
Author: Sebastian Domagała
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: aiohttp,api-client,async,spotify
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Requires-Dist: aiohttp>=3.13.0
|
|
20
|
+
Requires-Dist: pydantic-settings>=2.11.0
|
|
21
|
+
Requires-Dist: pydantic>=2.12.0
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Spotantic
|
|
25
|
+
|
|
26
|
+
[](https://www.python.org/downloads/)
|
|
27
|
+
[](LICENSE)
|
|
28
|
+
|
|
29
|
+
An asynchronous Python client library for the Spotify Web API with full type hints, modular endpoint helpers, and support for multiple authorization flows.
|
|
30
|
+
|
|
31
|
+
## ✨ Features
|
|
32
|
+
|
|
33
|
+
- **Fully Asynchronous**: Built on `aiohttp` for non-blocking operations
|
|
34
|
+
- **Type-Safe**: Leverages Pydantic for request validation and response parsing
|
|
35
|
+
- **Multiple Auth Flows**: Support for Client Credentials, Authorization Code, and Authorization Code PKCE flows
|
|
36
|
+
- **Modular Endpoints**: Clean, organized endpoint helpers for albums, artists, playlists, tracks, users, and more
|
|
37
|
+
- **Request Validation**: All requests are validated before sending to Spotify's API
|
|
38
|
+
- **Automatic Token Refresh**: Optional automatic refresh token handling
|
|
39
|
+
- **Comprehensive Documentation**: Full API reference and examples included
|
|
40
|
+
|
|
41
|
+
## 📋 Prerequisites
|
|
42
|
+
|
|
43
|
+
- **Python 3.12 or higher**
|
|
44
|
+
- A Spotify Developer account (get one at [developer.spotify.com](https://developer.spotify.com))
|
|
45
|
+
- Client ID and Client Secret from the Spotify Developer Dashboard
|
|
46
|
+
|
|
47
|
+
## 🔧 Installation
|
|
48
|
+
|
|
49
|
+
### From PyPI (Recommended)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Using uv (recommended)
|
|
53
|
+
uv add spotantic
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or using pip:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install spotantic
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### From Source
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/domagalasebastian/spotantic.git
|
|
66
|
+
cd spotantic
|
|
67
|
+
|
|
68
|
+
# Create venv and install dependencies
|
|
69
|
+
uv sync
|
|
70
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
71
|
+
|
|
72
|
+
# Install in development mode
|
|
73
|
+
uv sync --group dev
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 🚀 Quick Start
|
|
77
|
+
|
|
78
|
+
### 1. Configure Your Environment
|
|
79
|
+
|
|
80
|
+
Create a `.env` file in your project root with your Spotify credentials:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Your credentials from Spotify Developer Dashboard
|
|
84
|
+
SPOTANTIC_AUTH_CLIENT_ID=your_client_id_here
|
|
85
|
+
SPOTANTIC_AUTH_CLIENT_SECRET=your_client_secret_here
|
|
86
|
+
SPOTANTIC_AUTH_REDIRECT_URI=http://127.0.0.1:8000/callback
|
|
87
|
+
|
|
88
|
+
# Scopes you need (space-separated)
|
|
89
|
+
SPOTANTIC_AUTH_SCOPE=user-library-read user-library-modify
|
|
90
|
+
|
|
91
|
+
# Optional: where to store the access token cache
|
|
92
|
+
SPOTANTIC_AUTH_ACCESS_TOKEN_FILE_PATH=.token_info_cache
|
|
93
|
+
SPOTANTIC_AUTH_STORE_ACCESS_TOKEN=true
|
|
94
|
+
|
|
95
|
+
# Optional: logging configuration
|
|
96
|
+
SPOTANTIC_LOGGING_ENABLE=true
|
|
97
|
+
SPOTANTIC_LOGGING_DEBUG=false
|
|
98
|
+
SPOTANTIC_LOGGING_LOGS_DIR=logs/
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For more details on configuration options, see the [Quick Start Guide](https://spotantic.readthedocs.io/en/latest/quickstart.html).
|
|
102
|
+
|
|
103
|
+
### 2. Create a Client
|
|
104
|
+
|
|
105
|
+
Choose an authorization flow based on your use case:
|
|
106
|
+
|
|
107
|
+
#### Authorization Code PKCE Flow (Recommended for user-facing apps)
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
import asyncio
|
|
111
|
+
from spotantic.auth import AuthCodePKCEFlowManager
|
|
112
|
+
from spotantic.client import SpotanticClient
|
|
113
|
+
from spotantic.models.auth import AuthSettings
|
|
114
|
+
|
|
115
|
+
async def main():
|
|
116
|
+
# Load settings from .env file
|
|
117
|
+
auth_settings = AuthSettings()
|
|
118
|
+
|
|
119
|
+
# Create auth manager (browser opens automatically for authorization)
|
|
120
|
+
auth_manager = AuthCodePKCEFlowManager(
|
|
121
|
+
auth_settings=auth_settings,
|
|
122
|
+
allow_lazy_refresh=True
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Authorize user
|
|
126
|
+
await auth_manager.authorize()
|
|
127
|
+
|
|
128
|
+
# Create client
|
|
129
|
+
client = SpotanticClient(
|
|
130
|
+
auth_manager=auth_manager,
|
|
131
|
+
max_attempts=3,
|
|
132
|
+
check_insufficient_scope=True
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
return client
|
|
136
|
+
|
|
137
|
+
# Run it
|
|
138
|
+
client = asyncio.run(main())
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Client Credentials Flow (For server-to-server requests)
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from spotantic.auth import ClientCredentialsFlowManager
|
|
145
|
+
from spotantic.client import SpotanticClient
|
|
146
|
+
from spotantic.models.auth import AuthSettings
|
|
147
|
+
|
|
148
|
+
async def main():
|
|
149
|
+
auth_settings = AuthSettings()
|
|
150
|
+
auth_manager = ClientCredentialsFlowManager(auth_settings=auth_settings)
|
|
151
|
+
await auth_manager.authorize()
|
|
152
|
+
|
|
153
|
+
return SpotanticClient(auth_manager=auth_manager)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### Standard Authorization Code Flow
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from spotantic.auth import AuthCodeFlowManager
|
|
160
|
+
from spotantic.client import SpotanticClient
|
|
161
|
+
from spotantic.models.auth import AuthSettings
|
|
162
|
+
|
|
163
|
+
async def main():
|
|
164
|
+
auth_settings = AuthSettings()
|
|
165
|
+
auth_manager = AuthCodeFlowManager(
|
|
166
|
+
auth_settings=auth_settings,
|
|
167
|
+
allow_lazy_refresh=True
|
|
168
|
+
)
|
|
169
|
+
await auth_manager.authorize()
|
|
170
|
+
|
|
171
|
+
return SpotanticClient(auth_manager=auth_manager)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 3. Make API Requests
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from spotantic.endpoints import albums, tracks
|
|
178
|
+
|
|
179
|
+
async def search_and_get_details(client):
|
|
180
|
+
# Get user's saved albums
|
|
181
|
+
saved_albums = await albums.get_user_saved_albums(client, limit=5)
|
|
182
|
+
|
|
183
|
+
# All responses are fully typed
|
|
184
|
+
for album in saved_albums.data.items:
|
|
185
|
+
print(f"Album: {album.album.album_name}")
|
|
186
|
+
print(f"Artist: {album.album.artists[0].artist_name}")
|
|
187
|
+
|
|
188
|
+
# Get details for a specific album
|
|
189
|
+
album_id = saved_albums.data.items[0].album.album_id
|
|
190
|
+
album_details = await albums.get_album(client, album_id=album_id)
|
|
191
|
+
|
|
192
|
+
print(f"Release Date: {album_details.data.release_date}")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
For more examples, see the [examples](examples/) directory and [full documentation](https://spotantic.readthedocs.io/).
|
|
196
|
+
|
|
197
|
+
## 📚 Authorization Flows
|
|
198
|
+
|
|
199
|
+
Spotantic supports three Spotify authorization flows:
|
|
200
|
+
|
|
201
|
+
| Flow | Use Case | Refresh Token | Requires Secret |
|
|
202
|
+
|------|----------|---------------|-----------------|
|
|
203
|
+
| **Client Credentials** | Server-to-server, no user data | ❌ | ✅ |
|
|
204
|
+
| **Authorization Code** | Full user authorization, backendapps | ✅ | ✅ |
|
|
205
|
+
| **Authorization Code PKCE** | Browser/native apps | ✅ | ❌ |
|
|
206
|
+
|
|
207
|
+
**Important**: Spotantic only supports localhost redirect URIs. During authorization, the library temporarily hosts a local endpoint to complete the OAuth exchange.
|
|
208
|
+
|
|
209
|
+
See the [Authorization Guide](https://spotantic.readthedocs.io/en/latest/auth_reference.html) for detailed information.
|
|
210
|
+
|
|
211
|
+
## 🧪 Testing and Development
|
|
212
|
+
|
|
213
|
+
### Running Tests
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Run all unit tests
|
|
217
|
+
pytest tests/unit
|
|
218
|
+
|
|
219
|
+
# Run specific test directory
|
|
220
|
+
pytest tests/unit/endpoints/albums
|
|
221
|
+
|
|
222
|
+
# Run integration tests (requires valid token and network access)
|
|
223
|
+
pytest tests/integration
|
|
224
|
+
|
|
225
|
+
# Run only tests that do not affect user data
|
|
226
|
+
pytest tests/integration -m "readonly"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Code Quality Checks
|
|
230
|
+
|
|
231
|
+
Spotantic uses Ruff for linting and formatting. All contributions must pass these checks:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Run pre-commit checks (linting, formatting, type checking)
|
|
235
|
+
uv run pre-commit run --all-files
|
|
236
|
+
|
|
237
|
+
# Or individually:
|
|
238
|
+
# Lint and auto-fix
|
|
239
|
+
uv run ruff check --fix .
|
|
240
|
+
|
|
241
|
+
# Format code
|
|
242
|
+
uv run ruff format .
|
|
243
|
+
|
|
244
|
+
# Type checking
|
|
245
|
+
pyright
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Building Documentation Locally
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
cd docs
|
|
252
|
+
uv run sphinx-build -b html source/ build/
|
|
253
|
+
# Documentation available at build/index.html (open in browser)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## 🤝 Contributing
|
|
257
|
+
|
|
258
|
+
Contributions are welcome! Please follow these guidelines:
|
|
259
|
+
|
|
260
|
+
1. **Code Style**: All code must pass Ruff linting and formatting checks. Run `pre-commit run --all-files` before submitting a PR.
|
|
261
|
+
|
|
262
|
+
2. **Type Checking**: Code must pass Pyright type checking (`pyright`).
|
|
263
|
+
|
|
264
|
+
3. **Testing**:
|
|
265
|
+
- Add tests for any new features
|
|
266
|
+
- Ensure all tests pass: `pytest tests/unit`
|
|
267
|
+
- Tests run on Python 3.12, 3.13, and 3.14
|
|
268
|
+
|
|
269
|
+
4. **Commit Style**: Follow [Conventional Commits](https://www.conventionalcommits.org/) format.
|
|
270
|
+
|
|
271
|
+
5. **Documentation**: Update relevant documentation for API changes.
|
|
272
|
+
|
|
273
|
+
### Development Workflow
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Setup development environment
|
|
277
|
+
uv sync --all-groups
|
|
278
|
+
|
|
279
|
+
# Activate virtual environment
|
|
280
|
+
source .venv/bin/activate
|
|
281
|
+
|
|
282
|
+
# Make your changes and run checks
|
|
283
|
+
uv run pre-commit run --all-files
|
|
284
|
+
pytest tests/unit
|
|
285
|
+
|
|
286
|
+
# Optionally, run integration tests (requires valid token and network access)
|
|
287
|
+
pytest tests/integration
|
|
288
|
+
|
|
289
|
+
# Build docs to verify they work
|
|
290
|
+
uv run sphinx-build -b html docs/source docs/build/
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## 📄 License
|
|
294
|
+
|
|
295
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
296
|
+
|
|
297
|
+
## ⚠️ Legal Disclaimer
|
|
298
|
+
|
|
299
|
+
**This project is not affiliated with, endorsed by, or associated with Spotify AB or any of its subsidiaries or affiliates.** Spotantic is an independent, community-maintained library that provides convenient access to the Spotify Web API. All Spotify trademarks, logos, and product names are the property of Spotify AB.
|
|
300
|
+
|
|
301
|
+
Please ensure your use of this library complies with [Spotify's Developer Terms of Service](https://developer.spotify.com/terms).
|
|
302
|
+
|
|
303
|
+
## 🔗 Resources
|
|
304
|
+
|
|
305
|
+
- **[Spotify Web API Documentation](https://developer.spotify.com/documentation/web-api/)**
|
|
306
|
+
- **[Project Documentation](https://spotantic.readthedocs.io/)**
|
|
307
|
+
- **[GitHub Repository](https://github.com/domagalasebastian/spotantic)**
|
|
308
|
+
- **[Examples](examples/)**
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
Made with ❤️ by [Sebastian Domagała](https://github.com/domagalasebastian)
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Spotantic
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
An asynchronous Python client library for the Spotify Web API with full type hints, modular endpoint helpers, and support for multiple authorization flows.
|
|
7
|
+
|
|
8
|
+
## ✨ Features
|
|
9
|
+
|
|
10
|
+
- **Fully Asynchronous**: Built on `aiohttp` for non-blocking operations
|
|
11
|
+
- **Type-Safe**: Leverages Pydantic for request validation and response parsing
|
|
12
|
+
- **Multiple Auth Flows**: Support for Client Credentials, Authorization Code, and Authorization Code PKCE flows
|
|
13
|
+
- **Modular Endpoints**: Clean, organized endpoint helpers for albums, artists, playlists, tracks, users, and more
|
|
14
|
+
- **Request Validation**: All requests are validated before sending to Spotify's API
|
|
15
|
+
- **Automatic Token Refresh**: Optional automatic refresh token handling
|
|
16
|
+
- **Comprehensive Documentation**: Full API reference and examples included
|
|
17
|
+
|
|
18
|
+
## 📋 Prerequisites
|
|
19
|
+
|
|
20
|
+
- **Python 3.12 or higher**
|
|
21
|
+
- A Spotify Developer account (get one at [developer.spotify.com](https://developer.spotify.com))
|
|
22
|
+
- Client ID and Client Secret from the Spotify Developer Dashboard
|
|
23
|
+
|
|
24
|
+
## 🔧 Installation
|
|
25
|
+
|
|
26
|
+
### From PyPI (Recommended)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Using uv (recommended)
|
|
30
|
+
uv add spotantic
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or using pip:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install spotantic
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### From Source
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/domagalasebastian/spotantic.git
|
|
43
|
+
cd spotantic
|
|
44
|
+
|
|
45
|
+
# Create venv and install dependencies
|
|
46
|
+
uv sync
|
|
47
|
+
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
48
|
+
|
|
49
|
+
# Install in development mode
|
|
50
|
+
uv sync --group dev
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 🚀 Quick Start
|
|
54
|
+
|
|
55
|
+
### 1. Configure Your Environment
|
|
56
|
+
|
|
57
|
+
Create a `.env` file in your project root with your Spotify credentials:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Your credentials from Spotify Developer Dashboard
|
|
61
|
+
SPOTANTIC_AUTH_CLIENT_ID=your_client_id_here
|
|
62
|
+
SPOTANTIC_AUTH_CLIENT_SECRET=your_client_secret_here
|
|
63
|
+
SPOTANTIC_AUTH_REDIRECT_URI=http://127.0.0.1:8000/callback
|
|
64
|
+
|
|
65
|
+
# Scopes you need (space-separated)
|
|
66
|
+
SPOTANTIC_AUTH_SCOPE=user-library-read user-library-modify
|
|
67
|
+
|
|
68
|
+
# Optional: where to store the access token cache
|
|
69
|
+
SPOTANTIC_AUTH_ACCESS_TOKEN_FILE_PATH=.token_info_cache
|
|
70
|
+
SPOTANTIC_AUTH_STORE_ACCESS_TOKEN=true
|
|
71
|
+
|
|
72
|
+
# Optional: logging configuration
|
|
73
|
+
SPOTANTIC_LOGGING_ENABLE=true
|
|
74
|
+
SPOTANTIC_LOGGING_DEBUG=false
|
|
75
|
+
SPOTANTIC_LOGGING_LOGS_DIR=logs/
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For more details on configuration options, see the [Quick Start Guide](https://spotantic.readthedocs.io/en/latest/quickstart.html).
|
|
79
|
+
|
|
80
|
+
### 2. Create a Client
|
|
81
|
+
|
|
82
|
+
Choose an authorization flow based on your use case:
|
|
83
|
+
|
|
84
|
+
#### Authorization Code PKCE Flow (Recommended for user-facing apps)
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
import asyncio
|
|
88
|
+
from spotantic.auth import AuthCodePKCEFlowManager
|
|
89
|
+
from spotantic.client import SpotanticClient
|
|
90
|
+
from spotantic.models.auth import AuthSettings
|
|
91
|
+
|
|
92
|
+
async def main():
|
|
93
|
+
# Load settings from .env file
|
|
94
|
+
auth_settings = AuthSettings()
|
|
95
|
+
|
|
96
|
+
# Create auth manager (browser opens automatically for authorization)
|
|
97
|
+
auth_manager = AuthCodePKCEFlowManager(
|
|
98
|
+
auth_settings=auth_settings,
|
|
99
|
+
allow_lazy_refresh=True
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Authorize user
|
|
103
|
+
await auth_manager.authorize()
|
|
104
|
+
|
|
105
|
+
# Create client
|
|
106
|
+
client = SpotanticClient(
|
|
107
|
+
auth_manager=auth_manager,
|
|
108
|
+
max_attempts=3,
|
|
109
|
+
check_insufficient_scope=True
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return client
|
|
113
|
+
|
|
114
|
+
# Run it
|
|
115
|
+
client = asyncio.run(main())
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Client Credentials Flow (For server-to-server requests)
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from spotantic.auth import ClientCredentialsFlowManager
|
|
122
|
+
from spotantic.client import SpotanticClient
|
|
123
|
+
from spotantic.models.auth import AuthSettings
|
|
124
|
+
|
|
125
|
+
async def main():
|
|
126
|
+
auth_settings = AuthSettings()
|
|
127
|
+
auth_manager = ClientCredentialsFlowManager(auth_settings=auth_settings)
|
|
128
|
+
await auth_manager.authorize()
|
|
129
|
+
|
|
130
|
+
return SpotanticClient(auth_manager=auth_manager)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
#### Standard Authorization Code Flow
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from spotantic.auth import AuthCodeFlowManager
|
|
137
|
+
from spotantic.client import SpotanticClient
|
|
138
|
+
from spotantic.models.auth import AuthSettings
|
|
139
|
+
|
|
140
|
+
async def main():
|
|
141
|
+
auth_settings = AuthSettings()
|
|
142
|
+
auth_manager = AuthCodeFlowManager(
|
|
143
|
+
auth_settings=auth_settings,
|
|
144
|
+
allow_lazy_refresh=True
|
|
145
|
+
)
|
|
146
|
+
await auth_manager.authorize()
|
|
147
|
+
|
|
148
|
+
return SpotanticClient(auth_manager=auth_manager)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 3. Make API Requests
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from spotantic.endpoints import albums, tracks
|
|
155
|
+
|
|
156
|
+
async def search_and_get_details(client):
|
|
157
|
+
# Get user's saved albums
|
|
158
|
+
saved_albums = await albums.get_user_saved_albums(client, limit=5)
|
|
159
|
+
|
|
160
|
+
# All responses are fully typed
|
|
161
|
+
for album in saved_albums.data.items:
|
|
162
|
+
print(f"Album: {album.album.album_name}")
|
|
163
|
+
print(f"Artist: {album.album.artists[0].artist_name}")
|
|
164
|
+
|
|
165
|
+
# Get details for a specific album
|
|
166
|
+
album_id = saved_albums.data.items[0].album.album_id
|
|
167
|
+
album_details = await albums.get_album(client, album_id=album_id)
|
|
168
|
+
|
|
169
|
+
print(f"Release Date: {album_details.data.release_date}")
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
For more examples, see the [examples](examples/) directory and [full documentation](https://spotantic.readthedocs.io/).
|
|
173
|
+
|
|
174
|
+
## 📚 Authorization Flows
|
|
175
|
+
|
|
176
|
+
Spotantic supports three Spotify authorization flows:
|
|
177
|
+
|
|
178
|
+
| Flow | Use Case | Refresh Token | Requires Secret |
|
|
179
|
+
|------|----------|---------------|-----------------|
|
|
180
|
+
| **Client Credentials** | Server-to-server, no user data | ❌ | ✅ |
|
|
181
|
+
| **Authorization Code** | Full user authorization, backendapps | ✅ | ✅ |
|
|
182
|
+
| **Authorization Code PKCE** | Browser/native apps | ✅ | ❌ |
|
|
183
|
+
|
|
184
|
+
**Important**: Spotantic only supports localhost redirect URIs. During authorization, the library temporarily hosts a local endpoint to complete the OAuth exchange.
|
|
185
|
+
|
|
186
|
+
See the [Authorization Guide](https://spotantic.readthedocs.io/en/latest/auth_reference.html) for detailed information.
|
|
187
|
+
|
|
188
|
+
## 🧪 Testing and Development
|
|
189
|
+
|
|
190
|
+
### Running Tests
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Run all unit tests
|
|
194
|
+
pytest tests/unit
|
|
195
|
+
|
|
196
|
+
# Run specific test directory
|
|
197
|
+
pytest tests/unit/endpoints/albums
|
|
198
|
+
|
|
199
|
+
# Run integration tests (requires valid token and network access)
|
|
200
|
+
pytest tests/integration
|
|
201
|
+
|
|
202
|
+
# Run only tests that do not affect user data
|
|
203
|
+
pytest tests/integration -m "readonly"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Code Quality Checks
|
|
207
|
+
|
|
208
|
+
Spotantic uses Ruff for linting and formatting. All contributions must pass these checks:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# Run pre-commit checks (linting, formatting, type checking)
|
|
212
|
+
uv run pre-commit run --all-files
|
|
213
|
+
|
|
214
|
+
# Or individually:
|
|
215
|
+
# Lint and auto-fix
|
|
216
|
+
uv run ruff check --fix .
|
|
217
|
+
|
|
218
|
+
# Format code
|
|
219
|
+
uv run ruff format .
|
|
220
|
+
|
|
221
|
+
# Type checking
|
|
222
|
+
pyright
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Building Documentation Locally
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
cd docs
|
|
229
|
+
uv run sphinx-build -b html source/ build/
|
|
230
|
+
# Documentation available at build/index.html (open in browser)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## 🤝 Contributing
|
|
234
|
+
|
|
235
|
+
Contributions are welcome! Please follow these guidelines:
|
|
236
|
+
|
|
237
|
+
1. **Code Style**: All code must pass Ruff linting and formatting checks. Run `pre-commit run --all-files` before submitting a PR.
|
|
238
|
+
|
|
239
|
+
2. **Type Checking**: Code must pass Pyright type checking (`pyright`).
|
|
240
|
+
|
|
241
|
+
3. **Testing**:
|
|
242
|
+
- Add tests for any new features
|
|
243
|
+
- Ensure all tests pass: `pytest tests/unit`
|
|
244
|
+
- Tests run on Python 3.12, 3.13, and 3.14
|
|
245
|
+
|
|
246
|
+
4. **Commit Style**: Follow [Conventional Commits](https://www.conventionalcommits.org/) format.
|
|
247
|
+
|
|
248
|
+
5. **Documentation**: Update relevant documentation for API changes.
|
|
249
|
+
|
|
250
|
+
### Development Workflow
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Setup development environment
|
|
254
|
+
uv sync --all-groups
|
|
255
|
+
|
|
256
|
+
# Activate virtual environment
|
|
257
|
+
source .venv/bin/activate
|
|
258
|
+
|
|
259
|
+
# Make your changes and run checks
|
|
260
|
+
uv run pre-commit run --all-files
|
|
261
|
+
pytest tests/unit
|
|
262
|
+
|
|
263
|
+
# Optionally, run integration tests (requires valid token and network access)
|
|
264
|
+
pytest tests/integration
|
|
265
|
+
|
|
266
|
+
# Build docs to verify they work
|
|
267
|
+
uv run sphinx-build -b html docs/source docs/build/
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## 📄 License
|
|
271
|
+
|
|
272
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
273
|
+
|
|
274
|
+
## ⚠️ Legal Disclaimer
|
|
275
|
+
|
|
276
|
+
**This project is not affiliated with, endorsed by, or associated with Spotify AB or any of its subsidiaries or affiliates.** Spotantic is an independent, community-maintained library that provides convenient access to the Spotify Web API. All Spotify trademarks, logos, and product names are the property of Spotify AB.
|
|
277
|
+
|
|
278
|
+
Please ensure your use of this library complies with [Spotify's Developer Terms of Service](https://developer.spotify.com/terms).
|
|
279
|
+
|
|
280
|
+
## 🔗 Resources
|
|
281
|
+
|
|
282
|
+
- **[Spotify Web API Documentation](https://developer.spotify.com/documentation/web-api/)**
|
|
283
|
+
- **[Project Documentation](https://spotantic.readthedocs.io/)**
|
|
284
|
+
- **[GitHub Repository](https://github.com/domagalasebastian/spotantic)**
|
|
285
|
+
- **[Examples](examples/)**
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
Made with ❤️ by [Sebastian Domagała](https://github.com/domagalasebastian)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "spotantic"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Sebastian Domagała"},
|
|
10
|
+
]
|
|
11
|
+
description = "Async Spotify API client"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.12"
|
|
14
|
+
keywords = ["spotify", "async", "api-client", "aiohttp"]
|
|
15
|
+
license="MIT"
|
|
16
|
+
license-files = ["LICENSE"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"aiohttp>=3.13.0",
|
|
26
|
+
"pydantic>=2.12.0",
|
|
27
|
+
"pydantic-settings>=2.11.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = [
|
|
32
|
+
"pre-commit>=4.5.1",
|
|
33
|
+
"pyright>=1.1.406",
|
|
34
|
+
"pytest>=9.0.2",
|
|
35
|
+
"pytest-asyncio>=1.3.0",
|
|
36
|
+
"ruff>=0.14.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
docs = [
|
|
40
|
+
"sphinx>=9.1.0",
|
|
41
|
+
"sphinx-autobuild>=2025.8.25",
|
|
42
|
+
"sphinx-rtd-theme>=3.1.0",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
"Homepage" = "https://github.com/domagalasebastian/spotantic"
|
|
47
|
+
"Documentation" = "https://spotantic.readthedocs.io"
|
|
48
|
+
"Bug Tracker" = "https://github.com/domagalasebastian/spotantic/issues"
|
|
49
|
+
"Questions" = "https://github.com/domagalasebastian/spotantic/discussions"
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build]
|
|
52
|
+
include = ["src/spotantic/py.typed"]
|
|
53
|
+
|
|
54
|
+
[tool.hatch.build.targets.wheel]
|
|
55
|
+
packages = ["src/spotantic"]
|
|
56
|
+
|
|
57
|
+
[tool.ruff]
|
|
58
|
+
line-length = 120
|
|
59
|
+
indent-width = 4
|
|
60
|
+
target-version = "py312"
|
|
61
|
+
|
|
62
|
+
[tool.ruff.lint]
|
|
63
|
+
select = ["E4", "E7", "E9", "F", "Q", "I", "RUF022"]
|
|
64
|
+
ignore = []
|
|
65
|
+
|
|
66
|
+
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
67
|
+
fixable = ["ALL"]
|
|
68
|
+
unfixable = []
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint.isort]
|
|
71
|
+
known-first-party = ["spotantic"]
|
|
72
|
+
force-single-line = true
|
|
73
|
+
|
|
74
|
+
[tool.ruff.lint.pydocstyle]
|
|
75
|
+
convention = "google"
|
|
76
|
+
|
|
77
|
+
[tool.ruff.format]
|
|
78
|
+
# Like Black, use double quotes for strings.
|
|
79
|
+
quote-style = "double"
|
|
80
|
+
|
|
81
|
+
# Like Black, indent with spaces, rather than tabs.
|
|
82
|
+
indent-style = "space"
|
|
83
|
+
|
|
84
|
+
# Like Black, respect magic trailing commas.
|
|
85
|
+
skip-magic-trailing-comma = false
|
|
86
|
+
|
|
87
|
+
# Like Black, automatically detect the appropriate line ending.
|
|
88
|
+
line-ending = "auto"
|
|
89
|
+
|
|
90
|
+
[tool.pyright]
|
|
91
|
+
exclude = ["**/__pycache__", ".venv", "**/node_modules", "**/.*"]
|
|
92
|
+
venvPath = "."
|
|
93
|
+
venv = ".venv"
|
|
94
|
+
|
|
95
|
+
[tool.pytest]
|
|
96
|
+
minversion = "9.0"
|
|
97
|
+
addopts = [
|
|
98
|
+
"-ra",
|
|
99
|
+
"--strict-markers",
|
|
100
|
+
"--import-mode=importlib",
|
|
101
|
+
]
|
|
102
|
+
testpaths = ["tests"]
|
|
103
|
+
asyncio_mode = "auto"
|
|
104
|
+
|
|
105
|
+
markers = [
|
|
106
|
+
"readonly: tests that do not modify data",
|
|
107
|
+
"mutation: tests that modify data (create/delete/update)",
|
|
108
|
+
"user_library: tests that are interactive with the user's Spotify library",
|
|
109
|
+
"requires_active_device: tests that require an active Spotify device",
|
|
110
|
+
"affects_playback: tests that affect playback (e.g., play/pause/skip)",
|
|
111
|
+
]
|
|
File without changes
|