More type-friendly paging API
This commit is contained in:
parent
9f5caa76f0
commit
a783edd3ac
@ -1,9 +1,9 @@
|
|||||||
"""
|
"""
|
||||||
Utility methods for the Spotify query API
|
Utility methods for the Spotify query API
|
||||||
"""
|
"""
|
||||||
from typing import Any, Dict, Iterable, cast
|
from typing import Iterable
|
||||||
|
|
||||||
from spotify_model.album import SearchAlbum
|
from spotify_model import Paging, SearchAlbum
|
||||||
from spotipy import Spotify
|
from spotipy import Spotify
|
||||||
|
|
||||||
from .util import exhaust
|
from .util import exhaust
|
||||||
@ -12,11 +12,8 @@ from .util import exhaust
|
|||||||
def search_album(client: Spotify, search_str: str) -> Iterable[SearchAlbum]:
|
def search_album(client: Spotify, search_str: str) -> Iterable[SearchAlbum]:
|
||||||
"Display albums from a search string"
|
"Display albums from a search string"
|
||||||
|
|
||||||
def _search(limit: int, offset: int) -> Dict[str, Any]:
|
def _search(limit: int, offset: int) -> Paging:
|
||||||
return cast(
|
return Paging(**client.search(search_str, limit=limit, offset=offset, type="album")["albums"])
|
||||||
Dict[str, Any],
|
|
||||||
client.search(search_str, limit=limit, offset=offset, type="album")["albums"],
|
|
||||||
)
|
|
||||||
|
|
||||||
for item in exhaust(_search):
|
for item in exhaust(_search):
|
||||||
yield SearchAlbum(**item)
|
yield SearchAlbum(**item)
|
||||||
|
@ -6,6 +6,7 @@ from pathlib import Path
|
|||||||
from typing import Any, Dict, Iterable, Protocol
|
from typing import Any, Dict, Iterable, Protocol
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
from spotify_model import Paging
|
||||||
from spotipy import Spotify, SpotifyClientCredentials
|
from spotipy import Spotify, SpotifyClientCredentials
|
||||||
|
|
||||||
DEFAULT_LIMIT = 50
|
DEFAULT_LIMIT = 50
|
||||||
@ -23,20 +24,18 @@ def read_credentials(path: Path) -> Spotify:
|
|||||||
class Paginated(Protocol):
|
class Paginated(Protocol):
|
||||||
"Protocol definition for functions that will be provided to the `exhaust` handler"
|
"Protocol definition for functions that will be provided to the `exhaust` handler"
|
||||||
|
|
||||||
def __call__(self, limit: int, offset: int) -> Dict[str, Any]:
|
def __call__(self, limit: int, offset: int) -> Paging:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
def exhaust(function: Paginated, limit: int = DEFAULT_LIMIT) -> Iterable[Dict[str, Any]]:
|
def exhaust(function: Paginated, limit: int = DEFAULT_LIMIT) -> Iterable[Dict[str, Any]]:
|
||||||
"Exhaust a function that returns a pagination object"
|
"Exhaust a function that returns a pagination object"
|
||||||
response = function(limit=limit, offset=0)
|
response = function(limit=limit, offset=0)
|
||||||
total = response["total"]
|
|
||||||
limit = response["limit"]
|
|
||||||
|
|
||||||
for item in response["items"]:
|
for item in response.items:
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
for i in range(1, ceil(total / limit)):
|
for i in range(1, ceil(response.total / limit)):
|
||||||
response = function(limit=limit, offset=limit * i)
|
response = function(limit=response.limit, offset=response.limit * i)
|
||||||
for item in response["items"]:
|
for item in response.items:
|
||||||
yield item
|
yield item
|
||||||
|
Loading…
Reference in New Issue
Block a user