Welcome to the online documentation of Tekore! We provide a client for the Spotify Web API for Python, complete with all available endpoints and authentication methods, async support and loads of additional features. Tekore allows you to interact with the API effortlessly. Here’s five lines to get you full access and start playing your top songs.
import tekore as tk
conf = (client_id, client_secret, redirect_uri)
token = tk.prompt_for_user_token(*conf, scope=tk.scope.every)
spotify = tk.Spotify(token)
tracks = spotify.current_user_top_tracks(limit=10)
spotify.playback_start_tracks([t.id for t in tracks.items])
See our homepage on PyPI for more information about the package and its versions. If you’ve found a bug or would like to propose a feature, please submit an issue on GitHub. Join our Discord community to ask for help or discuss just about anything related to Tekore. You can also ask a question on Stack Overflow.
If you’re new here, have a look at Getting started. Example scripts can be found in Examples. Detailed information is available in our concise Reference.
Features
The Web API provides access to a plethora of data on music and users. Tekore implements these integral features completely.
Authorisation for applications and users.
Endpoints for access to every resource in the API.
Additional features are provided for your convenience.
Support for asynchronous programming using
async/await
.A self-refreshing access token.
Responses are parsed into models with explicit attributes. They have a readable
repr
and can be serialised back to JSON.Senders, a hook between Tekore and the Web API. Enables retries on failed requests, response caching and session persistence.
Access rights for user tokens.
Conversions between Spotify IDs, URIs and URLs.
Read and write configuration from files and environment variables.
Release notes
Unreleased
Fixed
Make
available_markets
ofShow
,LocalAlbum
andLocalTrack
optional (#323)
5.4.0 (2024-02-27)
Fixed
Add
ep
as a valid enum toAlbumType
for top tracks API responses (#318)Add undocumented
smart_shuffle
toCurrentlyPlayingContext
(#320)
Added
Support HTTPX
0.27
(#317)
5.3.1 (2024-01-28)
Fixed
5.3.0 (2023-12-22)
Fixed
Make
images
optional inPlaylist
to fix getting empty playlists without an image (#309)Make
is_playable
inEpisode
optional despite API specifications (#310)Make deprecated
language
optional inEpisode
pending removal (#310)Add undocumented
dict
to types ofduration_ms
inLocalTrack
(#310)Add undocumented
available_markets
toFullPlaylistEpisode
(#310)
Added
Add
restrictions
toFullEpisode
(#310)Support HTTPX
0.26
(#311)Improve
UnknownModelAttributeWarning
to include model name (#313)
5.2.1 (2023-11-22)
Fixed
Exclude Pydantic versions
2.5.0
and2.5.1
(#306)Add missing
available_markets
toFullChapter
(#308)
5.2.0 (2023-11-05)
Fixed
Added
Add support for short URLs as
is_short_link()
andfollow_short_link
(#301)
5.1.1 (2023-10-14)
Fixed
5.1.0 (2023-10-04)
Added
Support HTTPX
0.25
(#294)
Fixed
5.0.1 (2023-07-06)
Fixed
Add missing
Optional
annotations to support Pydantic 2 (#293)
5.0.0 (2023-06-18)
Tekore 5 comes with an overhauled response model system based on Pydantic. Although the underlying change is major, the primary usage of models remains unchanged. The new models are more robust and easier to maintain. However, with more careful data validation new issues may arise. Please submit them on GitHub.
Changed
Remove support for Python 3.7 (EOL) (#292)
Use Pydantic in response models (#279)
Many type hints are fixed and improved.
Instead of retaining unknown response attributes, they are now discarded. However, the same warning message is raised.
.json
and.asbuiltin
methods are replaced by Pydantic models’.json
and.dict
.Models use the builtin
datetime
object directly..pprint
and custom__repr__
are removed in favor of using Pydantic’s own machinery.The builtin list class is used everywhere instead of the old
ModelList
.
4.6.1 (2023-05-25)
Fixed
4.6.0 (2023-04-12)
Added
Fixed
FullChapter
/SimpleChapter
- change “restriction” to “restrictions” (#286)
4.5.0 (2022-11-06)
Added
Errors - carry scope information with
Unauthorised
(#276)Client - add new audiobook (Audiobook API) and chapter Chapter API endpoints and “audiobook” as a valid search type. Note that audiobooks are currently only available in the US market. The APIs also seem to be unreliable. (#277)
Client - add new get queue endpoint
playback_queue
. Queue results seem inconsistent at this time. (#278)
Fixed
4.4.1 (2022-10-08)
Fixed
Handle changed response to fix paging at search limit (#275)
4.4.0 (2022-05-24)
Added
4.3.0 (2022-03-11)
Added
Dependency to HTTPX upgraded to include version
0.22.*
(#267)Expose the underlying credentials manager in
RefreshingCredentials
andRefreshingToken
to facilitate closing their HTTP client, which is no longer closed by default as of HTTPX version0.22
(#267)
Fixed
Add missing context “collection” to
ContextType
for playing saved tracks (#270)
4.2.0 (2022-01-19)
Added
Conversions - add
user
as a valid ID type and URL-encode hashes of user IDs into_url()
(#266)
Fixed
4.1.0 (2021-11-20)
4.0.0 (2021-09-09)
Tekore 4.0 is a maintenance release to prepare for the nearly deprecated Python 3.6, update dependencies and improve backwards compatibility.
Changed
Added
Improved documentation for type hints and response models (#109)
Responses can now parse unknown attributes, greatly improving backwards compatibility.
UnknownModelAttributeWarning
was introduced (#247)
3.7.1 (2021-05-04)
Fixed
Models - add missing but undocumented
html_description
field toFullShow
andSimpleShow
(#251)Models - require the newly documented
html_description
field inFullEpisode
andSimpleEpisode
(#251)
3.7.0 (2021-04-08)
Added
Client - add episode endpoints to library API, and the corresponding
SavedEpisode
andSavedEpisodePaging
models (#249)
3.6.2 (2021-03-23)
Fixed
Models - add missing but undocumented
html_description
field toFullEpisode
andSimpleEpisode
(#246)
3.6.1 (2021-03-07)
Fixed
Authorisation - allow missing scope in token responses and parse it to an empty
Scope
(#245)
3.6.0 (2021-03-02)
Added
3.5.1 (2021-02-12)
Fixed
3.5.0 (2021-01-15)
Added
Authorisation - add
streaming
andapp-remote-control
as extra scopes (#237)
Fixed
3.4.2 (2020-12-14)
Fixed
3.4.1 (2020-12-04)
Fixed
Client - document the need for at least one seed in
recommendations
(#229)
3.4.0 (2020-11-24)
Added
Conversions - ignore URL parameters in
from_url()
(#226)Conversions -
from_uri()
,from_url()
raise proper errors with entirely invalid formats, error messages were improved (#227)
Fixed
3.3.0 (2020-10-22)
Added
Configuration - warning messages for missing configuration now include the variable name which was missing (#222)
Models - improved type hints and documentation of potentially missing values (#221)
Fixed
3.2.0 (2020-10-16)
Added
Support Python 3.9 (#219)
Dependency to HTTPX upgraded to include versions
0.15.*
and0.16.*
(#216)Error messages for
parse_code_from_url()
,parse_state_from_url()
andCredentials.pkce_user_authorisation()
were improved (#218)Spotify
and Senders, both synchronous and asynchronous, can now be closed directly withclose
(#220)
3.1.0 (2020-09-13)
Added
Fixed
PrivateUser
- a birthday attribute was added. It is not obtainable with new tokens but is returned for old tokens that have the now-invaliduser-read-birthday
scope (#52, #197)
3.0.1 (2020-09-05)
Fixed
featured_playlists
- allow missing owner inPlaylist
models (#212)
3.0.0 (2020-09-03)
The next major iteration of Tekore brings fewer breaking changes than in 2.0, but packs a number of improvements to authorisation and senders. Most notably, PKCE is now provided as an option for user authorisation and Requests is no longer used to perform web requests. HTTPX, which was already in use with async, is used exclusively instead.
Added
Authorisation - PKCE can be used in user authorisation, providing added security for public clients by removing the need to use a client secret. (#189)
UserAuth
- implement user authorisation with security checks, the caller simply provides the resulting URI after redirection (#207)Senders - Tekore’s own
Request
andResponse
wrappers are now used in the sender interface (#139)Classes now have a readable
repr
(#191)Dependency to HTTPX upgraded to include version
0.14.*
(#202)gen_state()
- generate state for user authorisation (#207)parse_state_from_url()
- parse state from URL parameters (#207)
Removed
Playlist API - methods for playlist tracks and
episodes_as_tracks
argument ofSpotify.playlist()
deprecated in 2.0 (#178, #202)Dependency to Requests dropped in favor of HTTPX (#139)
Senders -
TransientSender
andSingletonSender
along with their asynchronous variants were removed (#139)Senders - default sender and keyword argument options were removed (#139)
Changed
Errors - web exceptions now inherit from
Exception
rather than the underlying HTTP library’s top-level exception. They always contain the relevantRequest
andResponse
(#139)Senders - as the only concrete senders,
PersistentSender
andAsyncPersistentSender
are now implemented inSyncSender
andAsyncSender
, respectively (#139)CachingSender
- argument order is now in line withRetryingSender
(#139)Senders - clients (
Spotify
andCredentials
) now inherit fromExtendingSender
(#139)Authorisation - raise a more descriptive error if secret is required but not provided (#210)
Fixed
2.1.3 (2020-08-04)
Fixed
Client - correctly return
ModelList
when chunking input (#196)Authorisation - fix error handling when response does not contain an error description (#199)
playback
andplayback_currently_playing
- correctly handle local tracks (#200)
2.1.2 (2020-07-21)
Fixed
FullShow
- add undocumentedtotal_episodes
parameter, marktotal_episodes
ofSimpleShow
undocumented (#194)
2.1.1 (2020-07-02)
Fixed
SimpleShow
- add optionaltotal_episodes
parameter (#190)
2.1.0 (2020-05-31)
Added
Fixed
Errors - correctly fall back to
ClientError
andServerError
when encountering an unknown status code (#185)
2.0.0 (2020-05-27)
This release significantly improves the overall structure of the library and provides quality of life enhancements to various tasks. Most notably, submodules were removed in favor of a flat structure. Everything is now imported from the top level with the exception of Models.
Removed
Importing from submodules (#81)
OAuthError
in Authorisation - see below for details (#154)
Deprecated
Playlist API - methods specifically for playlist tracks and
episodes_as_tracks
argument ofSpotify.playlist()
(#178)
Added
Authorisation - a list of
scopes
and strings is accepted in scope arguments (#81)Scope
operations were expanded to properly handle all combinations ofstr
,scope
andScope
(#177)Playlist API - new methods to fully support episodes in playlists. The new endpoints are direct counterparts to
playlist_tracks_*
methods. (#178)
Changed
Import structure
Submodules were removed in favor of a flat structure. In addition to simply relocating objects, some changes were made as well. (#81)
Options for Senders and Configuration are now set at the top level
AuthorisationScopes
was renamed toscope
, and its alias scopes is no longer availableReady-made scopes read, write and every are now accessed via the
scope
enumeration
Response models
These changes aim to make Models consistent and serialisation clear. (#149)
The JSON encoder used internally was made private
Hierarchies and names of model base classes and member types changed
Instead of using
str
, models are now converted to JSON using theirjson
methodAs a result of the change above, the
repr
of models can be viewed simply withprint
. Therepr
of model lists was significantly improved. Viewing attributes of models produces consistent results.The
asbuiltin
method replacesasdict()
for models and was also added for lists of models. Enumerations and timestamps are no longer preserved in the conversion.pprint
output is now compact by default
Playlist items
Boolean attributes of FullTrack
and
FullEpisode
on a playlist were previously also
available elsewhere, but had None
values. They were removed.
The booleans are still available in playlist-related calls with the new
FullPlaylistTrack
and
FullPlaylistEpisode
.
LocalPlaylistTrack
now also provides
these booleans. (#170)
Miscellaneous
Exceptions thrown in Authorisation now match Client. Because of that,
OAuthError
was removed. Errors now inherit from a common base class. (#154)Token.scope
andRefreshingToken.scope
now return aScope
instead of a string. (#177)Default sender changed from
TransientSender
toPersistentSender
, also affectsClient
behavior (#141)
Fixed
Properly close sessions in
PersistentSender
(#179)Members of
AlbumGroup
are now strings as intended, rather than one-element tuples (#181)Include readme to source distributions to fix setup (#182)
1.7.0 (2020-04-28)
Added
Most imports can be done directly at the top level (#174)
Deprecated
Importing from submodules, removed in Tekore 2.0 (#81)
Fixed
recommendations
documentation changed to reflect that only IDs are accepted as seeds, not URIs or URLs (#173)track_audio_analysis
allow for missing attributes in analysis (#175)
1.6.0 (2020-04-07)
Added
Client - Support for podcasts. New APIs for episodes and shows. New
scope
user-read-playback-position
for returning episode resume points. New endpoints for saving shows in a user’s library.playback_queue_add
now accepts episodes.playback
andplayback_currently_playing
can return currently playing episodes and shows.playlist
andplaylist_tracks
can return episodes on playlists.search
allows for searching episodes and shows. (#164)Dependency to HTTPX upgraded to include version
0.12.*
(#166)
Fixed
Errors are now correctly raised when parsing responses in
playlist
andplaylist_tracks
(#164)Conversions
to_url()
now return URLs with prefixhttps
instead ofhttp
, in line with API and application behavior.from_url()
now correctly acceptshttps
addresses for conversion. (#165)Models - The
repr
of local items can now be produced without errors (#171)
1.5.0 (2020-03-11)
Added
RetryingSender
- avoid unnecessary retries and reduce total wait time (#163)
Fixed
category_playlists
require category parameter (#160)AsyncPersistentSender
- persist connections appropriately (#161)playback_queue_add
match endpoint address to changed API (#162)
1.4.0 (2020-03-02)
Added
playlist_tracks_clear
- convenience endpoint for deleting tracks from a playlist (#155)Conversions - accept shows and episodes as valid types (#159)
Fixed
playlist_tracks_add
- insert tracks in correct order when chunking (#156)
1.3.0 (2020-02-26)
Added
playback_queue_add
- add tracks to queue (#152)CachingSender
- option to specify maximum cache size (#143)Client - optionally send long lists of resources as chunks circumventing API limits (#153)
1.2.0 (2020-02-17)
Added
Fixed
Paging navigation - respect API limits when retrieving all items or pages of a
search
(#145)Paging navigation - always return an awaitable when asynchronous (#146)
1.1.0 (2020-02-02)
Added
Async support in authentication and API endpoints (#131)
CachingSender
- a sender for response caching (#4)Configuration - reading missing values produces a warning (0fa61801)
Fixed
1.0.1 (2020-01-17)
Fixed
PlaylistTrack
- accept missing video thumbnail (#132)
1.0.0 (2020-01-14)
Packaging improvements
Declare versioning scheme
0.1.0 (2020-01-14)
Initial release of Tekore!
Reference
All public objects are documented in these sections.
Web API authorisation |
|
Web API endpoints |
|
Import and export credentials |
|
Convert IDs, URIs and URLs |
|
Web errors for clients |
|
Response models |
|
Request senders |
Client
Web API endpoints.
API summary |
|
---|---|
Album information |
|
Artist information |
|
Audiobook information |
|
Spotify featured catalogue |
|
Chapter information |
|
Episode information |
|
Follow artists, playlists and users |
|
Save (like) albums, shows and tracks |
|
Spotify market information |
|
User top listens |
|
Playback operations |
|
Playlist operations |
|
Search functionality |
|
Show information |
|
Track information and analysis |
|
User information |
Each method of the client corresponds to an API call, with some exceptions. Further documentation on endpoints can be viewed in the Web API reference.
import tekore as tk
# Initialise the client
spotify = tk.Spotify(token)
# Call the API
album = spotify.album('3RBULTZJ97bvVzZLpxcB0j')
for track in album.tracks.items:
print(track.track_number, track.name)
Required and optional scopes to call any endpoint can be determined in code.
Endpoints provide required_scope
and optional_scope
attributes which return a Scope
.
A combination of the two is provided in scope
.
They can be accessed via the class itself or its instances.
scope_cls = tk.Spotify.current_user_top_tracks.scope
scope_inst = tk.Spotify().current_user_top_tracks.scope
assert scope_cls == scope_inst
- class tekore.Spotify(token=None, sender=None, asynchronous=None, max_limits_on=False, chunked_on=False)
Bases:
tekore.Client
.Client to Web API endpoints.
- Parameters:
token – bearer token for requests
sender (Sender) – request sender
asynchronous (bool) – synchronicity requirement
max_limits_on (bool) – use maximum limits in paging calls, overrided by endpoint arguments
chunked_on (bool) – use chunking when requesting lists of resources
- token
bearer token for requests
- sender
underlying sender
- max_limits_on
use maximum limits in paging calls, overrided by endpoint arguments
- chunked_on
use chunking when requesting lists of resources
Non-endpoint methods
Toggle chunking lists of resources. |
|
Toggle using maximum limits in paging calls. |
|
Use a different token with requests. |
|
Follow redirect of a short link to get the underlying resource URL. |
|
Determine if URL is a Spotify short link. |
|
Build request url and headers, and send with underlying sender. |
|
Close the underlying sender. |
- Spotify.chunked(on=True)
Toggle chunking lists of resources. Context manager, async safe.
- Parameters:
on (bool) – enable or disable chunking
- Returns:
self as context
- Return type:
Generator[Spotify, None, None]
Examples
spotify = Spotify(token) with spotify.chunked(True): tracks = spotify.tracks(many_ids) spotify = Spotify(token, chunked_on=True) with spotify.chunked(False): tracks = spotify.search(many_ids[:50])
- Spotify.max_limits(on=True)
Toggle using maximum limits in paging calls. Context manager, async safe.
- Parameters:
on (bool) – enable or disable using maximum limits
- Returns:
self as context
- Return type:
Generator[Spotify, None, None]
Examples
spotify = Spotify(token) with spotify.max_limits(True): tracks, = spotify.search('piano') spotify = Spotify(token, max_limits_on=True) with spotify.max_limits(False): tracks, = spotify.search('piano')
- Spotify.token_as(token)
Use a different token with requests. Context manager, async safe.
- Parameters:
token – access token
- Returns:
self as context
- Return type:
Generator[Spotify, None, None]
Examples
spotify = Spotify() with spotify.token_as(token): album = spotify.album(album_id) spotify = Spotify(app_token) with spotify.token_as(user_token): user = spotify.current_user()
- Spotify.follow_short_link(link)
Follow redirect of a short link to get the underlying resource URL.
Safely also accept a direct link, request a redirect and return the original URL. Also use the underlying sender for an unauthenticated request.
- Returns:
result of the short link redirect
- Return type:
url
- Parameters:
link (str) –
- tekore.is_short_link(url)
Determine if URL is a Spotify short link.
- Parameters:
url (str) –
- Return type:
bool
- Spotify.send(request)
Build request url and headers, and send with underlying sender.
Exposed to easily send arbitrary requests, for custom behavior in some endpoint e.g. for a subclass. It may also come in handy if a bugfix or a feature is not implemented in a timely manner, or in debugging related to the client or Web API.
Album API
Get an album. |
|
Get tracks on album. |
|
Get multiple albums. |
- Spotify.album(album_id, market=None)
Get an album.
- Parameters:
album_id (str) – album ID
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
- Return type:
- Spotify.album_tracks(album_id, market=None, limit=20, offset=0)
Get tracks on album.
- Parameters:
album_id (str) – album ID
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
Artist API
Get information for an artist. |
|
Get an artist's albums. |
|
Get artists similar to an identified artist. |
|
Get an artist's top 10 tracks by country. |
|
Get information for multiple artists. |
- Spotify.artist(artist_id)
Get information for an artist.
- Parameters:
artist_id (str) – artist ID
- Return type:
- Spotify.artist_albums(artist_id, include_groups=None, market=None, limit=20, offset=0)
Get an artist’s albums.
- Parameters:
artist_id (str) – the artist ID
include_groups (List[str | AlbumGroup]) – album groups to include in the response
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
Get artists similar to an identified artist.
Similarity is based on analysis of the Spotify community’s listening history.
- Parameters:
artist_id (str) – artist ID
- Return type:
List[FullArtist]
- Spotify.artist_top_tracks(artist_id, market)
Get an artist’s top 10 tracks by country.
- Parameters:
artist_id (str) – the artist ID
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
- Return type:
List[FullTrack]
- Spotify.artists(artist_ids)
Get information for multiple artists.
- Parameters:
artist_ids (list) – list of artist IDs, max 50 without chunking
- Return type:
List[FullArtist]
Audiobook API
Get information for an audiobook. |
|
Get chapters of an audiobook. |
|
Get information for multiple audiobooks. |
- Spotify.audiobook(audiobook_id, market=None)
Get information for an audiobook.
- Parameters:
audiobook_id (str) – audiobook ID
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the show is considered unavailable.
- Return type:
- Spotify.audiobook_chapters(audiobook_id, market=None, limit=20, offset=0)
Get chapters of an audiobook.
- Parameters:
audiobook_id (str) – audiobook ID
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the show is considered unavailable.
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.audiobooks(audiobook_ids, market=None)
Get information for multiple audiobooks.
- Parameters:
audiobook_ids (list) – the audiobook IDs, max 50 without chunking
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the show is considered unavailable.
- Return type:
List[FullAudiobook]
Browse API
Get a list of categories used to tag items in Spotify. |
|
Get a single category used to tag items in Spotify. |
|
Get a list of Spotify playlists tagged with a particular category. |
|
Get a list of Spotify featured playlists. |
|
Get a list of new album releases featured in Spotify. |
|
Get a list of available genre seeds. |
|
Get a list of recommended tracks for seeds. |
- Spotify.categories(country=None, locale=None, limit=20, offset=0)
Get a list of categories used to tag items in Spotify.
- Parameters:
country (str) – an ISO 3166-1 alpha-2 country code
locale (str) – the desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 alpha-2 country code joined by an underscore
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.category(category_id, country=None, locale=None)
Get a single category used to tag items in Spotify.
- Parameters:
category_id (str) – category ID
country (str) – an ISO 3166-1 alpha-2 country code
locale (str) – the desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 alpha-2 country code joined by an underscore
- Return type:
- Spotify.category_playlists(category_id, country=None, limit=20, offset=0)
Get a list of Spotify playlists tagged with a particular category.
- Parameters:
category_id (str) – category ID
country (str) – an ISO 3166-1 alpha-2 country code
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.featured_playlists(country=None, locale=None, timestamp=None, limit=20, offset=0)
Get a list of Spotify featured playlists.
- Parameters:
country (str) – an ISO 3166-1 alpha-2 country code
locale (str) – the desired language, consisting of a lowercase ISO 639 language code and an uppercase ISO 3166-1 alpha-2 country code joined by an underscore
timestamp (str) – Timestamp in ISO 8601 format: yyyy-MM-ddTHH:mm:ss. Used to specify the user’s local time to get results tailored for that specific date and time in the day.
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Returns:
message and playlists
- Return type:
Tuple[str, SimplePlaylistPaging]
- Spotify.new_releases(country=None, limit=20, offset=0)
Get a list of new album releases featured in Spotify.
- Parameters:
country (str) – an ISO 3166-1 alpha-2 country code
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.recommendation_genre_seeds()
Get a list of available genre seeds.
- Return type:
List[str]
- Spotify.recommendations(artist_ids=None, genres=None, track_ids=None, limit=20, market=None, **attributes)
Get a list of recommended tracks for seeds.
Warning
The total number of seeds provided in
artist_ids
,genres
andtrack_ids
must be at least 1 and at most 5.- Parameters:
artist_ids (list) – list of seed artist IDs
genres (list) – list of seed genre names
track_ids (list) – list of seed track IDs
limit (int) – the number of items to return (1..100)
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
attributes – min/max/target_<attribute> - For all tuneable track attributes see
model.RecommendationAttribute
, these values provide filters and targeting on results.
- Raises:
ValueError – if any attribute is not allowed
- Return type:
Chapter API
Get information for a chapter. |
|
Get information for multiple chapters. |
- Spotify.chapter(chapter_id, market=None)
Get information for a chapter.
- Parameters:
chapter_id (str) – chapter ID
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the episode is considered unavailable.
- Return type:
- Spotify.chapters(chapter_ids, market=None)
Get information for multiple chapters.
- Parameters:
chapter_ids (list) – the chapter IDs, max 50 without chunking
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the episode is considered unavailable.
- Return type:
List[FullChapter]
Episode API
Get information for an episode. |
|
Get information for multiple episodes. |
- Spotify.episode(episode_id, market=None)
Get information for an episode.
- Parameters:
episode_id (str) – episode ID
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the episode is considered unavailable.
- Return type:
- Spotify.episodes(episode_ids, market=None)
Get information for multiple episodes.
- Parameters:
episode_ids (list) – the episode IDs, max 50 without chunking
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the episode is considered unavailable.
- Return type:
List[FullEpisode]
Follow API
Follow artists as current user. |
|
Check if current user follows artists. |
|
Unfollow artists as current user. |
|
Get artists followed by the current user. |
|
Follow a playlist as current user. |
|
Check if users are following a playlist. |
|
Unfollow a playlist as current user. |
|
Get a list of the playlists owned or followed by the current user. |
|
Follow users as current user. |
|
Check if current user follows users. |
|
Unfollow users as current user. |
- Spotify.artists_follow(artist_ids)
Follow artists as current user.
- Parameters:
artist_ids (list) – list of artist IDs, max 50 without chunking
- Return type:
None
- Spotify.artists_is_following(artist_ids)
Check if current user follows artists.
- Parameters:
artist_ids (list) – list of artist IDs, max 50 without chunking
- Returns:
follow statuses in the same order that the artist IDs were given
- Return type:
List[bool]
- Spotify.artists_unfollow(artist_ids)
Unfollow artists as current user.
- Parameters:
artist_ids (list) – list of artist IDs, max 50 without chunking
- Return type:
None
- Spotify.followed_artists(limit=20, after=None)
Get artists followed by the current user.
- Parameters:
limit (int) – the number of items to return (1..50)
after (str) – the last artist ID retrieved from the previous request
- Return type:
- Spotify.playlist_follow(playlist_id, public=True)
Follow a playlist as current user.
- Parameters:
playlist_id (str) – playlist ID
public (bool) – follow publicly
- Return type:
None
- Spotify.playlist_is_following(playlist_id, user_ids)
Check if users are following a playlist.
- Parameters:
playlist_id (str) – playlist ID
user_ids (list) – list of user IDs, max 5 without chunking
- Returns:
follow statuses in the same order that the user IDs were given
- Return type:
List[bool]
- Spotify.playlist_unfollow(playlist_id)
Unfollow a playlist as current user.
- Parameters:
playlist_id (str) – playlist ID
- Return type:
None
- Spotify.followed_playlists(limit=20, offset=0)
Get a list of the playlists owned or followed by the current user.
- Parameters:
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.users_follow(user_ids)
Follow users as current user.
- Parameters:
user_ids (list) – list of user IDs, max 50 without chunking
- Return type:
None
- Spotify.users_is_following(user_ids)
Check if current user follows users.
- Parameters:
user_ids (list) – list of user IDs, max 50 without chunking
- Returns:
follow statuses in the same order that the user IDs were given
- Return type:
List[bool]
- Spotify.users_unfollow(user_ids)
Unfollow users as current user.
- Parameters:
user_ids (list) – list of user IDs, max 50 without chunking
- Return type:
None
Library API
Get the albums saved in the current user's library. |
|
Save albums for current user. |
|
Check if user has saved albums. |
|
Remove albums for current user. |
|
Get the episodes saved in the current user's library. |
|
Save episodes for current user. |
|
Check if user has saved episodes. |
|
Remove episodes for current user. |
|
Get the shows saved in the current user's library. |
|
Save shows for current user. |
|
Check if user has saved shows. |
|
Remove shows for current user. |
|
Get the songs saved in the current user's library. |
|
Save tracks for current user. |
|
Check if user has saved tracks. |
|
Remove tracks for current user. |
- Spotify.saved_albums(market=None, limit=20, offset=0)
Get the albums saved in the current user’s library.
- Parameters:
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.saved_albums_add(album_ids)
Save albums for current user.
- Parameters:
album_ids (list) – list of album IDs, max 50 without chunking
- Return type:
None
- Spotify.saved_albums_contains(album_ids)
Check if user has saved albums.
- Parameters:
album_ids (list) – list of album IDs, max 50 without chunking
- Returns:
save statuses in the same order the album IDs were given
- Return type:
List[bool]
- Spotify.saved_albums_delete(album_ids)
Remove albums for current user.
- Parameters:
album_ids (list) – list of album IDs, max 50 without chunking
- Return type:
None
- Spotify.saved_episodes(market=None, limit=20, offset=0)
Get the episodes saved in the current user’s library.
- Parameters:
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.saved_episodes_add(episode_ids)
Save episodes for current user.
- Parameters:
episode_ids (list) – list of episode IDs, max 50 without chunking
- Return type:
None
- Spotify.saved_episodes_contains(episode_ids)
Check if user has saved episodes.
- Parameters:
episode_ids (list) – list of episode IDs, max 50 without chunking
- Returns:
save statuses in the same order the episode IDs were given
- Return type:
List[bool]
- Spotify.saved_episodes_delete(episode_ids)
Remove episodes for current user.
- Parameters:
episode_ids (list) – list of episode IDs, max 50 without chunking
- Return type:
None
- Spotify.saved_shows(market=None, limit=20, offset=0)
Get the shows saved in the current user’s library.
- Parameters:
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.saved_shows_add(show_ids)
Save shows for current user.
- Parameters:
show_ids (list) – list of show IDs, max 50 without chunking
- Return type:
None
- Spotify.saved_shows_contains(show_ids)
Check if user has saved shows.
- Parameters:
show_ids (list) – list of show IDs, max 50 without chunking
- Returns:
save statuses in the same order the show IDs were given
- Return type:
List[bool]
- Spotify.saved_shows_delete(show_ids, market=None)
Remove shows for current user.
- Parameters:
show_ids (list) – list of show IDs, max 50 without chunking
market (str) – an ISO 3166-1 alpha-2 country code, only remove shows that are available in the specified market, overrided by token’s country
- Return type:
None
- Spotify.saved_tracks(market=None, limit=20, offset=0)
Get the songs saved in the current user’s library.
- Parameters:
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.saved_tracks_add(track_ids)
Save tracks for current user.
- Parameters:
track_ids (list) – list of track IDs, max 50 without chunking
- Return type:
None
- Spotify.saved_tracks_contains(track_ids)
Check if user has saved tracks.
- Parameters:
track_ids (list) – list of track IDs, max 50 without chunking
- Returns:
save statuses in the same order the track IDs were given
- Return type:
List[bool]
- Spotify.saved_tracks_delete(track_ids)
Remove tracks for current user.
- Parameters:
track_ids (list) – list of track IDs, max 50 without chunking
- Return type:
None
Markets API
Get available market country codes. |
- Spotify.markets()
Get available market country codes.
- Returns:
available markets
- Return type:
List[str]
Personalisation API
Get the current user's top artists. |
|
Get the current user's top tracks. |
- Spotify.current_user_top_artists(time_range='medium_term', limit=20, offset=0)
Get the current user’s top artists.
- Parameters:
time_range (str) – Over what time frame are the affinities computed. Valid-values: short_term, medium_term, long_term
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.current_user_top_tracks(time_range='medium_term', limit=20, offset=0)
Get the current user’s top tracks.
- Parameters:
time_range (str) – Over what time frame are the affinities computed. Valid-values: short_term, medium_term, long_term
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
Player API
Get information about user's current playback. |
|
Get user's currently playing track. |
|
Get a user's available devices. |
|
Skip user's playback to next track. |
|
Pause a user's playback. |
|
Skip user's playback to previous track. |
|
Get items in a user's queue. |
|
Add a track or an episode to a user's queue. |
|
Get tracks from the current user's recently played tracks. |
|
Set repeat mode for playback. |
|
Resume user's playback. |
|
Seek to position in current playing track. |
|
Toggle shuffle for user's playback. |
|
Start playback of a context: an album, artist or playlist. |
|
Start playback of one or more tracks. |
|
Transfer playback to another device. |
|
Set volume for user's playback. |
- Spotify.playback(market=None, tracks_only=False)
Get information about user’s current playback.
- Parameters:
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
tracks_only (bool) – return only tracks in the currently playing item, if True, episodes have None as the currently playing item
- Returns:
information about current playback
- Return type:
- Spotify.playback_currently_playing(market=None, tracks_only=False)
Get user’s currently playing track.
Requiredscope
: user-read-currently-playing user-read-playback-stateOptionalscope
: user-read-currently-playing user-read-playback-stateOnly one of the scopes above is required.
- Parameters:
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
tracks_only (bool) – return only tracks in the currently playing item, if True, episodes have None as the currently playing item
- Returns:
information about the current track playing
- Return type:
- Spotify.playback_next(device_id=None)
Skip user’s playback to next track.
- Parameters:
device_id (str) – device to skip track on
- Return type:
None
- Spotify.playback_pause(device_id=None)
Pause a user’s playback.
- Parameters:
device_id (str) – device to pause playback on
- Return type:
None
- Spotify.playback_previous(device_id=None)
Skip user’s playback to previous track.
- Parameters:
device_id (str) – device to skip track on
- Return type:
None
- Spotify.playback_queue()
Get items in a user’s queue.
The result also include items in the current playback context even though they are not explicitly in the queue. The number of items in the queue is inconsistent, but from manual experimentation at least two items are returned.
- Return type:
- Spotify.playback_queue_add(uri, device_id=None)
Add a track or an episode to a user’s queue.
- Parameters:
uri (str) – resource to add, track or episode
device_id (str) – devide to extend the queue on
- Return type:
None
- Spotify.playback_recently_played(limit=20, after=None, before=None)
Get tracks from the current user’s recently played tracks.
Only
after
orbefore
should be specified at one time.- Parameters:
limit (int) – the number of items to return (1..50)
after (int) – a unix timestamp in milliseconds, must not be specified with ‘before’
before (int) – a unix timestamp in milliseconds, must not be specified with ‘after’
- Return type:
- Spotify.playback_repeat(state, device_id=None)
Set repeat mode for playback.
- Parameters:
state (str | RepeatState) – track, context, or off
device_id (str) – device to set repeat on
- Return type:
None
- Spotify.playback_resume(device_id=None)
Resume user’s playback.
- Parameters:
device_id (str) – device to start playback on
- Return type:
None
- Spotify.playback_seek(position_ms, device_id=None)
Seek to position in current playing track.
- Parameters:
position_ms (int) – position on track
device_id (str) – device to seek on
- Return type:
None
- Spotify.playback_shuffle(state, device_id=None)
Toggle shuffle for user’s playback.
- Parameters:
state (bool) – shuffle state
device_id (str) – device to toggle shuffle on
- Return type:
None
- Spotify.playback_start_context(context_uri, offset=None, position_ms=None, device_id=None)
Start playback of a context: an album, artist or playlist.
- Parameters:
context_uri (str) – context to start playing
offset (int | str) – offset into context by index or track ID, only available when context is an album or playlist
position_ms (int) – initial position of first played track
device_id (str) – device to start playback on
- Return type:
None
- Spotify.playback_start_tracks(track_ids, offset=None, position_ms=None, device_id=None)
Start playback of one or more tracks.
- Parameters:
track_ids (list) – track IDs to start playing
offset (int | str) – offset into tracks by index or track ID
position_ms (int) – initial position of first played track
device_id (str) – device to start playback on
- Return type:
None
- Spotify.playback_transfer(device_id, force_play=False)
Transfer playback to another device.
- Parameters:
device_id (str) – device to transfer playback to
force_play (bool) – true: play after transfer, false: keep current state
- Return type:
None
- Spotify.playback_volume(volume_percent, device_id=None)
Set volume for user’s playback.
- Parameters:
volume_percent (int) – volume to set (0..100)
device_id (str) – device to set volume on
- Return type:
None
Playlist API
Get playlist of a user. |
|
Get a list of the playlists owned or followed by a user. |
|
Create a playlist. |
|
Change a playlist's details. |
|
Get cover image of a playlist. |
|
Upload a custom playlist cover image. |
|
Full details of items on a playlist. |
|
Add items. |
|
Remove all items. |
|
Remove items by URI. |
|
Reorder items. |
|
Replace all items. |
See Spotify’s guide on working with playlists for additional information.
- Spotify.playlist(playlist_id, fields=None, market=None, as_tracks=False)
Get playlist of a user.
Note
Returns a dictionary if
fields
oras_tracks
is specified.- Parameters:
playlist_id (str) – playlist ID
fields (str) – which fields to return, see the Web API documentation for details
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’ when using a user token to authenticate. For episodes in the playlist, if a user token is used, the country associated with it overrides this parameter. If an application token is used and no market is specified, episodes are considered unavailable and returned as None.
as_tracks (bool | Iterable[str]) – return types of items with track-like fields. If
True
, return all other types as tracks. If an iterable is passed, types contained are returned as tracks. Currently the only extra type isepisode
.
- Returns:
playlist object, or raw dictionary if
fields
oras_tracks
was specified- Return type:
Union[FullPlaylist, dict]
- Spotify.playlists(user_id, limit=20, offset=0)
Get a list of the playlists owned or followed by a user.
Collaborative playlists are only returned for the current user.
- Parameters:
user_id (str) – user ID
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.playlist_create(user_id, name, public=True, description='')
Create a playlist.
- Parameters:
user_id (str) – user ID
name (str) – the name of the playlist
public (bool) – is the created playlist public
description (str) – the description of the playlist
- Return type:
- Spotify.playlist_change_details(playlist_id, name=None, public=None, collaborative=None, description=None)
Change a playlist’s details.
- Parameters:
playlist_id (str) – playlist ID
name (str) – name of the playlist
public (bool) – is the playlist public
collaborative (bool) – is the playlist collaborative
description (str) – description of the playlist
- Return type:
None
- Spotify.playlist_cover_image(playlist_id)
Get cover image of a playlist.
Note
Returns a list of images.
- Parameters:
playlist_id (str) – playlist ID
- Return type:
List[Image]
- Spotify.playlist_cover_image_upload(playlist_id, image)
Upload a custom playlist cover image.
- Parameters:
playlist_id (str) – playlist ID
image (str) – image data as a base64-encoded string
- Return type:
None
- Spotify.playlist_items(playlist_id, fields=None, market=None, as_tracks=False, limit=100, offset=0)
Full details of items on a playlist.
Note
Returns a dictionary if
fields
oras_tracks
is specified.- Parameters:
playlist_id (str) – playlist ID
fields (str) – which fields to return, see the Web API documentation for details
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’ when using a user token to authenticate. For episodes in the playlist, if a user token is used, the country associated with it overrides this parameter. If an application token is used and no market is specified, episodes are considered unavailable and returned as None.
as_tracks (bool | Iterable[str]) – return types of items with track-like fields. If
True
, return all other types as tracks. If an iterable is passed, types contained are returned as tracks. Currently the only extra type isepisode
.limit (int) – the number of items to return (1..100)
offset (int) – the index of the first item to return
- Returns:
paging object containing playlist items, or raw dictionary if
fields
oras_tracks
was specified- Return type:
Union[PlaylistTrackPaging, dict]
- Spotify.playlist_add(playlist_id, uris, position=None)
Add items.
- Parameters:
playlist_id (str) – playlist ID
uris (list) – list of URIs, max 100 without chunking
position (int) – index to insert the items in
- Returns:
snapshot ID for the playlist
- Return type:
str
- Spotify.playlist_clear(playlist_id)
Remove all items.
- Parameters:
playlist_id (str) – playlist ID
- Return type:
None
- Spotify.playlist_remove(playlist_id, uris, snapshot_id=None)
Remove items by URI.
Removes all occurrences of the specified items. Note that when chunked,
snapshot_id
is not updated between requests.- Parameters:
playlist_id (str) – playlist ID
uris (list) – list of URIs, max 100 without chunking
snapshot_id (str) – snapshot ID for the playlist
- Returns:
snapshot ID for the playlist
- Return type:
str
- Spotify.playlist_reorder(playlist_id, range_start, insert_before, range_length=1, snapshot_id=None)
Reorder items.
- Parameters:
playlist_id (str) – playlist ID
range_start (int) – position of the first item to be reordered
range_length (int) – number of items to be reordered
insert_before (int) – position where the items should be inserted
snapshot_id (str) – snapshot ID for the playlist
- Returns:
snapshot ID for the playlist
- Return type:
str
- Spotify.playlist_replace(playlist_id, uris)
Replace all items.
- Parameters:
playlist_id (str) – playlist ID
uris (list) – list of URIs, max 100
- Return type:
None
Search API
- Spotify.search(query, types=('track',), market=None, include_external=None, limit=20, offset=0)
Search for an item.
Returns
NotFound
if limit+offset would be above 1000.- Parameters:
query (str) – search query
types (tuple) – resources to search for, tuple of strings containing artist, album, audiobook, track, playlist, show and/or episode
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
include_external (str) – if ‘audio’, response will include any externally hosted audio
- Returns:
Paging objects containing the types of items searched for in the order that they were specified in ‘types’.
artist:
FullArtistOffsetPaging
album:
SimpleAlbumPaging
audiobook:
SimpleAudiobookPaging
episode:
SimpleEpisodePaging
playlist:
SimplePlaylistPaging
show:
SimpleShowPaging
track:
FullTrackPaging
- Return type:
tuple
Examples
tracks, = spotify.search('monty python') artists, = spotify.search('sheeran', types=('artist',)) albums, tracks = spotify.search('piano', types=('album', 'track')) spotify.search('gold album:boba artist:abba', types=('track',)) spotify.search('bob year:1980-2020', types=('show',))
Note
You can narrow down search results by specifying field filters (e.g. year range, genre). See the Search for an Item page of the official documentation for more information.
Show API
Get information for a show. |
|
Get episodes of a show. |
|
Get information for multiple shows. |
- Spotify.show(show_id, market=None)
Get information for a show.
The user-read-playback-position scope allows episode resume points to be returned.
- Parameters:
show_id (str) – show ID
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the show is considered unavailable.
- Return type:
- Spotify.show_episodes(show_id, market=None, limit=20, offset=0)
Get episodes of a show.
- Parameters:
show_id (str) – show ID
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the show is considered unavailable.
limit (int) – the number of items to return (1..50)
offset (int) – the index of the first item to return
- Return type:
- Spotify.shows(show_ids, market=None)
Get information for multiple shows.
The user-read-playback-position scope allows episode resume points to be returned.
- Parameters:
show_ids (list) – the show IDs, max 50 without chunking
market (str) – an ISO 3166-1 alpha-2 country code. If a user token is used to authenticate, the country associated with it overrides this parameter. If an application token is used and no market is specified, the show is considered unavailable.
- Return type:
List[FullShow]
Track API
Get information for a track. |
|
Get a detailed audio analysis for a track. |
|
Get audio feature information for a track. |
|
Get information for multiple tracks. |
|
Get audio feature information for multiple tracks. |
- Spotify.track(track_id, market=None)
Get information for a track.
- Parameters:
track_id (str) – track ID
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
- Return type:
- Spotify.track_audio_analysis(track_id)
Get a detailed audio analysis for a track.
The analysis describes the track’s structure and musical content, including rythm, pitch and timbre.
- Parameters:
track_id (str) –
- Return type:
- Spotify.track_audio_features(track_id)
Get audio feature information for a track.
- Parameters:
track_id (str) –
- Return type:
- Spotify.tracks(track_ids, market=None)
Get information for multiple tracks.
- Parameters:
track_ids (list) – the track IDs, max 50 without chunking
market (str) – an ISO 3166-1 alpha-2 country code or ‘from_token’
- Return type:
List[FullTrack]
- Spotify.tracks_audio_features(track_ids)
Get audio feature information for multiple tracks.
Feature information for a track may be
None
if not available.- Parameters:
track_ids (list) – track IDs, max 100 without chunking
- Return type:
List[AudioFeatures]
User API
Get current user's profile. |
|
Get a user's profile. |
- Spotify.current_user()
Get current user’s profile.
The user-read-private scope allows the user’s country and product subscription level to be returned.
- Return type:
- Spotify.user(user_id)
Get a user’s profile.
- Parameters:
user_id (str) – user ID
- Return type:
Configuration
Importing and exporting application credentials.
Read configuration from environment variables. |
|
Read configuration from a config file. |
|
Write configuration to a config file. |
|
Missing value read from configuration. |
|
Configuration variable name for a client ID. |
|
Configuration variable name for a client secret. |
|
Configuration variable name for a redirect URI. |
|
Configuration variable name for a user refresh token. |
Environment variables and configuration files can be used to provide application and user credentials. See also Options.
- tekore.config_from_environment(return_refresh=False)
Read configuration from environment variables.
- Parameters:
return_refresh (bool) – return user refresh token
- Returns:
(client ID, client secret, redirect URI), None if not found. If return_refresh is True, also return user refresh token.
- Return type:
tuple
- Raises:
MissingConfigurationWarning – when a missing value is encountered
Examples
client_id, client_secret, redirect_uri = tk.config_from_environment() conf = tk.config_from_environment(return_refresh=True) client_id, client_secret, redirect_uri, user_refresh = conf
- tekore.config_from_file(file_path, section='DEFAULT', return_refresh=False)
Read configuration from a config file.
The configuration must be in INI format as accepted by
configparser.ConfigParser
.- Parameters:
file_path (str) – path of the file containing the credential variables
section (str) – name of the section to read variables from
return_refresh (bool) – return user refresh token
- Returns:
(client ID, client secret, redirect URI), None if not found. If return_refresh is True, also return user refresh token.
- Return type:
tuple
- Raises:
MissingConfigurationWarning – when a missing value is encountered
Examples
client_id, client_secret, redirect_uri = tk.config_from_file(filename) conf = tk.config_from_file(filename, return_refresh=True) client_id, client_secret, redirect_uri, user_refresh = conf
- tekore.config_to_file(file_path, values, section='DEFAULT')
Write configuration to a config file.
Existing configuration is preserved if it’s not in conflict.
- Parameters:
file_path (str) – path of the configuration file
values (Iterable | dict) – configuration values to write, dict or iterable, see below for examples
section (str) – name of the section to write to
- Return type:
None
Examples
Configuration can be written in different ways. Pass in an iterable to use the preset variable names. The values should be ordered as returned when reading configuration:
client_id, client_secret, redirect_uri, user_refresh
.conf = (client_id, client_secret, redirect_uri, user_refresh) config_to_file(filename, conf)
A shorter iterable or one containing
None
values may be passed. Items missing from the end are ignored andNone
values are discarded.# Write partial information config_to_file(filename, (client_id, client_secret)) # Fill the missing configuration conf = (None, None, redirect_uri, user_refresh) config_to_file(filename, conf)
A dictionary is also accepted. In this case the keys are used instead of preset variable names.
config_to_file(filename, {'REFRESH_TOKEN': refresh_token})
- class tekore.MissingConfigurationWarning
Bases:
RuntimeWarning
Missing value read from configuration.
Options
Configuration values are read from and written to preset names. Those names can be changed to your liking.
import tekore as tk
tk.client_id_var = 'your_client_id_var'
tk.client_secret_var = 'your_client_secret_var'
tk.redirect_uri_var = 'your_redirect_uri_var'
tk.user_refresh_var = 'your_user_refresh_var'
Note
Changing values requires importing Tekore as a module as above.
- tekore.client_id_var: str = 'SPOTIFY_CLIENT_ID'
Configuration variable name for a client ID.
- tekore.client_secret_var: str = 'SPOTIFY_CLIENT_SECRET'
Configuration variable name for a client secret.
- tekore.redirect_uri_var: str = 'SPOTIFY_REDIRECT_URI'
Configuration variable name for a redirect URI.
- tekore.user_refresh_var: str = 'SPOTIFY_USER_REFRESH'
Configuration variable name for a user refresh token.
Conversions
Conversions between Spotify IDs, URIs and URLs.
Convert an ID to an URI of the appropriate type. |
|
Convert an ID to an URL of the appropriate type. |
|
Parse type and ID from an URI. |
|
Parse type and ID from an URL. |
|
Error in conversion. |
|
Valid types of Spotify IDs. |
|
Validate resource ID to be base 62. |
|
Validate type of an ID. |
import tekore as tk
# Create ULR for opening an album in the browser
mountain = '3RBULTZJ97bvVzZLpxcB0j'
m_url = tk.to_url('album', mountain)
# Parse input
type_, id_ = tk.from_url(m_url)
print(f'Got type `{type_}` with ID `{id_}`')
- tekore.check_id(id_)
Validate resource ID to be base 62.
Note that user IDs can have special characters, so they cannot be validated.
- Raises:
ConversionError – When ID is invalid.
- Parameters:
id_ (str) –
- Return type:
None
- tekore.check_type(type_)
Validate type of an ID.
- Raises:
ConversionError – When type is invalid.
- Parameters:
type_ (str | IdentifierType) –
- Return type:
None
- class tekore.ConversionError
Bases:
Exception
Error in conversion.
- tekore.from_uri(uri)
Parse type and ID from an URI.
- Parameters:
uri (str) – URI to parse
- Returns:
type and ID parsed from the URI
- Return type:
Tuple[str, str]
- Raises:
ConversionError – On invalid format, prefix, type or ID.
- tekore.from_url(url)
Parse type and ID from an URL.
Any parameters in the URL will be ignored.
- Parameters:
url (str) – URL to parse
- Returns:
type and ID parsed from the URL
- Return type:
Tuple[str, str]
- Raises:
ConversionError – On invalid format, prefix, type or ID.
- tekore.to_uri(type_, id_)
Convert an ID to an URI of the appropriate type.
- Parameters:
type – valid
IdentifierType
id – resource identifier
type_ (str | IdentifierType) –
id_ (str) –
- Returns:
converted URI
- Return type:
str
- Raises:
ConversionError – On invalid type or ID.
- tekore.to_url(type_, id_)
Convert an ID to an URL of the appropriate type.
- Parameters:
type – valid
IdentifierType
id – resource identifier
type_ (str | IdentifierType) –
id_ (str) –
- Returns:
converted URL
- Return type:
str
- Raises:
ConversionError – On invalid type or ID.
Errors
Web errors for Authorisation and Client.
Base error for all web status errors. |
|
4xx - Base client error. |
|
5xx - Base server error. |
|
400 - Bad request. |
|
401 - Unauthorised. |
|
403 - Forbidden. |
|
404 - Not found. |
|
429 - Too many requests. |
|
500 - Internal server error. |
|
502 - Bad gateway. |
|
503 - Service unavailable. |
Clients facing the Web API raise errors when recieving bad status codes.
Only errors documented in the Web API documentation are expected and provided.
Other exceptions are raised as ClientError
or ServerError
.
import tekore as tk
conf = tk.config_from_environment()
token = tk.request_client_token(*conf[:2])
spotify = tk.Spotify(token)
try:
spotify.album('not-a-real-album')
except tk.BadRequest:
print('Whoops, bad request!')
except tk.HTTPError:
print('Something is seriously wrong.')
Error objects also contain the relevant Request
and Response
objects for closer inspection.
try:
spotify.album('not-a-real-album')
except tk.BadRequest as ex:
print(str(ex))
print(ex.request)
print(ex.response)
- class tekore.HTTPError(message, request, response)
Bases:
Exception
Base error for all web status errors.
- request
request that led to the error
- response
response from the web server
- class tekore.BadRequest(message, request, response)
Bases:
ClientError
400 - Bad request.
The request could not be understood by the server due to malformed syntax.
- class tekore.Unauthorised(message, request, response)
Bases:
ClientError
401 - Unauthorised.
The request requires user authentication or, if the request included authorization credentials, authorization has been refused for those credentials.
The scopes associated with the call are attached to this class.
- optional_scope: str
- required_scope: str
- scope: str
- class tekore.Forbidden(message, request, response)
Bases:
ClientError
403 - Forbidden.
The server understood the request, but is refusing to fulfill it.
- class tekore.NotFound(message, request, response)
Bases:
ClientError
404 - Not found.
The requested resource could not be found. This error can be due to a temporary or permanent condition.
- class tekore.TooManyRequests(message, request, response)
Bases:
ClientError
429 - Too many requests.
Rate limiting has been applied.
- class tekore.InternalServerError(message, request, response)
Bases:
ServerError
500 - Internal server error.
You should never receive this error because the clever coders at Spotify catch them all… But if you are unlucky enough to get one, please report it to Spotify through their GitHub (spotify/web-api).
- class tekore.BadGateway(message, request, response)
Bases:
ClientError
502 - Bad gateway.
The server was acting as a gateway or proxy and received an invalid response from the upstream server.
Bases:
ClientError
503 - Service unavailable.
The server is currently unable to handle the request due to a temporary condition which will be alleviated after some delay. You can choose to resend the request again.
Models
Response model definitions for client.
Responses are parsed into Pydantic models. This allows accessing parts of the response directly as attributes. Further documentation on specific attribute values can be viewed in the Web API reference.
import tekore as tk
# Call the API
spotify = tk.Spotify(token)
album = spotify.album('3RBULTZJ97bvVzZLpxcB0j')
# Use the response
for track in album.tracks.items:
print(track.track_number, track.name)
Using Pydantic models means that responses are easy to work with.
They provide a readable repr
(particularly with devtools) for quick inspection,
and it is also possible to convert models to builtin and JSON representations:
from pprint import pprint
print(album)
pprint(album, depth=2)
album.dict()
album.json()
Responses will sometimes contain unknown attributes when the API changes.
They are ignored when parsing the response model, but a
UnknownModelAttributeWarning
is issued when encountering one.
Please consider upgrading Tekore if a newer version documents and handles it.
Models are made available in the tekore.models
namespace.
Album
Album base. |
|
Relationship between artist and album. |
|
Type of album. |
|
Simplified album object. |
|
Paging containing simplified albums. |
|
Complete album object. |
|
Album saved to library. |
|
Paging of albums in library. |
- class tekore.model.Album(*, id, href, type, uri, album_type, artists, external_urls, images, name, total_tracks, release_date, release_date_precision, available_markets=None, is_playable=None)
Bases:
Item
Album base.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
album_type (AlbumType) –
artists (List[SimpleArtist]) –
external_urls (dict) –
images (List[Image]) –
name (str) –
total_tracks (int) –
release_date (str) –
release_date_precision (ReleaseDatePrecision) –
available_markets (List[str] | None) –
is_playable (bool | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album_type': FieldInfo(annotation=AlbumType, required=True), 'artists': FieldInfo(annotation=List[SimpleArtist], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'total_tracks': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.AlbumGroup(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
StrEnum
Relationship between artist and album.
- album = 'album'
- appears_on = 'appears_on'
- compilation = 'compilation'
- single = 'single'
- class tekore.model.AlbumType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
StrEnum
Type of album.
- album = 'album'
- compilation = 'compilation'
- ep = 'ep'
- single = 'single'
- class tekore.model.SimpleAlbum(*, id, href, type, uri, album_type, artists, external_urls, images, name, total_tracks, release_date, release_date_precision, available_markets=None, is_playable=None, album_group=None)
Bases:
Album
Simplified album object.
album_group
is available when getting an artist’s albums.available_markets
is available when market is not specified.The presence of
is_playable
is undocumented and it appears to only beTrue
when it is present.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
album_type (AlbumType) –
artists (List[SimpleArtist]) –
external_urls (dict) –
images (List[Image]) –
name (str) –
total_tracks (int) –
release_date (str) –
release_date_precision (ReleaseDatePrecision) –
available_markets (List[str] | None) –
is_playable (bool | None) –
album_group (AlbumGroup | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album_group': FieldInfo(annotation=Union[AlbumGroup, NoneType], required=False, default=None), 'album_type': FieldInfo(annotation=AlbumType, required=True), 'artists': FieldInfo(annotation=List[SimpleArtist], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'total_tracks': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleAlbumPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging containing simplified albums.
- Parameters:
href (str) –
items (List[SimpleAlbum]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SimpleAlbum], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullAlbum(*, id, href, type, uri, album_type, artists, external_urls, images, name, total_tracks, release_date, release_date_precision, available_markets=None, is_playable=None, copyrights, external_ids, genres, label, popularity, tracks)
Bases:
Album
Complete album object.
available_markets
is available when market is not specified.The presence of
is_playable
is undocumented and it appears to only beTrue
when it is present.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
album_type (AlbumType) –
artists (List[SimpleArtist]) –
external_urls (dict) –
images (List[Image]) –
name (str) –
total_tracks (int) –
release_date (str) –
release_date_precision (ReleaseDatePrecision) –
available_markets (List[str] | None) –
is_playable (bool | None) –
copyrights (List[Copyright]) –
external_ids (dict) –
genres (List[str]) –
label (str | None) –
popularity (int) –
tracks (SimpleTrackPaging) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album_type': FieldInfo(annotation=AlbumType, required=True), 'artists': FieldInfo(annotation=List[SimpleArtist], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'copyrights': FieldInfo(annotation=List[Copyright], required=True), 'external_ids': FieldInfo(annotation=dict, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'genres': FieldInfo(annotation=List[str], required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'label': FieldInfo(annotation=Union[str, NoneType], required=True), 'name': FieldInfo(annotation=str, required=True), 'popularity': FieldInfo(annotation=int, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'total_tracks': FieldInfo(annotation=int, required=True), 'tracks': FieldInfo(annotation=SimpleTrackPaging, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedAlbum(*, added_at, album)
Bases:
Model
Album saved to library.
- Parameters:
added_at (datetime) –
album (FullAlbum) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'added_at': FieldInfo(annotation=datetime, required=True), 'album': FieldInfo(annotation=FullAlbum, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedAlbumPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of albums in library.
- Parameters:
href (str) –
items (List[SavedAlbum]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SavedAlbum], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Artist
Artist base. |
|
Simplified artist object. |
|
Complete artist object. |
|
Paging of full artists. |
|
Paging of full artists. |
- class tekore.model.Artist(*, id, href, type, uri, external_urls, name)
Bases:
Item
Artist base.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
external_urls (dict) –
name (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleArtist(*, id, href, type, uri, external_urls, name)
Bases:
Artist
Simplified artist object.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
external_urls (dict) –
name (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullArtist(*, id, href, type, uri, external_urls, name, followers, genres, images, popularity)
Bases:
Artist
Complete artist object.
- Parameters:
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'external_urls': FieldInfo(annotation=dict, required=True), 'followers': FieldInfo(annotation=Followers, required=True), 'genres': FieldInfo(annotation=List[str], required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'name': FieldInfo(annotation=str, required=True), 'popularity': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullArtistCursorPaging(*, href, items, limit, next, cursors, total)
Bases:
CursorPaging
Paging of full artists.
- Parameters:
href (str) –
items (List[FullArtist]) –
limit (int) –
next (str | None) –
cursors (Cursor) –
total (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'cursors': FieldInfo(annotation=Cursor, required=True), 'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[FullArtist], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullArtistOffsetPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of full artists.
- Parameters:
href (str) –
items (List[FullArtist]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[FullArtist], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Audiobook
Audiobook base. |
|
Simplified audiobook. |
|
Paging of simplified audiobooks. |
|
Complete audiobook object. |
|
Audiobook author. |
|
Audiobook narrator. |
- class tekore.model.Audiobook(*, id, href, type, uri, authors, available_markets=None, copyrights, description, edition, explicit, external_urls, html_description, images, is_externally_hosted=None, languages, media_type, name, narrators, publisher, total_chapters)
Bases:
Item
Audiobook base.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
authors (List[Author]) –
available_markets (List[str] | None) –
copyrights (List[Copyright]) –
description (str) –
edition (str | None) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_externally_hosted (bool | None) –
languages (List[str]) –
media_type (str) –
name (str) –
narrators (List[Narrator]) –
publisher (str) –
total_chapters (int | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'authors': FieldInfo(annotation=List[Author], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'copyrights': FieldInfo(annotation=List[Copyright], required=True), 'description': FieldInfo(annotation=str, required=True), 'edition': FieldInfo(annotation=Union[str, NoneType], required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'media_type': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'narrators': FieldInfo(annotation=List[Narrator], required=True), 'publisher': FieldInfo(annotation=str, required=True), 'total_chapters': FieldInfo(annotation=Union[int, NoneType], required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleAudiobook(*, id, href, type, uri, authors, available_markets=None, copyrights, description, edition, explicit, external_urls, html_description, images, is_externally_hosted=None, languages, media_type, name, narrators, publisher, total_chapters, chapters=None)
Bases:
Audiobook
Simplified audiobook.
May contain
chapters
, but that is likely an error.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
authors (List[Author]) –
available_markets (List[str] | None) –
copyrights (List[Copyright]) –
description (str) –
edition (str | None) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_externally_hosted (bool | None) –
languages (List[str]) –
media_type (str) –
name (str) –
narrators (List[Narrator]) –
publisher (str) –
total_chapters (int | None) –
chapters (dict | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'authors': FieldInfo(annotation=List[Author], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'chapters': FieldInfo(annotation=Union[dict, NoneType], required=False, default=None), 'copyrights': FieldInfo(annotation=List[Copyright], required=True), 'description': FieldInfo(annotation=str, required=True), 'edition': FieldInfo(annotation=Union[str, NoneType], required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'media_type': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'narrators': FieldInfo(annotation=List[Narrator], required=True), 'publisher': FieldInfo(annotation=str, required=True), 'total_chapters': FieldInfo(annotation=Union[int, NoneType], required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleAudiobookPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of simplified audiobooks.
- Parameters:
href (str) –
items (List[SimpleAudiobook]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SimpleAudiobook], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullAudiobook(*, id, href, type, uri, authors, available_markets=None, copyrights, description, edition, explicit, external_urls, html_description, images, is_externally_hosted=None, languages, media_type, name, narrators, publisher, total_chapters, chapters)
Bases:
Audiobook
Complete audiobook object.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
authors (List[Author]) –
available_markets (List[str] | None) –
copyrights (List[Copyright]) –
description (str) –
edition (str | None) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_externally_hosted (bool | None) –
languages (List[str]) –
media_type (str) –
name (str) –
narrators (List[Narrator]) –
publisher (str) –
total_chapters (int | None) –
chapters (SimpleChapterPaging) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'authors': FieldInfo(annotation=List[Author], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'chapters': FieldInfo(annotation=SimpleChapterPaging, required=True), 'copyrights': FieldInfo(annotation=List[Copyright], required=True), 'description': FieldInfo(annotation=str, required=True), 'edition': FieldInfo(annotation=Union[str, NoneType], required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'media_type': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'narrators': FieldInfo(annotation=List[Narrator], required=True), 'publisher': FieldInfo(annotation=str, required=True), 'total_chapters': FieldInfo(annotation=Union[int, NoneType], required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Author(*, name)
Bases:
Model
Audiobook author.
- Parameters:
name (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'name': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Narrator(*, name)
Bases:
Model
Audiobook narrator.
- Parameters:
name (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'name': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Category
Spotify tag category. |
|
Paging of categories. |
- class tekore.model.Category(*, id, href, icons, name)
Bases:
Identifiable
Spotify tag category.
- Parameters:
id (str) –
href (str) –
icons (List[Image]) –
name (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'icons': FieldInfo(annotation=List[Image], required=True), 'id': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.CategoryPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of categories.
- Parameters:
href (str) –
items (List[Category]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[Category], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Chapter
Audiobook chapter base. |
|
Simplified chapter. |
|
Paging of simplified chapters. |
|
Complete chapter object. |
- class tekore.model.Chapter(*, id, href, type, uri, audio_preview_url, available_markets=None, chapter_number, description, duration_ms, explicit, external_urls, html_description, images, is_playable=None, languages, name, release_date_precision, release_date, restrictions=None, resume_point)
Bases:
Item
Audiobook chapter base.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
audio_preview_url (str | None) –
available_markets (List[str] | None) –
chapter_number (int) –
description (str) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_playable (bool | None) –
languages (List[str]) –
name (str) –
release_date_precision (ReleaseDatePrecision) –
release_date (str) –
restrictions (Restrictions | None) –
resume_point (ResumePoint) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'audio_preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'chapter_number': FieldInfo(annotation=int, required=True), 'description': FieldInfo(annotation=str, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'resume_point': FieldInfo(annotation=ResumePoint, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleChapter(*, id, href, type, uri, audio_preview_url, available_markets=None, chapter_number, description, duration_ms, explicit, external_urls, html_description, images, is_playable=None, languages, name, release_date_precision, release_date, restrictions=None, resume_point)
Bases:
Chapter
Simplified chapter.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
audio_preview_url (str | None) –
available_markets (List[str] | None) –
chapter_number (int) –
description (str) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_playable (bool | None) –
languages (List[str]) –
name (str) –
release_date_precision (ReleaseDatePrecision) –
release_date (str) –
restrictions (Restrictions | None) –
resume_point (ResumePoint) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'audio_preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'chapter_number': FieldInfo(annotation=int, required=True), 'description': FieldInfo(annotation=str, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'resume_point': FieldInfo(annotation=ResumePoint, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleChapterPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of simplified chapters.
- Parameters:
href (str) –
items (List[SimpleChapter]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SimpleChapter], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullChapter(*, id, href, type, uri, audio_preview_url, available_markets=None, chapter_number, description, duration_ms, explicit, external_urls, html_description, images, is_playable=None, languages, name, release_date_precision, release_date, restrictions=None, resume_point, audiobook)
Bases:
Chapter
Complete chapter object.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
audio_preview_url (str | None) –
available_markets (List[str] | None) –
chapter_number (int) –
description (str) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_playable (bool | None) –
languages (List[str]) –
name (str) –
release_date_precision (ReleaseDatePrecision) –
release_date (str) –
restrictions (Restrictions | None) –
resume_point (ResumePoint) –
audiobook (SimpleAudiobook) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'audio_preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'audiobook': FieldInfo(annotation=SimpleAudiobook, required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'chapter_number': FieldInfo(annotation=int, required=True), 'description': FieldInfo(annotation=str, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'resume_point': FieldInfo(annotation=ResumePoint, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Episode
Episode base. |
|
Simplified episode object. |
|
Paging of simplified episodes. |
|
Complete episode object. |
|
Episode saved to library. |
|
Paging of episodes in library. |
|
Resume point. |
- class tekore.model.Episode(*, id, href, type, uri, audio_preview_url, description, duration_ms, explicit, external_urls, html_description, images, is_externally_hosted, is_playable=None, language=None, languages, name, release_date, release_date_precision, resume_point=None)
Bases:
Item
Episode base.
language
is deprecated.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
audio_preview_url (str | None) –
description (str) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_externally_hosted (bool) –
is_playable (bool | None) –
language (str | None) –
languages (List[str]) –
name (str) –
release_date (str) –
release_date_precision (ReleaseDatePrecision) –
resume_point (ResumePoint | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'audio_preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'description': FieldInfo(annotation=str, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=bool, required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'language': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'resume_point': FieldInfo(annotation=Union[ResumePoint, NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleEpisode(*, id, href, type, uri, audio_preview_url, description, duration_ms, explicit, external_urls, html_description, images, is_externally_hosted, is_playable=None, language=None, languages, name, release_date, release_date_precision, resume_point=None)
Bases:
Episode
Simplified episode object.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
audio_preview_url (str | None) –
description (str) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_externally_hosted (bool) –
is_playable (bool | None) –
language (str | None) –
languages (List[str]) –
name (str) –
release_date (str) –
release_date_precision (ReleaseDatePrecision) –
resume_point (ResumePoint | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'audio_preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'description': FieldInfo(annotation=str, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=bool, required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'language': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'resume_point': FieldInfo(annotation=Union[ResumePoint, NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleEpisodePaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of simplified episodes.
- Parameters:
href (str) –
items (List[SimpleEpisode]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SimpleEpisode], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullEpisode(*, id, href, type, uri, audio_preview_url, description, duration_ms, explicit, external_urls, html_description, images, is_externally_hosted, is_playable=None, language=None, languages, name, release_date, release_date_precision, resume_point=None, restrictions=None, show)
Bases:
Episode
Complete episode object.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
audio_preview_url (str | None) –
description (str) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_externally_hosted (bool) –
is_playable (bool | None) –
language (str | None) –
languages (List[str]) –
name (str) –
release_date (str) –
release_date_precision (ReleaseDatePrecision) –
resume_point (ResumePoint | None) –
restrictions (Restrictions | None) –
show (SimpleShow) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'audio_preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'description': FieldInfo(annotation=str, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=bool, required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'language': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'resume_point': FieldInfo(annotation=Union[ResumePoint, NoneType], required=False, default=None), 'show': FieldInfo(annotation=SimpleShow, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedEpisode(*, added_at, episode)
Bases:
Model
Episode saved to library.
- Parameters:
added_at (datetime) –
episode (FullEpisode) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'added_at': FieldInfo(annotation=datetime, required=True), 'episode': FieldInfo(annotation=FullEpisode, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedEpisodePaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of episodes in library.
- Parameters:
href (str) –
items (List[SavedEpisode]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SavedEpisode], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.ResumePoint(*, fully_played, resume_position_ms)
Bases:
Model
Resume point.
- Parameters:
fully_played (bool) –
resume_position_ms (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'fully_played': FieldInfo(annotation=bool, required=True), 'resume_position_ms': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Playback
Current playback. |
|
Extended current playback context. |
|
Type of currently playing item. |
|
Playback queue. |
|
Playback device. |
|
Type of playback device. |
|
Player actions. |
|
Disallowed player actions. |
|
Reasons for errors in player actions. |
|
Playback repeat state. |
|
Previously played track. |
|
Cursor to play history. |
|
Paging to play history. |
|
Context of a played track or episode. |
|
Type of player context. |
Currently playing
- class tekore.model.CurrentlyPlaying(*, actions, currently_playing_type, is_playing, timestamp, context, progress_ms, item)
Bases:
Model
Current playback.
context
,progress_ms
anditem
may beNone
e.g. during a private session.- Parameters:
actions (Actions) –
currently_playing_type (CurrentlyPlayingType) –
is_playing (bool) –
timestamp (int) –
context (Context | None) –
progress_ms (int | None) –
item (FullTrack | LocalTrack | FullEpisode | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'actions': FieldInfo(annotation=Actions, required=True), 'context': FieldInfo(annotation=Union[Context, NoneType], required=True), 'currently_playing_type': FieldInfo(annotation=CurrentlyPlayingType, required=True), 'is_playing': FieldInfo(annotation=bool, required=True), 'item': FieldInfo(annotation=Union[FullTrack, LocalTrack, FullEpisode, NoneType], required=True), 'progress_ms': FieldInfo(annotation=Union[int, NoneType], required=True), 'timestamp': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.CurrentlyPlayingContext(*, actions, currently_playing_type, is_playing, timestamp, context, progress_ms, item, device, repeat_state, shuffle_state, smart_shuffle)
Bases:
CurrentlyPlaying
Extended current playback context.
smart_shuffle
is not documented in the Spotify API.- Parameters:
actions (Actions) –
currently_playing_type (CurrentlyPlayingType) –
is_playing (bool) –
timestamp (int) –
context (Context | None) –
progress_ms (int | None) –
item (FullTrack | LocalTrack | FullEpisode | None) –
device (Device) –
repeat_state (RepeatState) –
shuffle_state (bool) –
smart_shuffle (bool | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'actions': FieldInfo(annotation=Actions, required=True), 'context': FieldInfo(annotation=Union[Context, NoneType], required=True), 'currently_playing_type': FieldInfo(annotation=CurrentlyPlayingType, required=True), 'device': FieldInfo(annotation=Device, required=True), 'is_playing': FieldInfo(annotation=bool, required=True), 'item': FieldInfo(annotation=Union[FullTrack, LocalTrack, FullEpisode, NoneType], required=True), 'progress_ms': FieldInfo(annotation=Union[int, NoneType], required=True), 'repeat_state': FieldInfo(annotation=RepeatState, required=True), 'shuffle_state': FieldInfo(annotation=bool, required=True), 'smart_shuffle': FieldInfo(annotation=Union[bool, NoneType], required=True), 'timestamp': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.CurrentlyPlayingType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
StrEnum
Type of currently playing item.
- ad = 'ad'
- episode = 'episode'
- track = 'track'
- unknown = 'unknown'
- class tekore.model.Queue(*, currently_playing, queue)
Bases:
Model
Playback queue.
- Parameters:
currently_playing (FullTrack | LocalTrack | FullEpisode | None) –
queue (List[FullTrack | LocalTrack | FullEpisode | None]) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'currently_playing': FieldInfo(annotation=Union[FullTrack, LocalTrack, FullEpisode, NoneType], required=True), 'queue': FieldInfo(annotation=List[Union[FullTrack, LocalTrack, FullEpisode, NoneType]], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Device(*, id, is_active, is_private_session, is_restricted, name, type, volume_percent, supports_volume)
Bases:
Identifiable
Playback device.
- Parameters:
id (str) –
is_active (bool) –
is_private_session (bool) –
is_restricted (bool) –
name (str) –
type (DeviceType) –
volume_percent (int | None) –
supports_volume (bool) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=str, required=True), 'is_active': FieldInfo(annotation=bool, required=True), 'is_private_session': FieldInfo(annotation=bool, required=True), 'is_restricted': FieldInfo(annotation=bool, required=True), 'name': FieldInfo(annotation=str, required=True), 'supports_volume': FieldInfo(annotation=bool, required=True), 'type': FieldInfo(annotation=DeviceType, required=True), 'volume_percent': FieldInfo(annotation=Union[int, NoneType], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.DeviceType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
StrEnum
Type of playback device.
- AVR = 'AVR'
- AudioDongle = 'AudioDongle'
- Automobile = 'Automobile'
- CastAudio = 'CastAudio'
- CastVideo = 'CastVideo'
- Computer = 'Computer'
- GameConsole = 'GameConsole'
- STB = 'STB'
- Smartphone = 'Smartphone'
- Speaker = 'Speaker'
- TV = 'TV'
- Tablet = 'Tablet'
- Unknown = 'Unknown'
- audiodongle = 'AudioDongle'
- automobile = 'Automobile'
- avr = 'AVR'
- castaudio = 'CastAudio'
- castvideo = 'CastVideo'
- computer = 'Computer'
- gameconsole = 'GameConsole'
- smartphone = 'Smartphone'
- speaker = 'Speaker'
- stb = 'STB'
- tablet = 'Tablet'
- tv = 'TV'
- unknown = 'Unknown'
- class tekore.model.Actions(*, disallows)
Bases:
Model
Player actions.
- Parameters:
disallows (Disallows) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'disallows': FieldInfo(annotation=Disallows, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Disallows(*, interrupting_playback=False, pausing=False, resuming=False, seeking=False, skipping_next=False, skipping_prev=False, toggling_repeat_context=False, toggling_shuffle=False, toggling_repeat_track=False, transferring_playback=False)
Bases:
Model
Disallowed player actions.
- Parameters:
interrupting_playback (bool) –
pausing (bool) –
resuming (bool) –
seeking (bool) –
skipping_next (bool) –
skipping_prev (bool) –
toggling_repeat_context (bool) –
toggling_shuffle (bool) –
toggling_repeat_track (bool) –
transferring_playback (bool) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'interrupting_playback': FieldInfo(annotation=bool, required=False, default=False), 'pausing': FieldInfo(annotation=bool, required=False, default=False), 'resuming': FieldInfo(annotation=bool, required=False, default=False), 'seeking': FieldInfo(annotation=bool, required=False, default=False), 'skipping_next': FieldInfo(annotation=bool, required=False, default=False), 'skipping_prev': FieldInfo(annotation=bool, required=False, default=False), 'toggling_repeat_context': FieldInfo(annotation=bool, required=False, default=False), 'toggling_repeat_track': FieldInfo(annotation=bool, required=False, default=False), 'toggling_shuffle': FieldInfo(annotation=bool, required=False, default=False), 'transferring_playback': FieldInfo(annotation=bool, required=False, default=False)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.PlayerErrorReason(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
Reasons for errors in player actions.
- ALREADY_PAUSED = 'The command requires playback to not be paused.'
- ALREADY_PLAYING = 'The track should not be restarted if the same track and context is already playing, and there is a resume point.'
- CONTEXT_DISALLOW = 'The command could not be performed on the context.'
- DEVICE_NOT_CONTROLLABLE = 'Not possible to remote control the device.'
- ENDLESS_CONTEXT = 'The shuffle command cannot be applied on an endless context.'
- NOT_PAUSED = 'The command requires playback to be paused.'
- NOT_PLAYING_CONTEXT = 'The command requires that a context is currently playing.'
- NOT_PLAYING_LOCALLY = 'The command requires playback on the local device.'
- NOT_PLAYING_TRACK = 'The command requires that a track is currently playing.'
- NO_ACTIVE_DEVICE = 'Requires an active device and the user has none.'
- NO_NEXT_TRACK = 'The command requires a next track, but there is none in the context.'
- NO_PREV_TRACK = 'The command requires a previous track, but there is none in the context.'
- NO_SPECIFIC_TRACK = 'The requested track does not exist.'
- PREMIUM_REQUIRED = 'The request is prohibited for non-premium users.'
- RATE_LIMITED = 'The user is rate limited due to too frequent track play,also known as cat-on-the-keyboard spamming.'
- REMOTE_CONTROL_DISALLOW = 'The context cannot be remote-controlled.'
- UNKNOWN = 'Certain actions are restricted because of unknown reasons.'
- VOLUME_CONTROL_DISALLOW = 'Not possible to remote control the device’s volume.'
Play history
- class tekore.model.PlayHistory(*, track, played_at, context)
Bases:
Model
Previously played track.
Context is supposedly sometimes available.
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'context': FieldInfo(annotation=Union[Context, NoneType], required=True), 'played_at': FieldInfo(annotation=datetime, required=True), 'track': FieldInfo(annotation=FullTrack, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.PlayHistoryCursor(*, after, before)
Bases:
Cursor
Cursor to play history.
- Parameters:
after (str | None) –
before (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'after': FieldInfo(annotation=Union[str, NoneType], required=True), 'before': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.PlayHistoryPaging(*, href, items, limit, next, cursors)
Bases:
CursorPaging
Paging to play history.
Cursors are not available when paging is exhausted.
- Parameters:
href (str) –
items (List[PlayHistory]) –
limit (int) –
next (str | None) –
cursors (PlayHistoryCursor | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'cursors': FieldInfo(annotation=Union[PlayHistoryCursor, NoneType], required=True), 'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[PlayHistory], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Context(*, type, href, external_urls, uri)
Bases:
Model
Context of a played track or episode.
- Parameters:
type (ContextType) –
href (str) –
external_urls (dict) –
uri (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=ContextType, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Playlist
Playlist base. |
|
Track or episode on a playlist. |
|
Paging of playlist tracks. |
|
Simplified playlist object. |
|
Paging of simplified playlists. |
|
Complete playlist object. |
|
Track on a playlist. |
|
Episode on a playlist. |
|
Local track on a playlist. |
|
Base for local items. |
|
Album of a locally saved track. |
|
Artist of a locally saved track. |
|
Locally saved track. |
- class tekore.model.Playlist(*, id, href, type, uri, collaborative, description, external_urls, images, name, owner, public, snapshot_id, primary_color)
Bases:
Item
Playlist base.
owner
can beNone
on featured playlists.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
collaborative (bool) –
description (str | None) –
external_urls (dict) –
images (List[Image] | None) –
name (str) –
owner (PublicUser) –
public (bool | None) –
snapshot_id (str) –
primary_color (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'collaborative': FieldInfo(annotation=bool, required=True), 'description': FieldInfo(annotation=Union[str, NoneType], required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=Union[List[Image], NoneType], required=True), 'name': FieldInfo(annotation=str, required=True), 'owner': FieldInfo(annotation=PublicUser, required=True), 'primary_color': FieldInfo(annotation=Union[str, NoneType], required=True), 'public': FieldInfo(annotation=Union[bool, NoneType], required=True), 'snapshot_id': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.PlaylistTrack(*, added_at, added_by, is_local, track, primary_color, video_thumbnail)
Bases:
Model
Track or episode on a playlist.
- Parameters:
added_at (datetime) –
added_by (PublicUser) –
is_local (bool) –
track (FullPlaylistTrack | FullPlaylistEpisode | LocalPlaylistTrack | None) –
primary_color (str | None) –
video_thumbnail (dict | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'added_at': FieldInfo(annotation=datetime, required=True), 'added_by': FieldInfo(annotation=PublicUser, required=True), 'is_local': FieldInfo(annotation=bool, required=True), 'primary_color': FieldInfo(annotation=Union[str, NoneType], required=True), 'track': FieldInfo(annotation=Union[FullPlaylistTrack, FullPlaylistEpisode, LocalPlaylistTrack, NoneType], required=True), 'video_thumbnail': FieldInfo(annotation=Union[dict, NoneType], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.PlaylistTrackPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of playlist tracks.
- Parameters:
href (str) –
items (List[PlaylistTrack]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[PlaylistTrack], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimplePlaylist(*, id, href, type, uri, collaborative, description, external_urls, images, name, owner, public, snapshot_id, primary_color, tracks)
Bases:
Playlist
Simplified playlist object.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
collaborative (bool) –
description (str | None) –
external_urls (dict) –
images (List[Image] | None) –
name (str) –
owner (PublicUser) –
public (bool | None) –
snapshot_id (str) –
primary_color (str | None) –
tracks (Tracks) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'collaborative': FieldInfo(annotation=bool, required=True), 'description': FieldInfo(annotation=Union[str, NoneType], required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=Union[List[Image], NoneType], required=True), 'name': FieldInfo(annotation=str, required=True), 'owner': FieldInfo(annotation=PublicUser, required=True), 'primary_color': FieldInfo(annotation=Union[str, NoneType], required=True), 'public': FieldInfo(annotation=Union[bool, NoneType], required=True), 'snapshot_id': FieldInfo(annotation=str, required=True), 'tracks': FieldInfo(annotation=Tracks, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimplePlaylistPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of simplified playlists.
- Parameters:
href (str) –
items (List[SimplePlaylist | None]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[Union[SimplePlaylist, NoneType]], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullPlaylist(*, id, href, type, uri, collaborative, description, external_urls, images, name, owner, public, snapshot_id, primary_color, followers, tracks)
Bases:
Playlist
Complete playlist object.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
collaborative (bool) –
description (str | None) –
external_urls (dict) –
images (List[Image] | None) –
name (str) –
owner (PublicUser) –
public (bool | None) –
snapshot_id (str) –
primary_color (str | None) –
followers (Followers) –
tracks (PlaylistTrackPaging) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'collaborative': FieldInfo(annotation=bool, required=True), 'description': FieldInfo(annotation=Union[str, NoneType], required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'followers': FieldInfo(annotation=Followers, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=Union[List[Image], NoneType], required=True), 'name': FieldInfo(annotation=str, required=True), 'owner': FieldInfo(annotation=PublicUser, required=True), 'primary_color': FieldInfo(annotation=Union[str, NoneType], required=True), 'public': FieldInfo(annotation=Union[bool, NoneType], required=True), 'snapshot_id': FieldInfo(annotation=str, required=True), 'tracks': FieldInfo(annotation=PlaylistTrackPaging, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullPlaylistTrack(*, id, href, type, uri, artists, available_markets=None, disc_number, duration_ms, explicit, external_urls, is_local, is_playable=None, linked_from=None, name, preview_url, restrictions=None, track_number, album, external_ids, popularity, episode, track)
Bases:
FullTrack
Track on a playlist.
Provides
episode
andtrack
booleans to easily determine the type of playlist item.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
artists (List[SimpleArtist]) –
available_markets (List[str] | None) –
disc_number (int) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
is_local (Literal[False]) –
is_playable (bool | None) –
linked_from (TrackLink | None) –
name (str) –
preview_url (str | None) –
restrictions (Restrictions | None) –
track_number (int) –
album (SimpleAlbum) –
external_ids (dict) –
popularity (int) –
episode (Literal[False]) –
track (Literal[True]) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album': FieldInfo(annotation=SimpleAlbum, required=True), 'artists': FieldInfo(annotation=List[SimpleArtist], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'disc_number': FieldInfo(annotation=int, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'episode': FieldInfo(annotation=Literal[False], required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_ids': FieldInfo(annotation=dict, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'is_local': FieldInfo(annotation=Literal[False], required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'linked_from': FieldInfo(annotation=Union[TrackLink, NoneType], required=False, default=None), 'name': FieldInfo(annotation=str, required=True), 'popularity': FieldInfo(annotation=int, required=True), 'preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'track': FieldInfo(annotation=Literal[True], required=True), 'track_number': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullPlaylistEpisode(*, id, href, type, uri, audio_preview_url, description, duration_ms, explicit, external_urls, html_description, images, is_externally_hosted, is_playable=None, language=None, languages, name, release_date, release_date_precision, resume_point=None, restrictions=None, show, available_markets=None, episode, track)
Bases:
FullEpisode
Episode on a playlist.
Provides
episode
andtrack
booleans to easily determine the type of playlist item.available_markets
is undocumented.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
audio_preview_url (str | None) –
description (str) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
html_description (str) –
images (List[Image]) –
is_externally_hosted (bool) –
is_playable (bool | None) –
language (str | None) –
languages (List[str]) –
name (str) –
release_date (str) –
release_date_precision (ReleaseDatePrecision) –
resume_point (ResumePoint | None) –
restrictions (Restrictions | None) –
show (SimpleShow) –
available_markets (List[str] | None) –
episode (Literal[True]) –
track (Literal[False]) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'audio_preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'description': FieldInfo(annotation=str, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'episode': FieldInfo(annotation=Literal[True], required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=bool, required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'language': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'languages': FieldInfo(annotation=List[str], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=str, required=True), 'release_date_precision': FieldInfo(annotation=ReleaseDatePrecision, required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'resume_point': FieldInfo(annotation=Union[ResumePoint, NoneType], required=False, default=None), 'show': FieldInfo(annotation=SimpleShow, required=True), 'track': FieldInfo(annotation=Literal[False], required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Local items
Some playlists contain locally stored tracks. They contain mostly None values along with empty lists and dictionaries.
- class tekore.model.LocalPlaylistTrack(*, id, href, name, type, uri, album, artists, available_markets=None, disc_number, duration_ms, explicit, external_ids, external_urls, is_local, popularity, preview_url, track_number, episode=False, track=True)
Bases:
LocalTrack
Local track on a playlist.
Provides
episode
andtrack
booleans to easily determine the type of playlist item.- Parameters:
id (None) –
href (None) –
name (str) –
type (str) –
uri (str) –
album (LocalAlbum) –
artists (List[LocalArtist]) –
available_markets (List[None]) –
disc_number (int) –
duration_ms (int | dict) –
explicit (bool) –
external_ids (dict) –
external_urls (dict) –
is_local (Literal[True]) –
popularity (int) –
preview_url (None) –
track_number (int) –
episode (Literal[False]) –
track (Literal[True]) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album': FieldInfo(annotation=LocalAlbum, required=True), 'artists': FieldInfo(annotation=List[LocalArtist], required=True), 'available_markets': FieldInfo(annotation=List[NoneType], required=False, default_factory=list), 'disc_number': FieldInfo(annotation=int, required=True), 'duration_ms': FieldInfo(annotation=Union[int, dict], required=True), 'episode': FieldInfo(annotation=Literal[False], required=False, default=False), 'explicit': FieldInfo(annotation=bool, required=True), 'external_ids': FieldInfo(annotation=dict, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=NoneType, required=True), 'id': FieldInfo(annotation=NoneType, required=True), 'is_local': FieldInfo(annotation=Literal[True], required=True), 'name': FieldInfo(annotation=str, required=True), 'popularity': FieldInfo(annotation=int, required=True), 'preview_url': FieldInfo(annotation=NoneType, required=True), 'track': FieldInfo(annotation=Literal[True], required=False, default=True), 'track_number': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.LocalItem(*, id, href, name, type, uri)
Bases:
Model
Base for local items.
- Parameters:
id (None) –
href (None) –
name (str) –
type (str) –
uri (None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=NoneType, required=True), 'id': FieldInfo(annotation=NoneType, required=True), 'name': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=NoneType, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.LocalAlbum(*, id, href, name, type, uri, album_type, artists, available_markets=None, external_urls, images, release_date, release_date_precision)
Bases:
LocalItem
Album of a locally saved track.
- Parameters:
id (None) –
href (None) –
name (str) –
type (str) –
uri (None) –
album_type (None) –
artists (List[None]) –
available_markets (List[None]) –
external_urls (dict) –
images (List[None]) –
release_date (None) –
release_date_precision (None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album_type': FieldInfo(annotation=NoneType, required=True), 'artists': FieldInfo(annotation=List[NoneType], required=True), 'available_markets': FieldInfo(annotation=List[NoneType], required=False, default_factory=list), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=NoneType, required=True), 'id': FieldInfo(annotation=NoneType, required=True), 'images': FieldInfo(annotation=List[NoneType], required=True), 'name': FieldInfo(annotation=str, required=True), 'release_date': FieldInfo(annotation=NoneType, required=True), 'release_date_precision': FieldInfo(annotation=NoneType, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=NoneType, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.LocalArtist(*, id, href, name, type, uri, external_urls)
Bases:
LocalItem
Artist of a locally saved track.
- Parameters:
id (None) –
href (None) –
name (str) –
type (str) –
uri (None) –
external_urls (dict) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=NoneType, required=True), 'id': FieldInfo(annotation=NoneType, required=True), 'name': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=NoneType, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.LocalTrack(*, id, href, name, type, uri, album, artists, available_markets=None, disc_number, duration_ms, explicit, external_ids, external_urls, is_local, popularity, preview_url, track_number)
Bases:
LocalItem
Locally saved track.
Locally saved track where most attributes are always None, empty, zero or False.
duration_ms
being an object is undocumented.- Parameters:
id (None) –
href (None) –
name (str) –
type (str) –
uri (str) –
album (LocalAlbum) –
artists (List[LocalArtist]) –
available_markets (List[None]) –
disc_number (int) –
duration_ms (int | dict) –
explicit (bool) –
external_ids (dict) –
external_urls (dict) –
is_local (Literal[True]) –
popularity (int) –
preview_url (None) –
track_number (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album': FieldInfo(annotation=LocalAlbum, required=True), 'artists': FieldInfo(annotation=List[LocalArtist], required=True), 'available_markets': FieldInfo(annotation=List[NoneType], required=False, default_factory=list), 'disc_number': FieldInfo(annotation=int, required=True), 'duration_ms': FieldInfo(annotation=Union[int, dict], required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_ids': FieldInfo(annotation=dict, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=NoneType, required=True), 'id': FieldInfo(annotation=NoneType, required=True), 'is_local': FieldInfo(annotation=Literal[True], required=True), 'name': FieldInfo(annotation=str, required=True), 'popularity': FieldInfo(annotation=int, required=True), 'preview_url': FieldInfo(annotation=NoneType, required=True), 'track_number': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Recommendation
Track recommendations. |
|
Recommendation seeds. |
|
Attributes available in recommendations. |
- class tekore.model.Recommendations(*, seeds, tracks)
Bases:
Model
Track recommendations.
- Parameters:
seeds (List[RecommendationSeed]) –
tracks (List[FullTrack]) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'seeds': FieldInfo(annotation=List[RecommendationSeed], required=True), 'tracks': FieldInfo(annotation=List[FullTrack], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.RecommendationSeed(*, id, afterFilteringSize, afterRelinkingSize, href, initialPoolSize, type)
Bases:
Identifiable
Recommendation seeds.
- Parameters:
id (str) –
afterFilteringSize (int) –
afterRelinkingSize (int) –
href (str | None) –
initialPoolSize (int) –
type (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'afterFilteringSize': FieldInfo(annotation=int, required=True), 'afterRelinkingSize': FieldInfo(annotation=int, required=True), 'href': FieldInfo(annotation=Union[str, NoneType], required=True), 'id': FieldInfo(annotation=str, required=True), 'initialPoolSize': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.RecommendationAttribute(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
StrEnum
Attributes available in recommendations.
- acousticness = 'acousticness'
- danceability = 'danceability'
- duration_ms = 'duration_ms'
- energy = 'energy'
- instrumentalness = 'instrumentalness'
- key = 'key'
- liveness = 'liveness'
- loudness = 'loudness'
- mode = 'mode'
- popularity = 'popularity'
- speechiness = 'speechiness'
- tempo = 'tempo'
- time_signature = 'time_signature'
- valence = 'valence'
Show
Show base. |
|
Simplified show object. |
|
Paging of simplified shows. |
|
Complete show object. |
|
Show saved in library. |
|
Paging of shows in library. |
- class tekore.model.Show(*, id, href, type, uri, available_markets=None, copyrights, description, explicit, external_urls, html_description=None, images, is_externally_hosted, languages, media_type, name, publisher, total_episodes=None)
Bases:
Item
Show base.
publisher
being an object is undocumented.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
available_markets (List[str]) –
copyrights (List[Copyright]) –
description (str) –
explicit (bool) –
external_urls (dict) –
html_description (str | None) –
images (List[Image]) –
is_externally_hosted (bool | None) –
languages (List[str]) –
media_type (str) –
name (str) –
publisher (str | dict) –
total_episodes (int | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'available_markets': FieldInfo(annotation=List[str], required=False, default_factory=list), 'copyrights': FieldInfo(annotation=List[Copyright], required=True), 'description': FieldInfo(annotation=str, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=Union[bool, NoneType], required=True), 'languages': FieldInfo(annotation=List[str], required=True), 'media_type': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'publisher': FieldInfo(annotation=Union[str, dict], required=True), 'total_episodes': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleShow(*, id, href, type, uri, available_markets=None, copyrights, description, explicit, external_urls, html_description=None, images, is_externally_hosted, languages, media_type, name, publisher, total_episodes=None)
Bases:
Show
Simplified show object.
total_episodes
is undocumented by Spotify, so it might be missing or removed in a future version.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
available_markets (List[str]) –
copyrights (List[Copyright]) –
description (str) –
explicit (bool) –
external_urls (dict) –
html_description (str | None) –
images (List[Image]) –
is_externally_hosted (bool | None) –
languages (List[str]) –
media_type (str) –
name (str) –
publisher (str | dict) –
total_episodes (int | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'available_markets': FieldInfo(annotation=List[str], required=False, default_factory=list), 'copyrights': FieldInfo(annotation=List[Copyright], required=True), 'description': FieldInfo(annotation=str, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=Union[bool, NoneType], required=True), 'languages': FieldInfo(annotation=List[str], required=True), 'media_type': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'publisher': FieldInfo(annotation=Union[str, dict], required=True), 'total_episodes': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleShowPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of simplified shows.
- Parameters:
href (str) –
items (List[SimpleShow]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SimpleShow], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullShow(*, id, href, type, uri, available_markets=None, copyrights, description, explicit, external_urls, html_description=None, images, is_externally_hosted, languages, media_type, name, publisher, total_episodes=None, episodes=None)
Bases:
Show
Complete show object.
total_episodes
is undocumented by Spotify, so it might be missing or removed in a future version.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
available_markets (List[str]) –
copyrights (List[Copyright]) –
description (str) –
explicit (bool) –
external_urls (dict) –
html_description (str | None) –
images (List[Image]) –
is_externally_hosted (bool | None) –
languages (List[str]) –
media_type (str) –
name (str) –
publisher (str | dict) –
total_episodes (int | None) –
episodes (SimpleEpisodePaging | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'available_markets': FieldInfo(annotation=List[str], required=False, default_factory=list), 'copyrights': FieldInfo(annotation=List[Copyright], required=True), 'description': FieldInfo(annotation=str, required=True), 'episodes': FieldInfo(annotation=Union[SimpleEpisodePaging, NoneType], required=False, default=None), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'html_description': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=List[Image], required=True), 'is_externally_hosted': FieldInfo(annotation=Union[bool, NoneType], required=True), 'languages': FieldInfo(annotation=List[str], required=True), 'media_type': FieldInfo(annotation=str, required=True), 'name': FieldInfo(annotation=str, required=True), 'publisher': FieldInfo(annotation=Union[str, dict], required=True), 'total_episodes': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedShow(*, added_at, show)
Bases:
Model
Show saved in library.
- Parameters:
added_at (datetime) –
show (SimpleShow) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'added_at': FieldInfo(annotation=datetime, required=True), 'show': FieldInfo(annotation=SimpleShow, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedShowPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of shows in library.
- Parameters:
href (str) –
items (List[SavedShow]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SavedShow], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Track
Track base. |
|
Simplified track object. |
|
Paging of simplified tracks. |
|
Complete track object. |
|
Paging of full tracks. |
|
Track saved to library. |
|
Paging of tracks in library. |
|
Minimal representation of playlist tracks. |
|
Relinked track. |
|
Restrictions on relinked resource. |
|
Track audio analysis. |
|
Generic representation of an interval. |
|
Analysis of a track's section. |
|
Analysis of a track's segment. |
|
Features of a track. |
- class tekore.model.Track(*, id, href, type, uri, artists, available_markets=None, disc_number, duration_ms, explicit, external_urls, is_local, is_playable=None, linked_from=None, name, preview_url, restrictions=None, track_number)
Bases:
Item
Track base.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
artists (List[SimpleArtist]) –
available_markets (List[str] | None) –
disc_number (int) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
is_local (bool) –
is_playable (bool | None) –
linked_from (TrackLink | None) –
name (str) –
preview_url (str | None) –
restrictions (Restrictions | None) –
track_number (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'artists': FieldInfo(annotation=List[SimpleArtist], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'disc_number': FieldInfo(annotation=int, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'is_local': FieldInfo(annotation=bool, required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'linked_from': FieldInfo(annotation=Union[TrackLink, NoneType], required=False, default=None), 'name': FieldInfo(annotation=str, required=True), 'preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'track_number': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleTrack(*, id, href, type, uri, artists, available_markets=None, disc_number, duration_ms, explicit, external_urls, is_local, is_playable=None, linked_from=None, name, preview_url, restrictions=None, track_number)
Bases:
Track
Simplified track object.
When market is specified,
available_markets
is not available.is_playable
is not available when market is not specified.restrictions
is available if restrictions have been placed on the track, making it unplayable.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
artists (List[SimpleArtist]) –
available_markets (List[str] | None) –
disc_number (int) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
is_local (bool) –
is_playable (bool | None) –
linked_from (TrackLink | None) –
name (str) –
preview_url (str | None) –
restrictions (Restrictions | None) –
track_number (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'artists': FieldInfo(annotation=List[SimpleArtist], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'disc_number': FieldInfo(annotation=int, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'is_local': FieldInfo(annotation=bool, required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'linked_from': FieldInfo(annotation=Union[TrackLink, NoneType], required=False, default=None), 'name': FieldInfo(annotation=str, required=True), 'preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'track_number': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SimpleTrackPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of simplified tracks.
- Parameters:
href (str) –
items (List[SimpleTrack]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SimpleTrack], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullTrack(*, id, href, type, uri, artists, available_markets=None, disc_number, duration_ms, explicit, external_urls, is_local, is_playable=None, linked_from=None, name, preview_url, restrictions=None, track_number, album, external_ids, popularity)
Bases:
Track
Complete track object.
When market is specified,
available_markets
is not available.is_playable
is not available when market is not specified.restrictions
is available if restrictions have been placed on the track, making it unplayable.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
artists (List[SimpleArtist]) –
available_markets (List[str] | None) –
disc_number (int) –
duration_ms (int) –
explicit (bool) –
external_urls (dict) –
is_local (bool) –
is_playable (bool | None) –
linked_from (TrackLink | None) –
name (str) –
preview_url (str | None) –
restrictions (Restrictions | None) –
track_number (int) –
album (SimpleAlbum) –
external_ids (dict) –
popularity (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'album': FieldInfo(annotation=SimpleAlbum, required=True), 'artists': FieldInfo(annotation=List[SimpleArtist], required=True), 'available_markets': FieldInfo(annotation=Union[List[str], NoneType], required=False, default=None), 'disc_number': FieldInfo(annotation=int, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'explicit': FieldInfo(annotation=bool, required=True), 'external_ids': FieldInfo(annotation=dict, required=True), 'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'is_local': FieldInfo(annotation=bool, required=True), 'is_playable': FieldInfo(annotation=Union[bool, NoneType], required=False, default=None), 'linked_from': FieldInfo(annotation=Union[TrackLink, NoneType], required=False, default=None), 'name': FieldInfo(annotation=str, required=True), 'popularity': FieldInfo(annotation=int, required=True), 'preview_url': FieldInfo(annotation=Union[str, NoneType], required=True), 'restrictions': FieldInfo(annotation=Union[Restrictions, NoneType], required=False, default=None), 'track_number': FieldInfo(annotation=int, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.FullTrackPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of full tracks.
- Parameters:
href (str) –
items (List[FullTrack]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[FullTrack], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedTrack(*, added_at, track)
Bases:
Model
Track saved to library.
- Parameters:
added_at (datetime) –
track (FullTrack) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'added_at': FieldInfo(annotation=datetime, required=True), 'track': FieldInfo(annotation=FullTrack, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.SavedTrackPaging(*, href, items, limit, next, total, offset, previous)
Bases:
OffsetPaging
Paging of tracks in library.
- Parameters:
href (str) –
items (List[SavedTrack]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=List[SavedTrack], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Tracks(*, href, total)
Bases:
Model
Minimal representation of playlist tracks.
- Parameters:
href (str) –
total (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.TrackLink(*, id, href, type, uri, external_urls)
Bases:
Item
Relinked track.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
external_urls (dict) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'external_urls': FieldInfo(annotation=dict, required=True), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Restrictions(*, reason)
Bases:
Model
Restrictions on relinked resource.
- Parameters:
reason (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'reason': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Audio analysis
- class tekore.model.AudioAnalysis(*, bars, beats, sections, segments, tatums, meta, track)
Bases:
Model
Track audio analysis.
See the Web API documentation for more details.
- Parameters:
bars (List[TimeInterval]) –
beats (List[TimeInterval]) –
sections (List[Section]) –
segments (List[Segment]) –
tatums (List[TimeInterval]) –
meta (dict) –
track (dict) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'bars': FieldInfo(annotation=List[TimeInterval], required=True), 'beats': FieldInfo(annotation=List[TimeInterval], required=True), 'meta': FieldInfo(annotation=dict, required=True), 'sections': FieldInfo(annotation=List[Section], required=True), 'segments': FieldInfo(annotation=List[Segment], required=True), 'tatums': FieldInfo(annotation=List[TimeInterval], required=True), 'track': FieldInfo(annotation=dict, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.TimeInterval(*, duration, start=None, confidence=None)
Bases:
Model
Generic representation of an interval.
Attributes are sometimes not available.
- Parameters:
duration (float) –
start (float | None) –
confidence (float | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'confidence': FieldInfo(annotation=Union[float, NoneType], required=False, default=None), 'duration': FieldInfo(annotation=float, required=True), 'start': FieldInfo(annotation=Union[float, NoneType], required=False, default=None)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Section(*, duration, loudness, tempo, tempo_confidence, key_confidence, mode_confidence, time_signature, time_signature_confidence, confidence=None, mode=None, key=None, start=None)
Bases:
Model
Analysis of a track’s section.
Attributes are sometimes not available.
- Parameters:
duration (float) –
loudness (float) –
tempo (float) –
tempo_confidence (float) –
key_confidence (float) –
mode_confidence (float) –
time_signature (int) –
time_signature_confidence (float) –
confidence (float | None) –
mode (int | None) –
key (int | None) –
start (float | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'confidence': FieldInfo(annotation=Union[float, NoneType], required=False, default=None), 'duration': FieldInfo(annotation=float, required=True), 'key': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'key_confidence': FieldInfo(annotation=float, required=True), 'loudness': FieldInfo(annotation=float, required=True), 'mode': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'mode_confidence': FieldInfo(annotation=float, required=True), 'start': FieldInfo(annotation=Union[float, NoneType], required=False, default=None), 'tempo': FieldInfo(annotation=float, required=True), 'tempo_confidence': FieldInfo(annotation=float, required=True), 'time_signature': FieldInfo(annotation=int, required=True), 'time_signature_confidence': FieldInfo(annotation=float, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Segment(*, duration, loudness_start, loudness_max, pitches, timbre, confidence=None, loudness_end=None, loudness_max_time=None, start=None)
Bases:
Model
Analysis of a track’s segment.
Attributes are sometimes not available.
- Parameters:
duration (float) –
loudness_start (float) –
loudness_max (float) –
pitches (List[float]) –
timbre (List[float]) –
confidence (float | None) –
loudness_end (float | None) –
loudness_max_time (float | None) –
start (float | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'confidence': FieldInfo(annotation=Union[float, NoneType], required=False, default=None), 'duration': FieldInfo(annotation=float, required=True), 'loudness_end': FieldInfo(annotation=Union[float, NoneType], required=False, default=None), 'loudness_max': FieldInfo(annotation=float, required=True), 'loudness_max_time': FieldInfo(annotation=Union[float, NoneType], required=False, default=None), 'loudness_start': FieldInfo(annotation=float, required=True), 'pitches': FieldInfo(annotation=List[float], required=True), 'start': FieldInfo(annotation=Union[float, NoneType], required=False, default=None), 'timbre': FieldInfo(annotation=List[float], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Audio features
- class tekore.model.AudioFeatures(*, id, acousticness, analysis_url, danceability, duration_ms, energy, instrumentalness, key, liveness, loudness, mode, speechiness, tempo, time_signature, track_href, type, uri, valence)
Bases:
Identifiable
Features of a track.
- Parameters:
id (str) –
acousticness (float) –
analysis_url (str) –
danceability (float) –
duration_ms (int) –
energy (float) –
instrumentalness (float) –
key (int) –
liveness (float) –
loudness (float) –
mode (int) –
speechiness (float) –
tempo (float) –
time_signature (int) –
track_href (str) –
type (str) –
uri (str) –
valence (float) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'acousticness': FieldInfo(annotation=float, required=True), 'analysis_url': FieldInfo(annotation=str, required=True), 'danceability': FieldInfo(annotation=float, required=True), 'duration_ms': FieldInfo(annotation=int, required=True), 'energy': FieldInfo(annotation=float, required=True), 'id': FieldInfo(annotation=str, required=True), 'instrumentalness': FieldInfo(annotation=float, required=True), 'key': FieldInfo(annotation=int, required=True), 'liveness': FieldInfo(annotation=float, required=True), 'loudness': FieldInfo(annotation=float, required=True), 'mode': FieldInfo(annotation=int, required=True), 'speechiness': FieldInfo(annotation=float, required=True), 'tempo': FieldInfo(annotation=float, required=True), 'time_signature': FieldInfo(annotation=int, required=True), 'track_href': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True), 'valence': FieldInfo(annotation=float, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
User
User base. |
|
User as viewable by anyone. |
|
User with private information. |
|
Explicit content filter of a user. |
- class tekore.model.User(*, id, href, type, uri, external_urls, display_name=None, followers=None, images=None)
Bases:
Item
User base.
display_name
,followers
andimages
may not be available.- Parameters:
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'display_name': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'external_urls': FieldInfo(annotation=dict, required=True), 'followers': FieldInfo(annotation=Union[Followers, NoneType], required=False, default=None), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=Union[List[Image], NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.PublicUser(*, id, href, type, uri, external_urls, display_name=None, followers=None, images=None)
Bases:
User
User as viewable by anyone.
- Parameters:
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'display_name': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'external_urls': FieldInfo(annotation=dict, required=True), 'followers': FieldInfo(annotation=Union[Followers, NoneType], required=False, default=None), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=Union[List[Image], NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.PrivateUser(*, id, href, type, uri, external_urls, display_name=None, followers=None, images=None, country=None, email=None, explicit_content=None, product=None, birthday=None)
Bases:
User
User with private information.
country
,explicit_content
andproduct
require theuser-read-private
scope.email
requires theuser-read-email
scope.birthday
is unavailable unless the now-invaliduser-read-birthdate
scope was granted to the token.- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
external_urls (dict) –
display_name (str | None) –
followers (Followers | None) –
images (List[Image] | None) –
country (str | None) –
email (str | None) –
explicit_content (ExplicitContent | None) –
product (str | None) –
birthday (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'birthday': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'country': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'display_name': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'email': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'explicit_content': FieldInfo(annotation=Union[ExplicitContent, NoneType], required=False, default=None), 'external_urls': FieldInfo(annotation=dict, required=True), 'followers': FieldInfo(annotation=Union[Followers, NoneType], required=False, default=None), 'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'images': FieldInfo(annotation=Union[List[Image], NoneType], required=False, default=None), 'product': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.ExplicitContent(*, filter_enabled, filter_locked)
Bases:
Model
Explicit content filter of a user.
- Parameters:
filter_enabled (bool) –
filter_locked (bool) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'filter_enabled': FieldInfo(annotation=bool, required=True), 'filter_locked': FieldInfo(annotation=bool, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Miscellaneous
Copyright. |
|
Followers. |
|
Image link and information. |
|
Precision of a release date. |
- class tekore.model.Copyright(*, text, type)
Bases:
Model
Copyright.
- Parameters:
text (str) –
type (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'text': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Followers(*, href, total)
Bases:
Model
Followers.
href
is alwaysNone
.- Parameters:
href (None) –
total (int) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=NoneType, required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Image(*, url, height, width)
Bases:
Model
Image link and information.
The Web API documentation reports that
height
andwidth
can beNone
or not available in the response.- Parameters:
url (str) –
height (int | None) –
width (int | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'height': FieldInfo(annotation=Union[int, NoneType], required=True), 'url': FieldInfo(annotation=str, required=True), 'width': FieldInfo(annotation=Union[int, NoneType], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Model bases
Response model base. |
|
The response model contains an unknown attribute. |
|
Object identified with a Spotify ID. |
|
Identifiable with additional fields. |
|
Paging base. |
|
Offset paging base. |
|
Data cursor. |
|
Cursor paging base. |
Functionality
- class tekore.model.Model
Bases:
BaseModel
Response model base.
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.UnknownModelAttributeWarning
Bases:
RuntimeWarning
The response model contains an unknown attribute.
Models
- class tekore.model.Identifiable(*, id)
Bases:
Model
Object identified with a Spotify ID.
- Parameters:
id (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'id': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Item(*, id, href, type, uri)
Bases:
Identifiable
Identifiable with additional fields.
- Parameters:
id (str) –
href (str) –
type (str) –
uri (str) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'id': FieldInfo(annotation=str, required=True), 'type': FieldInfo(annotation=str, required=True), 'uri': FieldInfo(annotation=str, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Paging(*, href, items, limit, next)
Bases:
Model
Paging base.
- Parameters:
href (str) –
items (Sequence[Model]) –
limit (int) –
next (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=Sequence[Model], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.OffsetPaging(*, href, items, limit, next, total, offset, previous)
Bases:
Paging
Offset paging base.
Paging that can be navigated both forward and back.
- Parameters:
href (str) –
items (Sequence[Model]) –
limit (int) –
next (str | None) –
total (int) –
offset (int) –
previous (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=Sequence[Model], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True), 'offset': FieldInfo(annotation=int, required=True), 'previous': FieldInfo(annotation=Union[str, NoneType], required=True), 'total': FieldInfo(annotation=int, required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.Cursor(*, after)
Bases:
Model
Data cursor.
- Parameters:
after (str | None) –
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'after': FieldInfo(annotation=Union[str, NoneType], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- class tekore.model.CursorPaging(*, href, items, limit, next, cursors)
Bases:
Paging
Cursor paging base.
Paging that can be navigated only forward following the cursor.
- Parameters:
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'cursors': FieldInfo(annotation=Cursor, required=True), 'href': FieldInfo(annotation=str, required=True), 'items': FieldInfo(annotation=Sequence[Model], required=True), 'limit': FieldInfo(annotation=int, required=True), 'next': FieldInfo(annotation=Union[str, NoneType], required=True)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
Member types
- class tekore.model.StrEnum(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
str
,Enum
Convert enumeration members to strings using their name.
Ignores case when getting items. This does not change values.
Senders
Manipulate the way clients send requests.
Send requests synchronously. |
|
Send requests asynchronously. |
|
Retry requests if unsuccessful. |
|
Cache successful GET requests. |
See also Other classes.
Senders provide a hook between
defining a request and sending it to the Web API.
The sender of a Client
also determines whether synchronous or
asynchronous calls are used to send requests and process responses.
Sender instances are passed to a client at initialisation.
import tekore as tk
tk.Credentials(*conf, sender=tk.SyncSender())
tk.Spotify(sender=tk.RetryingSender())
Senders wrap around the httpx
library
and accept additional keyword arguments to httpx.Client()
.
proxies = {
'http': 'http://10.10.10.10:8000',
'https': 'http://10.10.10.10:8000',
}
tk.SyncSender(proxies=proxies)
Instances of httpx.Client
or httpx.AsyncClient
can also be passed in for a finer control over sender behaviour.
from httpx import Client
client = Client(proxies=proxies)
tk.SyncSender(client)
Concrete senders
Final senders in a possible chain that concretely make the request to Spotify.
- class tekore.SyncSender(client=None)
Bases:
Sender
Send requests synchronously.
Warning
The underlying client is not closed automatically. Use
sender.client.close()
to close it, particularly if multiple senders are instantiated.- Parameters:
client (Client) –
httpx.Client
to use when sending requests
- close()
Close the underlying synchronous client.
- Return type:
None
- property is_async: bool
Sender asynchronicity, always
False
.
- class tekore.AsyncSender(client=None)
Bases:
Sender
Send requests asynchronously.
Warning
The underlying client is not closed automatically. Use
await sender.client.aclose()
to close it, particularly if multiple senders are instantiated.- Parameters:
client (AsyncClient) –
httpx.AsyncClient
to use when sending requests
- async close()
Close the underlying asynchronous client.
- Return type:
None
- property is_async: bool
Sender asynchronicity, always
True
.
Extending senders
Senders that extend the functionality of other senders.
- class tekore.RetryingSender(retries=0, sender=None)
Bases:
ExtendingSender
Retry requests if unsuccessful.
On server errors the set amount of retries are used to resend requests. On
TooManyRequests
the Retry-After header is checked and used to wait before requesting again.Note
Even when the number of retries is set to zero, retries based on rate limiting are still performed.
- Parameters:
retries (int) – maximum number of retries on server errors before giving up
sender (Sender) – request sender,
SyncSender
if not specified
Examples
Use for only rate limiting by leaving the retry count to zero.
tk.RetryingSender()
Pass the maximum number of retries to retry failed requests.
tk.RetryingSender(retries=3)
- class tekore.CachingSender(max_size=None, sender=None)
Bases:
ExtendingSender
Cache successful GET requests.
The Web API provides response headers for caching. Resources are cached based on Cache-Control, ETag and Vary headers. Thus
CachingSender
can be used with user tokens too. Resources marked as private, errors andVary: *
are not cached.When using asynchronous senders, the cache is protected with
asyncio.Lock
to prevent concurrent access. The lock is instantiated on the first asynchronous call, so using only oneasyncio.run()
(per sender) is advised.Note that if the cache has no maximum size it can grow without limit. Use
CachingSender.clear()
to empty the cache.- Parameters:
max_size (int) – maximum cache size (amount of responses), if specified the least recently used response is discarded when the cache would overflow
sender (Sender) – request sender,
SyncSender
if not specified
- clear()
Clear sender cache.
- Return type:
None
- property max_size: int | None
Maximum amount of requests stored in the cache.
- Returns:
maximum cache size
- Return type:
Optional[int]
Other classes
Bases for subclassing or other endeavours.
Sender interface for requests. |
|
Base class for senders that extend other senders. |
|
Sender arguments to a client are in conflict. |
|
Base class for clients. |
|
Wrapper for parameters of a HTTP request. |
|
Wrapper for result of a HTTP request. |
- class tekore.Sender
Bases:
ABC
Sender interface for requests.
- abstract close()
Close underlying client.
- Return type:
None | Coroutine[None, None, None]
- abstract property is_async: bool
Sender asynchronicity mode.
- class tekore.ExtendingSender(sender)
Bases:
Sender
Base class for senders that extend other senders.
- Parameters:
sender (Sender | None) – request sender,
SyncSender
if not specified
- close()
Close the underlying sender.
To close synchronous senders, call
close()
. To close asynchronous senders, awaitclose()
.- Return type:
None | Coroutine[None, None, None]
- property is_async: bool
Sender asynchronicity, delegated to the underlying sender.
- class tekore.SenderConflictWarning
Bases:
RuntimeWarning
Sender arguments to a client are in conflict.
- class tekore.Client(sender, asynchronous=None)
Bases:
ExtendingSender
Base class for clients.
- Parameters:
sender (Sender | None) – request sender - If not specified, a
SyncSender
is usedasynchronous (bool) – synchronicity requirement - If specified, overrides passed sender if they are in conflict and instantiates a sender of the requested type
- class tekore.Request(method, url, params=None, headers=None, data=None, json=None, content=None)
Wrapper for parameters of a HTTP request.
- Parameters:
method (str) –
url (str) –
params (dict | None) –
headers (dict | None) –
data (dict | None) –
json (dict | None) –
content (str | None) –
- class tekore.Response(url, headers, status_code, content)
Wrapper for result of a HTTP request.
- Parameters:
url (str) –
headers (dict) –
status_code (int) –
content (dict | None) –
Getting started
To use the Web API, you’ll need to register an application. From its page retrieve the client ID and secret. They are your application’s credentials to the API. A walkthrough of creating an application and setting it up can be found here.
Retrieving a client token
First we’ll retrieve a client token for the Spotify application. It is a token associated with your application and can be used to make basic calls to the API.
import tekore as tk
client_id = 'your_id_here'
client_secret = 'your_secret_here'
app_token = tk.request_client_token(client_id, client_secret)
Calling the API
Next the Spotify object should be created. The following script will list the track numbers and names of songs on an album given the album ID.
spotify = tk.Spotify(app_token)
album = spotify.album('3RBULTZJ97bvVzZLpxcB0j')
for track in album.tracks.items:
print(track.track_number, track.name)
Response attributes can be directly accessed with dot notation as above. To quickly inspect a response or any part of it, print its contents.
print(album)
print(album.artists[0])
Retrieving a user token
Many endpoints require user authorisation, for which another type of access token is needed. User tokens are associated with a Spotify user account.
Retrieving them requires some more setting up.
A redirect URI should be whitelisted in application settings.
It is the address to which users are redirected
after authorising the application.
Alternatively, the default redirect URI https://example.com/callback
can be used with a client with no other redirect URIs whitelisted.
Different privileges or scopes can be requested when authorising. Below we’ll retrieve a token that has every possible scope. The script will open a web page prompting for a Spotify login. The user is then redirected back to the whitelisted redirect URI. Paste the redirected URI in full to the shell to finalise token retrieval.
redirect_uri = 'your_uri_here'
user_token = tk.prompt_for_user_token(
client_id,
client_secret,
redirect_uri,
scope=tk.scope.every
)
Note
prompt_for_user_token()
eliminates the need for a web server,
which would normally be used to complete authorisation,
by requesting the user to manually enter information to the shell.
However, that also makes it unusable on a server.
Other authorisation methods are introduced in Authorisation guide.
Calling the API as a user
The following script replaces the application token with a user token and lists some of the user’s most listened tracks.
spotify.token = user_token
tracks = spotify.current_user_top_tracks(limit=10)
for track in tracks.items:
print(track.name)
The snippet below will play Sibelius’ Finlandia if the user has a recently used Spotify application open. If no active device is found, an error is thrown.
finlandia = '3hHWhvw2hjwfngWcFjIzqr'
spotify.playback_start_tracks([finlandia])
Saving the configuration
Currently, we need to go through the authorisation process every time the script is run. Let’s save the configuration to avoid this in the future.
conf = (client_id, client_secret, redirect_uri, user_token.refresh_token)
tk.config_to_file('tekore.cfg', conf)
Now we can replace the authorisation lines with reconstructing the token.
conf = tk.config_from_file('tekore.cfg', return_refresh=True)
user_token = tk.refresh_user_token(*conf[:2], conf[3])
Note
This approach is not scalable to multi-user scenarios. See Authorisation guide for more information.
How to read the documentation
The reference documentation is built for easy navigation.
Each endpoint (like playback
) contains
a description, required and optional scopes, arguments and return information.
Notably, the return type often contains a link to the relevant response model.
Follow them to discover the attributes that a model has.
Further links can be followed down the model hierarchy.
What’s next?
Our Authorisation guide details different authorisation options. Advanced usage provides an overview of things to keep in mind when building an actual application and what Tekore has to offer for that. You could also have a look at some example scripts to start familiarising yourself with the Web API.
Advanced usage
Client options
The client provides options and toggles to customise behavior in a variety of ways.
Maximise limits
The Web API limits the number of resources returned in many endpoints. By default, these limits are below their maximum values, matching API defaults. However, they can be maximised when instantiating a client or as a context.
import tekore as tk
spotify = tk.Spotify(max_limits_on=True)
spotify.max_limits_on = False
with spotify.max_limits():
tracks = spotify.all_items(spotify.search('piano')[0])
Chunked requests
Endpoints that accept lists of resources often limit the amount of items that can be passed in. To help with this restriction, those lists can be chunked.
spotify = tk.Spotify(chunked_on=True)
spotify.chunked_on = False
with spotify.chunked():
pass # Go nuts with e.g. spotify.artists_follow
Application configuration
It is generally advisable to separate configuration from code, and more importantly keep secrets outside public version control. To facilitate that, environment variables and configuration files can be used to provide application credentials. Set values in your environment or write a configuration file, then read the configuration.
export SPOTIFY_CLIENT_ID=your_id
export SPOTIFY_CLIENT_SECRET=your_secret
export SPOTIFY_REDIRECT_URI=your_uri
[DEFAULT]
SPOTIFY_CLIENT_ID=your_id
SPOTIFY_CLIENT_SECRET=your_secret
SPOTIFY_REDIRECT_URI=your_uri
client_id, client_secret, redirect_uri = tk.config_from_environment()
client_id, client_secret, redirect_uri = tk.config_from_file(filename)
These values can then be used to retrieve access tokens. Note that if all configuration values are defined, it is possible to use unpacking to provide the configuration.
conf = tk.config_from_environment()
cred = tk.Credentials(*conf)
Configuring a user refresh token is also possible.
Define SPOTIFY_USER_REFRESH
and pass in a boolean flag
to read it as a fourth configuration value.
tk.config_from_environment(return_refresh=True)
Configuration files can be written too. This is handy if a user’s refresh token needs to be stored.
tk.config_to_file(filename, (id_, secret, uri, refresh))
For more information see Configuration.
Customising request behavior
By default Tekore doesn’t do anything clever when sending requests. Its functionality, however, can be extended in a number of ways using different kinds of senders. Builtin senders can be used for retrying and caching.
Keepalive connections, retries and caching make up a performance-boosting and convenient setup, easily constructed from simple building blocks. Less errors, less requests and faster responses, particularly for busy applications that request the same static resources repeatedly.
sender = tk.CachingSender(
max_size=256,
sender=tk.RetryingSender(retries=2)
)
tk.Spotify(sender=sender)
At the lowest level, SyncSender
and AsyncSender
accept
httpx.Client
instances which can further customise behavior.
For example, setting longer request timeouts and retrying on connection errors
is possible with the following setup.
import httpx
trans = httpx.HTTPTransport(retries=3)
client = httpx.Client(timeout=30, transport=trans)
sender = tk.SyncSender(client=client)
With an async sender use httpx.AsyncClient
and
httpx.AsyncHTTPTransport
instead.
Traversing paging objects
Many Web API endpoints that would return a large number of the same type of object return paging objects for performance reasons. The client defines a few ways to navigate these pagings. Next and previous pages can be requested one at a time.
import tekore as tk
spotify = tk.Spotify(token)
items = spotify.playlist_items('37i9dQZEVXbMDoHDwVN2tF', limit=10)
t_next = spotify.next(items)
t_prev = spotify.previous(t_next)
To retrieve the whole content additional methods are available.
pages = spotify.all_pages(items)
items = spotify.all_items(items)
Async support
Tekore provides support for asynchronous programming with async-await.
Async mode may be enabled when instantiating a Client
.
tk.Credentials(*conf, asynchronous=True)
tk.Spotify(token, asynchronous=True)
Alternatively, an asynchronous sender may be passed directly into a client.
spotify = tk.Spotify(token, sender=tk.AsyncSender())
Note
The boolean parameter above overrides any conflicting sender that is set as default or simultaneously passed in to the client.
Now every call to an endpoint returns an awaitable instead of a response.
asyncio
can then be used to execute asynchronous requests.
See Senders and Examples for more information.
import asyncio
async def now_playing():
return await spotify.playback_currently_playing()
np = asyncio.run(now_playing())
Asynchronous execution can also be used for quick bursts of calls when combined
with asyncio.gather()
. See Scrape playlist artists for an example.
While asynchronous Credentials
is supported, it is worth considering
that concurrently refreshing tokens may lead to multiple refreshes for one token.
Synchronous credentials clients are recommended.
Note
Client context managers are async safe, meaning that they can be used in many tasks without affecting the state of other tasks. However, setting values outside of all contexts modifies the persistent value directly, and as such may affect other tasks.
Dynamic scoping
Gradually expanding token scopes and methods that “know” their associated
scopes can be used to dynamically expand user scopes in a web application.
Unauthorised
carries the scope information from failing calls
and can then be used to redirect users to authorise again.
@app.get("/endpoint")
def endpoint():
try:
spotify.playback()
except tk.Unauthorised as e:
return Redirect("/login?scope=" + str(e.scope))
Combined with refreshing the token on arrival to have the full scope and additionally redirecting the user back after authorisation, even static HTML applications using a Python backend become simple to implement.
Short links
The Spotify emits shortened URLs for e.g. playlists when sharing them
through the mobile application. Unfortunately, they are not usable as
they are, but they can be expanded to their full form. Tekore provides
two utilities for processing them: is_short_link()
and
Spotify.follow_short_link()
.
link = '...'
if is_short_link(link):
link = spotify.follow_short_link(link)
type, id_ = from_url(link)
Localisation
Many API calls that retrieve track information accept a market
or
country
parameter with which only tracks or albums available in that
market are returned. This sometimes changes track IDs as well.
When calling with a user token, this country code can also be
from_token
, in which case the results are for the user’s locale.
spotify.search('sheeran', market='SE')
spotify.search('horse', market='from_token')
In addition to returning results relevant to a specific market, results can be requested in specific languages. This is helpful for example in viewing names with non-latin alphabet.
from httpx import Client
client = Client(headers={'Accept-Language': 'ru'})
spotify = tk.Spotify(token, sender=tk.SyncSender(client))
artist = spotify.artist('2LbinT29RFLaXOGAN0jfQN')
print(artist.name)
Examples
Here are some things you could do with Tekore, enjoy!
Artist follower
This script will find all the artists you aren’t already following from your playlists, and prompt you to do so.
import tekore as tk
conf = tk.config_from_environment()
scope = [
tk.scope.user_follow_read,
tk.scope.user_follow_modify,
tk.scope.playlist_read_private
]
user_token = tk.prompt_for_user_token(*conf, scope=scope)
s = tk.Spotify(user_token, max_limits_on=True, chunked_on=True)
def prompt_user(what: str) -> bool:
while True:
resp = input(f"{what} [Y/n]: ").strip()
if resp.lower() == "y" or resp == "":
return True
elif resp.lower() == "n":
return False
artists = set()
for playlist in s.all_items(s.followed_playlists()):
if not prompt_user(f"Analyze playlist '{playlist.name}'?"):
continue
for item in s.all_items(s.playlist_items(playlist.id)):
if not item.track.track or item.track.is_local:
continue
for artist in item.track.artists:
artists.add((artist.id, artist.name))
ids = [a[0] for a in artists]
names = [a[1] for a in artists]
following = s.artists_is_following(ids)
for id_, name, status in zip(ids, names, following):
if status:
print(f"Skipping '{name}' as it's already being followed.")
continue
if not prompt_user(f"Follow '{name}'?"):
continue
s.artists_follow([id_])
print(f"Followed '{name}'.")
Async server
The following scripts starts up a simple AIOHTTP web server for song search.
Run the script and navigate to localhost:5000
to see the main page.
Enter search terms to the address bar to search for songs.
Asynchronous programming is particularly handy in web server contexts.
This is a small example, but the bottleneck of this server is Spotify’s API.
Therefore at larger scale more requests can be served
using this configuration than the synchronous counterpart.
To demonstrate this, one can insert an artificial delay to the search call.
First import asyncio
, then insert await asyncio.sleep(10)
somewhere in the function.
When searching in parallel (e.g. with two browser tabs) one should observe that
requests take about ten seconds, no matter how many are sent at once.
import tekore as tk
from aiohttp import web
conf = tk.config_from_environment()
token = tk.request_client_token(*conf[:2])
spotify = tk.Spotify(token, asynchronous=True)
routes = web.RouteTableDef()
@routes.get('/')
async def main(_) -> web.Response:
html = '<br>'.join([
'Enter text in the address bar to search for songs!',
'Search terms should be separated by plus signs.',
'For example:',
'host:5000/monty+python',
'host:5000/bright+side',
])
return web.Response(text=html, content_type='text/html')
@routes.get('/{search}')
async def search(request: web.Request) -> web.Response:
# await asyncio.sleep(10)
try:
query = request.match_info['search'].replace('+', ' ')
tracks, = await spotify.search(query, limit=5)
items = [t.artists[0].name + ': ' + t.name for t in tracks.items]
html = '<br>'.join(items)
return web.Response(text=html, content_type='text/html')
except Exception:
return web.Response(text='An error occured while searching!')
app = web.Application()
app.add_routes(routes)
web.run_app(app, port=5000)
Authenticating server
The scripts below detail how to start up a simple authentication sever.
In this example the configured redirect URI must match
http://localhost:5000/callback
and be whitelisted in your
application settings.
Note that the server need not be accessible from the web.
With a server that is hosted elsewhere
or one that needs to be accessible from outside,
whitelist another redirect URI that matches the server’s address.
Run the script and navigate to localhost:5000
to see your user ID.
It should be None
before logging in.
During login you will be redirected to authenticate at Spotify.
If access is granted and the state security check passes,
another redirection via /callback
to an info page will be performed.
It should read “successful” and refer you back to the main page.
You should now see a generated user ID and your currently playing track.
The ID is saved to your session cookies and preserved during navigation.
Logging out deletes the cookie and server-stored access token.
Note
The auths
dictionary could be used to store arbitrary information.
In this example it is used to map the state parameters
of ongoing authorisations to UserAuth
objects.
import tekore as tk
from flask import Flask, request, redirect, session
conf = tk.config_from_environment()
cred = tk.Credentials(*conf)
spotify = tk.Spotify()
auths = {} # Ongoing authorisations: state -> UserAuth
users = {} # User tokens: state -> token (use state as a user ID)
in_link = '<a href="/login">login</a>'
out_link = '<a href="/logout">logout</a>'
login_msg = f'You can {in_link} or {out_link}'
def app_factory() -> Flask:
app = Flask(__name__)
app.config['SECRET_KEY'] = 'aliens'
@app.route('/', methods=['GET'])
def main():
user = session.get('user', None)
token = users.get(user, None)
# Return early if no login or old session
if user is None or token is None:
session.pop('user', None)
return f'User ID: None<br>{login_msg}'
page = f'User ID: {user}<br>{login_msg}'
if token.is_expiring:
token = cred.refresh(token)
users[user] = token
try:
with spotify.token_as(token):
playback = spotify.playback_currently_playing()
item = playback.item.name if playback else None
page += f'<br>Now playing: {item}'
except tk.HTTPError:
page += '<br>Error in retrieving now playing!'
return page
@app.route('/login', methods=['GET'])
def login():
if 'user' in session:
return redirect('/', 307)
scope = tk.scope.user_read_currently_playing
auth = tk.UserAuth(cred, scope)
auths[auth.state] = auth
return redirect(auth.url, 307)
@app.route('/callback', methods=['GET'])
def login_callback():
code = request.args.get('code', None)
state = request.args.get('state', None)
auth = auths.pop(state, None)
if auth is None:
return 'Invalid state!', 400
token = auth.request_token(code, state)
session['user'] = state
users[state] = token
return redirect('/', 307)
@app.route('/logout', methods=['GET'])
def logout():
uid = session.pop('user', None)
if uid is not None:
users.pop(uid, None)
return redirect('/', 307)
return app
if __name__ == '__main__':
application = app_factory()
application.run('127.0.0.1', 5000)
import uvicorn
import tekore as tk
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse, HTMLResponse
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key="secret_key_placeholder")
conf = tk.config_from_environment()
cred = tk.Credentials(*conf)
spotify = tk.Spotify()
auths = {} # Ongoing authorisations: state -> UserAuth
users = {} # User tokens: state -> token (use state as a user ID)
in_link = '<a href="/login">login</a>'
out_link = '<a href="/logout">logout</a>'
login_msg = f"You can {in_link} or {out_link}"
@app.get("/", response_class=HTMLResponse)
def read_root(request: Request):
user = request.session.get("user", None)
token = users.get(user, None)
# Return early if no login or old session
if user is None or token is None:
request.session.pop("user", None)
return f"User ID: None<br>{login_msg}"
page = f"User ID: {user}<br>{login_msg}"
if token.is_expiring:
token = cred.refresh(token)
users[user] = token
try:
with spotify.token_as(token):
playback = spotify.playback_currently_playing()
item = playback.item.name if playback else None
page += f"<br>Now playing: {item}"
except tk.HTTPError:
page += "<br>Error in retrieving now playing!"
return HTMLResponse(content=page, status_code=200)
@app.get("/login")
def login(request: Request):
if "user" in request.session:
return RedirectResponse(url="/")
scope = tk.scope.user_read_currently_playing
auth = tk.UserAuth(cred, scope)
auths[auth.state] = auth
return RedirectResponse(auth.url)
@app.get("/callback")
def login_callback(request: Request, code: str, state: str):
auth = auths.pop(state, None)
if auth is None:
return "Invalid state!", 400
token = auth.request_token(code, state)
request.session["user"] = state
users[state] = token
return RedirectResponse("/")
@app.get("/logout")
def logout(request: Request):
uid = request.session.pop("user", None)
if uid is not None:
users.pop(uid, None)
return RedirectResponse("/")
if __name__ == "__main__":
uvicorn.run(
"main:app",
port=5000,
host="0.0.0.0",
reload=True,
)
Creating local scripts
The examples below give a framework for creating scripts to be run locally.
First we specify our client configuration and authorise a user. Once complete, the configuration is written to a file, along with the user’s refresh token which can be used to spawn new tokens without authorising again.
Note
The code below uses the default redirect URI
https://example.com/callback
, which doesn’t need to be configured.
However, if another redirect URI has been configured, it will not work.
import tekore as tk
client_id = 'your_client_id'
client_secret = 'your_client_secret'
redirect_uri = 'https://example.com/callback' # Or your redirect uri
conf = (client_id, client_secret, redirect_uri)
file = 'tekore.cfg'
token = tk.prompt_for_user_token(*conf, scope=tk.scope.every)
tk.config_to_file(file, conf + (token.refresh_token,))
That file can then be read whenever a script is started,
and a refreshed token requested without user interaction.
Thanks to the self-refreshing tokens returned by refresh_user_token()
,
even long-running scripts can simply use the same token indefinitely.
Note
When only application tokens are needed, client_id
and
client_secret
can be written to a file without initial authorisation.
import tekore as tk
file = 'tekore.cfg'
conf = tk.config_from_file(file, return_refresh=True)
token = tk.refresh_user_token(*conf[:2], conf[3])
spotify = tk.Spotify(token)
print(spotify.current_user_top_artists())
The same principle applies to configuration residing in the system environment,
which can be accessed with config_from_environment()
,
though configuration cannot be written to environment variables.
These snippets could also be combined to a single script
checking for the existence of configuration or even just the refresh token
to decide whether a new authorisation is needed or not.
Discord bot
The following example script creates a simple Discord bot that can be used to search tracks.
A bot account is required for sending messages in Discord. A quickstart guide for setting up a bot can be found here.
Once the bot is added to the server
users can call it with the prefix >tk track
.
The bot responds to the query by sending a brief summary of the search results.
Queries can be for example:
>tk track Sheeran
>tk track "Monty Python"
import tekore as tk
from discord import Game, Embed
from discord.ext import commands
token_discord = "your_discord_token"
conf = tk.config_from_environment()
token_spotify = tk.request_client_token(*conf[:2])
description = "Spotify track search bot using Tekore"
bot = commands.Bot(command_prefix='>tk ', description=description, activity=Game(name=">tk help"))
spotify = tk.Spotify(token_spotify, asynchronous=True)
@bot.command()
async def track(ctx, *, query: str = None):
if query is None:
await ctx.send("No search query specified")
return
tracks, = await spotify.search(query, limit=5)
embed = Embed(title="Track search results", color=0x1DB954)
embed.set_thumbnail(url="https://i.imgur.com/890YSn2.png")
embed.set_footer(text="Requested by " + ctx.author.display_name)
for t in tracks.items:
artist = t.artists[0].name
url = t.external_urls["spotify"]
message = "\n".join([
"[Spotify](" + url + ")",
":busts_in_silhouette: " + artist,
":cd: " + t.album.name
])
embed.add_field(name=t.name, value=message, inline=False)
await ctx.send(embed=embed)
@bot.event
async def on_ready():
print("Ready to demo!")
if __name__ == "__main__":
bot.run(token_discord)
Snippets
Here are some example snippets for various use cases. Fair warning, some of them perform (harmless and small) actions on your behalf.
Albums of user’s top artist
The following script shows the albums of one of your top artists.
It assumes that your credentials are saved in the environment and you have used Spotify enough to have top artists.
import tekore as tk
conf = tk.config_from_environment()
scope = tk.scope.user_top_read
token = tk.prompt_for_user_token(*conf, scope=scope)
spotify = tk.Spotify(token)
artist = spotify.current_user_top_artists(limit=1).items[0]
albums = spotify.artist_albums(artist.id)
print(f'Albums of {artist.name}:')
for a in albums.items:
print(a.release_date, a.name)
Analyse track from playlist
The following script retrieves a track from one of your playlists and analyses its features.
It assumes that your credentials are saved in the environment and you have followed or created at least one playlist and it has a track on it. Podcast episodes or a locally saved tracks are ignored, because they cannot be analysed.
import tekore as tk
conf = tk.config_from_environment()
token = tk.prompt_for_user_token(*conf)
spotify = tk.Spotify(token)
playlist = spotify.followed_playlists(limit=1).items[0]
track = spotify.playlist_items(playlist.id, limit=1).items[0].track
name = f'"{track.name}" from {playlist.name}'
if track.episode:
print(f'Cannot analyse episodes!\nGot {name}.')
elif track.track and track.is_local:
print(f'Cannot analyse local tracks!\nGot {name}.')
else:
print(f'Analysing {name}...\n')
analysis = spotify.track_audio_features(track.id)
print(repr(analysis))
Follow with a search
The following script searches for an artist and prompts the user to follow the first match.
It assumes that your credentials are saved in the environment.
import tekore as tk
conf = tk.config_from_environment()
scope = tk.scope.user_follow_modify
token = tk.prompt_for_user_token(*conf, scope=scope)
spotify = tk.Spotify(token)
search = input('Search for an artist: ')
artists, = spotify.search(search, types=('artist',), limit=1)
artist = artists.items[0]
follow = input(f'Follow {artist.name}? (y/n) ')
if follow.lower() == 'y':
spotify.artists_follow([artist.id])
print(f'{artist.name} followed.')
else:
print('Follow cancelled.')
Follow category playlist
The following script retrieves a Spotify playlist in one of the preset categories and follows it as the current user.
It assumes that your credentials are saved in the environment.
import tekore as tk
conf = tk.config_from_environment()
scope = tk.scope.playlist_modify_private
token = tk.prompt_for_user_token(*conf, scope=scope)
spotify = tk.Spotify(token)
category = spotify.categories(limit=1).items[0]
playlist = spotify.category_playlists(category.id, limit=1).items[0]
print(f'Following "{playlist.name}"" from category "{category.name}"...')
spotify.playlist_follow(playlist.id, public=False)
Play saved album
The following script plays one of your saved albums.
It assumes that your credentials are saved in the environment, there is at least one album saved in your library, and you have an active Spotify application open.
import tekore as tk
conf = tk.config_from_environment()
scope = tk.scope.user_library_read + tk.scope.user_modify_playback_state
token = tk.prompt_for_user_token(*conf, scope=scope)
spotify = tk.Spotify(token)
album = spotify.saved_albums(limit=1).items[0].album
album_uri = tk.to_uri('album', album.id)
spotify.playback_start_context(album_uri)
Recommended tracks playlist
The following script recommends songs based on your top tracks and creates a playlist from them.
It assumes that your credentials are saved in the environment and you have used Spotify enough to have top tracks.
import tekore as tk
conf = tk.config_from_environment()
scope = tk.scope.user_top_read + tk.scope.playlist_modify_private
token = tk.prompt_for_user_token(*conf, scope=scope)
spotify = tk.Spotify(token)
top_tracks = spotify.current_user_top_tracks(limit=5).items
top_track_ids = [t.id for t in top_tracks]
recommendations = spotify.recommendations(track_ids=top_track_ids).tracks
user = spotify.current_user()
playlist = spotify.playlist_create(
user.id,
'Tekore Recommendations',
public=False,
description='Recommendations based on your top tracks <3'
)
uris = [t.uri for t in recommendations]
spotify.playlist_add(playlist.id, uris=uris)
Scrape playlist artists
The following script retrieves all tracks of your playlists and aggregates the most common artists by total track count.
It assumes that your credentials are saved in the environment and
you have followed or created at least one playlist.
For this example, the artist of podcast episodes is the name of the show.
To avoid errors when hitting rate limits, a RetryingSender
is used.
import asyncio
import tekore as tk
from collections import Counter
conf = tk.config_from_environment()
scope = tk.scope.playlist_read_private
token = tk.prompt_for_user_token(*conf, scope=scope)
def get_artist(track) -> str:
if track.episode:
return track.show.name
else:
return track.artists[0].name
Asynchronous functions can be used to achieve a faster runtime
when making lots of parallelisable calls to the API.
A series of asynchronous calls alone does not help much, but the calls can be
parallelised with asyncio.gather()
.
The code is more complex, but with bigger workloads more time is saved.
async def count_artists(spotify: tk.Spotify, playlist_id: str):
tracks = await spotify.playlist_items(playlist_id)
tracks = spotify.all_items(tracks)
return Counter([get_artist(t.track) async for t in tracks])
async def main() -> Counter:
sender = tk.RetryingSender(sender=tk.AsyncSender())
spotify = tk.Spotify(token, sender=sender, max_limits_on=True)
playlists = await spotify.followed_playlists()
playlists = spotify.all_items(playlists)
counts = [await count_artists(spotify, p.id) async for p in playlists]
await spotify.close()
return sum(counts, Counter())
artists = asyncio.run(main())
for name, count in artists.most_common(3):
print(count, name)
async def count_artists(spotify: tk.Spotify, playlist_id: str):
tracks_paging = await spotify.playlist_items(playlist_id)
paging_len = len(tracks_paging.items)
track_calls = [
spotify.playlist_items(playlist_id, offset=ofs)
for ofs in range(paging_len, tracks_paging.total, paging_len)
]
pages = [tracks_paging] + await asyncio.gather(*track_calls)
tracks = sum([page.items for page in pages], [])
return Counter([get_artist(t.track) for t in tracks])
async def main() -> Counter:
sender = tk.RetryingSender(sender=tk.AsyncSender())
spotify = tk.Spotify(token, sender=sender, max_limits_on=True)
playlists_paging = await spotify.followed_playlists()
paging_len = len(playlists_paging.items)
playlist_calls = [
spotify.followed_playlists(offset=ofs)
for ofs in range(paging_len, playlists_paging.total, paging_len)
]
pages = [playlists_paging] + await asyncio.gather(*playlist_calls)
playlists = sum([page.items for page in pages], [])
count_calls = [count_artists(spotify, p.id) for p in playlists]
counts = await asyncio.gather(*count_calls)
await spotify.close()
return sum(counts, Counter())
artists = asyncio.run(main())
for name, count in artists.most_common(3):
print(count, name)
Tracks of a new release
The following script shows the tracks of a newly released album.
It assumes that your credentials are saved in the environment and there is at least new release in the Spotify catalogue.
import tekore as tk
conf = tk.config_from_environment()
token = tk.request_client_token(*conf[:2])
spotify = tk.Spotify(token)
simple_album = spotify.new_releases(limit=1).items[0]
album = spotify.album(simple_album.id)
print(f'Songs from {album.album_type} {album.name}:')
for t in album.tracks.items:
print(t.track_number, '-', t.name)
Additional resources
This documentation covers the most important aspects of the Web API, but for in-depth tutorials, guides and reference, Spotify’s own resources are strongly recommended.
App Settings - walkthrough of creating and configuring an application
Authorisation Guide - detailed view of authorisation methods
Web API Reference - reference documentation of all endpoints
Track Relinking Guide - about track availability within markets and how tracks are relinked to user markets
Working With Playlists - playlist semantics and properties