Skip to content

Commit 1126c67

Browse files
authored
Add support for fetching categories (#322)
1 parent 2747ab6 commit 1126c67

5 files changed

Lines changed: 539 additions & 0 deletions

File tree

src/spotifyaio/models.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,20 @@ class CategoryPlaylistResponse(DataClassORJSONMixin):
398398
playlists: PlaylistResponse
399399

400400

401+
@dataclass
402+
class CategoriesResponse(DataClassORJSONMixin):
403+
"""Categories response model."""
404+
405+
categories: CategoriesResponseInner
406+
407+
408+
@dataclass
409+
class CategoriesResponseInner(DataClassORJSONMixin):
410+
"""Categories response model."""
411+
412+
items: list[Category]
413+
414+
401415
@dataclass
402416
class Category(DataClassORJSONMixin):
403417
"""Category model."""

src/spotifyaio/spotify.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ArtistResponse,
1919
BasePlaylist,
2020
BaseUserProfile,
21+
CategoriesResponse,
2122
Category,
2223
CategoryPlaylistResponse,
2324
CurrentPlaying,
@@ -295,6 +296,12 @@ async def get_category(self, category_id: str) -> Category:
295296
response = await self._get(f"v1/browse/categories/{category_id}")
296297
return Category.from_json(response)
297298

299+
async def get_categories(self) -> list[Category]:
300+
"""Get category."""
301+
params: dict[str, Any] = {"limit": 48}
302+
response = await self._get("v1/browse/categories", params=params)
303+
return CategoriesResponse.from_json(response).categories.items
304+
298305
async def get_saved_albums(self) -> list[SavedAlbum]:
299306
"""Get saved albums."""
300307
params: dict[str, Any] = {"limit": 48}

tests/__snapshots__/test_spotify.ambr

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,250 @@
10691069
}),
10701070
])
10711071
# ---
1072+
# name: test_get_categories
1073+
list([
1074+
dict({
1075+
'category_id': '0JQ5DAt0tbjZptfcdMSKl3',
1076+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAt0tbjZptfcdMSKl3',
1077+
'icons': list([
1078+
dict({
1079+
'height': 274,
1080+
'url': 'https://t.scdn.co/images/728ed47fc1674feb95f7ac20236eb6d7.jpeg',
1081+
'width': 274,
1082+
}),
1083+
]),
1084+
'name': 'Made For You',
1085+
}),
1086+
dict({
1087+
'category_id': '0JQ5DAqbMKFz6FAsUtgAab',
1088+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFz6FAsUtgAab',
1089+
'icons': list([
1090+
dict({
1091+
'height': 274,
1092+
'url': 'https://t.scdn.co/images/728ed47fc1674feb95f7ac20236eb6d7.jpeg',
1093+
'width': 274,
1094+
}),
1095+
]),
1096+
'name': 'New Releases',
1097+
}),
1098+
dict({
1099+
'category_id': '0JQ5DAqbMKFEC4WFtoNRpw',
1100+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFEC4WFtoNRpw',
1101+
'icons': list([
1102+
dict({
1103+
'height': 274,
1104+
'url': 'https://t.scdn.co/media/derived/pop-274x274_447148649685019f5e2a03a39e78ba52_0_0_274_274.jpg',
1105+
'width': 274,
1106+
}),
1107+
]),
1108+
'name': 'Pop',
1109+
}),
1110+
dict({
1111+
'category_id': '0JQ5DAqbMKFQ00XGBls6ym',
1112+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFQ00XGBls6ym',
1113+
'icons': list([
1114+
dict({
1115+
'height': 274,
1116+
'url': 'https://t.scdn.co/images/728ed47fc1674feb95f7ac20236eb6d7.jpeg',
1117+
'width': 274,
1118+
}),
1119+
]),
1120+
'name': 'Hip-Hop',
1121+
}),
1122+
dict({
1123+
'category_id': '0JQ5DAqbMKFHOzuVTgTizF',
1124+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFHOzuVTgTizF',
1125+
'icons': list([
1126+
dict({
1127+
'height': 274,
1128+
'url': 'https://t.scdn.co/media/derived/edm-274x274_0ef612604200a9c14995432994455a6d_0_0_274_274.jpg',
1129+
'width': 274,
1130+
}),
1131+
]),
1132+
'name': 'Dance/Electronic',
1133+
}),
1134+
dict({
1135+
'category_id': '0JQ5DAqbMKFCLroFGPFVr5',
1136+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFCLroFGPFVr5',
1137+
'icons': list([
1138+
dict({
1139+
'height': 274,
1140+
'url': 'https://t.scdn.co/images/970c289306e64c8782ecc84de5dea795.jpeg',
1141+
'width': 274,
1142+
}),
1143+
]),
1144+
'name': 'Dutch music',
1145+
}),
1146+
dict({
1147+
'category_id': '0JQ5DAudkNjCgYMM0TZXDw',
1148+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAudkNjCgYMM0TZXDw',
1149+
'icons': list([
1150+
dict({
1151+
'height': 274,
1152+
'url': 'https://charts-images.scdn.co/spotify-charts-logos/music_charts_search_arrow_274x274.jpeg',
1153+
'width': 274,
1154+
}),
1155+
]),
1156+
'name': 'Charts',
1157+
}),
1158+
dict({
1159+
'category_id': '0JQ5DAqbMKFzHmL4tf05da',
1160+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFzHmL4tf05da',
1161+
'icons': list([
1162+
dict({
1163+
'height': 274,
1164+
'url': 'https://t.scdn.co/media/original/mood-274x274_976986a31ac8c49794cbdc7246fd5ad7_274x274.jpg',
1165+
'width': 274,
1166+
}),
1167+
]),
1168+
'name': 'Mood',
1169+
}),
1170+
dict({
1171+
'category_id': '0JQ5DAqbMKFCWjUTdzaG0e',
1172+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFCWjUTdzaG0e',
1173+
'icons': list([
1174+
dict({
1175+
'height': 274,
1176+
'url': 'https://t.scdn.co/images/fe06caf056474bc58862591cd60b57fc.jpeg',
1177+
'width': 274,
1178+
}),
1179+
]),
1180+
'name': 'Indie',
1181+
}),
1182+
dict({
1183+
'category_id': '0JQ5DAqbMKFIRybaNTYXXy',
1184+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFIRybaNTYXXy',
1185+
'icons': list([
1186+
dict({
1187+
'height': 274,
1188+
'url': 'https://t.scdn.co/images/728ed47fc1674feb95f7ac20236eb6d7.jpeg',
1189+
'width': 274,
1190+
}),
1191+
]),
1192+
'name': 'In the car',
1193+
}),
1194+
dict({
1195+
'category_id': '0JQ5DAqbMKFEZPnFQSFB1T',
1196+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFEZPnFQSFB1T',
1197+
'icons': list([
1198+
dict({
1199+
'height': 274,
1200+
'url': 'https://t.scdn.co/media/derived/r-b-274x274_fd56efa72f4f63764b011b68121581d8_0_0_274_274.jpg',
1201+
'width': 274,
1202+
}),
1203+
]),
1204+
'name': 'R&B',
1205+
}),
1206+
dict({
1207+
'category_id': '0JQ5DAtOnAEpjOgUKwXyxj',
1208+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAtOnAEpjOgUKwXyxj',
1209+
'icons': list([
1210+
dict({
1211+
'height': 274,
1212+
'url': 'https://t.scdn.co/images/728ed47fc1674feb95f7ac20236eb6d7.jpeg',
1213+
'width': 274,
1214+
}),
1215+
]),
1216+
'name': 'Discover',
1217+
}),
1218+
dict({
1219+
'category_id': '0JQ5DAqbMKFA6SOHvT3gck',
1220+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFA6SOHvT3gck',
1221+
'icons': list([
1222+
dict({
1223+
'height': 274,
1224+
'url': 'https://t.scdn.co/images/7ee6530d5b3c4acc9a0957046bf11d63',
1225+
'width': 274,
1226+
}),
1227+
]),
1228+
'name': 'Party',
1229+
}),
1230+
dict({
1231+
'category_id': '0JQ5DAqbMKFAXlCG6QvYQ4',
1232+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFAXlCG6QvYQ4',
1233+
'icons': list([
1234+
dict({
1235+
'height': 274,
1236+
'url': 'https://t.scdn.co/media/links/workout-274x274.png',
1237+
'width': 274,
1238+
}),
1239+
]),
1240+
'name': 'Workout',
1241+
}),
1242+
dict({
1243+
'category_id': '0JQ5DAqbMKFGnsSfvg90Wo',
1244+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFGnsSfvg90Wo',
1245+
'icons': list([
1246+
dict({
1247+
'height': 274,
1248+
'url': 'https://t.scdn.co/images/c5495b9f0f694ffcb39c9217d4ed4375',
1249+
'width': 274,
1250+
}),
1251+
]),
1252+
'name': 'GLOW',
1253+
}),
1254+
dict({
1255+
'category_id': '0JQ5DAqbMKFNQ0fGp4byGU',
1256+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFNQ0fGp4byGU',
1257+
'icons': list([
1258+
dict({
1259+
'height': 274,
1260+
'url': 'https://t.scdn.co/images/b505b01bbe0e490cbe43b07f16212892.jpeg',
1261+
'width': 274,
1262+
}),
1263+
]),
1264+
'name': 'Afro',
1265+
}),
1266+
dict({
1267+
'category_id': '0JQ5DAqbMKFGvOw3O4nLAf',
1268+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFGvOw3O4nLAf',
1269+
'icons': list([
1270+
dict({
1271+
'height': 274,
1272+
'url': 'https://t.scdn.co/images/2078afd91e4d431eb19efc5bee5ab131.jpeg',
1273+
'width': 274,
1274+
}),
1275+
]),
1276+
'name': 'K-pop',
1277+
}),
1278+
dict({
1279+
'category_id': '0JQ5DAqbMKFIpEuaCnimBj',
1280+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFIpEuaCnimBj',
1281+
'icons': list([
1282+
dict({
1283+
'height': 274,
1284+
'url': 'https://t.scdn.co/media/derived/soul-274x274_266bc900b35dda8956380cffc73a4d8c_0_0_274_274.jpg',
1285+
'width': 274,
1286+
}),
1287+
]),
1288+
'name': 'Soul',
1289+
}),
1290+
dict({
1291+
'category_id': '0JQ5DAqbMKFFzDl7qN9Apr',
1292+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFFzDl7qN9Apr',
1293+
'icons': list([
1294+
dict({
1295+
'height': 274,
1296+
'url': 'https://t.scdn.co/media/derived/chill-274x274_4c46374f007813dd10b37e8d8fd35b4b_0_0_274_274.jpg',
1297+
'width': 274,
1298+
}),
1299+
]),
1300+
'name': 'Chill',
1301+
}),
1302+
dict({
1303+
'category_id': '0JQ5DAqbMKFDXXwE9BDJAr',
1304+
'href': 'https://api.spotify.com/v1/browse/categories/0JQ5DAqbMKFDXXwE9BDJAr',
1305+
'icons': list([
1306+
dict({
1307+
'height': 274,
1308+
'url': 'https://t.scdn.co/media/derived/rock_9ce79e0a4ef901bbd10494f5b855d3cc_0_0_274_274.jpg',
1309+
'width': 274,
1310+
}),
1311+
]),
1312+
'name': 'Rock',
1313+
}),
1314+
])
1315+
# ---
10721316
# name: test_get_category
10731317
dict({
10741318
'category_id': '0JQ5DAqbMKFRY5ok2pxXJ0',

0 commit comments

Comments
 (0)