:snake: A simple library to fetch data from the iTunes Store API made for Python >= 3.5

Overview

itunespy PyPI version

itunespy is a simple library to fetch data from the iTunes Store API made for Python 3.5 and beyond.

Important: Since version 1.6 itunespy no longer supports versions below Python 3.5. You can still use any previous versions but those won't get any further updates or features.

Installing

You can install it from pip:

pip install itunespy

Or you can simply clone this project anywhere in your computer:

git clone https://github.com/sleepyfran/itunespy.git

And then enter the cloned repo and execute:

python setup.py install

Dependencies

itunespy requires Requests and pycountry installed.

Examples and information

Search an artist and show all its album's names:

import itunespy

artist = itunespy.search_artist('Steven Wilson')  # Returns a list
albums = artist[0].get_albums()  # Get albums from the first result

for album in albums:
    print(album.collection_name)

Or search an album and show all its song's names and length, and finally the album length:

import itunespy

album = itunespy.search_album('One Hour By The Concrete Lake')  # Returns a list
tracks = album[0].get_tracks()  # Get tracks from the first result

for track in tracks:
    print(track.artist_name + ': ' + track.track_name + str(track.get_track_time_minutes()))
print('Total playing time: ' + str(album[0].get_album_time()))

Or search for a track:

import itunespy

track = itunespy.search_track('Iter Impius')  # Returns a list
print(track[0].artist_name + ': ' + track[0].track_name + ' | Length: ' + str(track[0].get_track_time_minutes())) # Get info from the first result

Or ebook authors:

import itunespy

author = itunespy.search_book_author('Fyodor Dostoevsky')  # Search for Dostoevsky

books = author[0].get_books()  # Get books from the firs result

for book in books:
    print(book.track_name)  # Show each book's name

Or software:

import itunespy

telegram = itunespy.search_software('Telegram')

print(telegram[0].track_name)  # Prints 'Telegram Messenger'

Basically, every search_ method is just an alias for a general search with certain parameters to make your life easier.

I made the basic ones, if you miss any, make an issue and provide information about the type you want added.

You can also perform a lookup:

import itunespy

lookup = itunespy.lookup(upc=720642462928) # Lookup for the Weezer's album 'Weezer'

for item in lookup:
    print(item.artist_name + ': ' + item.collection_name)

Since every search or lookup can return more than one object type, every object in the returned list has a 'type' property, so you can check if it's an artist, album or track like this:

import itunespy

lookup = itunespy.lookup(id=428011728)  # Steven Wilson's ID

for l in lookup:
    if l.type == 'artist':
        print('Artist!')
        print(l.artist_type)  # Since it's an artist, you can also check its artist type

For a complete list, take a look at the wrapperType and kind documentation in the iTunes API's site.

Each request has some parameters that you need to know. Searches has these:

term: The URL-encoded text string you want to search for. Example: Steven Wilson.
        The function will take care of spaces so you don't have to.
country: The two-letter country code for the store you want to search.
        For a full list of the codes: http://en.wikipedia.org/wiki/%20ISO_3166-1_alpha-2
media: The media type you want to search for. Since this module is made for music I recommend leaving it blank.
entity: The type of results you want returned, relative to the specified media type. Example: musicArtist.
        Full list: musicArtist, musicTrack, album, musicVideo, mix, song
attribute: The attribute you want to search for in the stores, relative to the specified media type.
limit: The number of search results you want the iTunes Store to return.

Note: Only the term is obligatory, the other ones have default values that will be used in case you don't provide any. Note 2: In specific searches, like search_artist or search_album, etc, don't change entity, since it's configured inside the function to retrieve an specific entity.

For lookups, the same parameters apply except for term, which changes to a couple of id fields:

id: iTunes ID of the artist/album/track
artist_amg_id: All Music Guide ID of the artist
upc: UPCs/EANs

Every search and lookup will always return a list of result_item instances, except if it's an artist, album, movie artist or an ebook author, which inheritates from result_item but has extra methods, like get_albums in music_artist. Each object has their own variables, following the iTunes API names adapted to Python syntax.

To take a look at all of this simply go to the item_result class.

Contributing

I'm accepting any pull request to improve or fix anything in the library, just fork the project and hack it!

Comments
  • [Feature Request] Add a setter method for track_time

    [Feature Request] Add a setter method for track_time

    Hey there, thanks for the nice project!

    I am the developer of ytmdl and my project has been dependent on your library since the beginning.

    It was later that I noticed that the track_time property of the songs are returned in miliseconds, however, my requirement was to get them in seconds, so I added a bit of code that updates the track_time value and then passed the whole results container along.

    It was working all nice and well until the last release. You made the move to change track_time to a property and it turns out the property doesn't have a setter method which is why my code was unable to update the track_time value and so as a result a lot of users started facing the issue.

    However, a few days ago a fellow user pointed out the issue to me and I found out about the latest release that broke my code.

    I just wanted to request to please add a setter method for the track_time property so that I can go back to using all the latest releases as currently I have forced the version 1.5.5 in the setup.

    Cheers! Thanks for the awesome library, really appreciate it.

    enhancement 
    opened by deepjyoti30 5
  • Possible to to download movies ?

    Possible to to download movies ?

    is it possible to download movies that i bought with python and sync it with the library ? iTunes produce horrible speeds ..i tried with IDM but that don't work bcs i can't play the file maybe library sync issue .

    question 
    opened by dualriposte 3
  • Add country support for sub-queries

    Add country support for sub-queries

    When searching the iTunes API it is possible to specify a country. This way one might get a MusicAlgum from the _get_result_list method. Using the get_tracks method on such an album will lookup the album. This however does not retain the country that was initially specified. For albums that are not available on the default (US) iTunes Store this causes get_tracks to effectively fail (no results are returned).

    This pull request adds the country field to ResultItem and retains the country from a search or lookup operation in the respective results. It also modifies the get_tracks method to lookup tracks in the same country that the MusicAlbum belongs to.

    opened by codello 2
  • Way to search by ISRC?

    Way to search by ISRC?

    I'm using the Spotify and iTunes API together and need a way to guarantee the results returned from each are the same. I haven't found a way to search by ISRC with your wrapper but maybe I missed something.

    question 
    opened by kylesurowiec 2
  • taking song that not matches the given id

    taking song that not matches the given id

    This is the code I used to search the specific song. I couldn't figure out where the error would be in the itunespy code .

    import itunespy
    
    
    def main():
        #working song
        #broken arrows avici https://music.apple.com/us/album/stories/1440834059
        #id_number = '1440834528'
    
        #tragic the kid laroy https://music.apple.com/gb/album/tragic-feat-youngboy-never-broke-again-internet-money/1538646756?i=1538647031
        id_number = '1538647031'
        #actiall id itunespy looks up 341728831
    
        track_info = itunespy.lookup(id=id_number)
        album_info = itunespy.lookup(id=track_info[0].collectionId)
    
        track = itunespy.search_track('arrows')
        print(track[0].artist_name + ': ' + track[0].track_name + ' | Length: ' + str(
            track[0].get_track_time_minutes()))  # Get info from the first result
    
    if __name__ == '__main__':
        main()
    
    opened by JensDeLeersnyderPXL 1
  • Asynchronous version

    Asynchronous version

    Hi would it be possible to make an async version with aiohttp? I would modify it myself but I'm fairly new to python so if it's something you're willing to do I'd be grateful. Otherwise if you could point me in the right direction that'd be good too.

    opened by describe19 1
  • Type hints and more

    Type hints and more

    This pull request includes a number of things:

    • Type annotations for every function
    • URL escaping via urllib.parse. This has the following implications:
      • Simpler Code
      • Fixes a bug where if only the artist_amg_id or only the ups was specified for a lookup operation the function would raise an error.
      • Fixes a bug where special characters in search term or other query parameters would not be properly escaped.
    • Dynamic property access in ResultItem this makes it easier to support any new attributes added to the iTunes Search API. Known attributes are included as type hints to help type checkers and IDEs.
    • A new Artist class that is made the superclass of all artist types. The main purpose of this is to provide a more intuitive way to type hint any artist (which is needed search_director for example).
    • The __repr__ function now returns the underlying JSON object of a ResultItem.
    • A Github Actions Workflow that checks the consistency of type annotations via MyPy.
    • Drop support for Python 3.4

    I did try to make all of the changes backwards compatible. The following functions may behave slightly differently:

    • Performing lookups and searches does not raise an error anymore if the artist_amg_id or ups is not a str (at least in some cases). I consider this a bugfix.
    • collection_type, artist_type and track_type are now available in a ResultItem even if it does not have a wrapperType. This is to provide a more consistent interface allowing to query arbitrary fields in a result.
    • The __repr__ function of ResultItems now returns a different value.
    opened by codello 1
  • Documentation Clarification

    Documentation Clarification

    hi in your code file, it states a string to be passed... but in your README.md you use an integer...

    Could you please clarify which value type?

    --------

    def lookup(id=None, artist_amg_id=None, upc=None, country='US', media='all', entity=None, attribute=None, limit=50): """ Returns the result of the lookup of the specified id, artist_amg_id or upc in an array of result_item(s) :param id: String. iTunes ID of the artist, album, track, ebook or software :param artist_amg_id: String. All Music Guide ID of the artist :param upc: String. UPCs/EANs :param country: String. The two-letter country code for the store you want to search. For a full list of the codes: http://en.wikipedia.org/wiki/%20ISO_3166-1_alpha-2 :param media: String. The media type you want to search for. Example: music :param entity: String. The type of results you want returned, relative to the specified media type. Example: musicArtist. Full list: musicArtist, musicTrack, album, musicVideo, mix, song :param attribute: String. The attribute you want to search for in the stores, relative to the specified media type. :param limit: Integer. The number of search results you want the iTunes Store to return. :return: An array of result_item(s) """

    question 
    opened by jasonkolodziej 1
Releases(1.6)
  • 1.6(May 13, 2020)

    Thanks to the wonderful @codello who did all the amazing work on this release! ๐Ÿ‘


    • ๐Ÿ”ฅ Breaking: This version and further versions of itunespy will NOT support any Python version below 3.5. If you need to use this library in any other version you can use itunespy <= 1.5.5 but those won't get any support or new features.
    • ๐Ÿ”ฅ Breaking: __repr__ now returns a different value (see below) so make sure you don't use this in a non-compatible way before updating.

    • ๐Ÿ˜„ Type hints are now available throughout the code
    • ๐Ÿ˜„ collection_type, artist_type and track_type are now available in a ResultItem even if it does not have a wrapperType. This is to provide a more consistent interface allowing to query arbitrary fields in a result.
    • ๐Ÿ˜„ __repr__ now returns the underlying JSON object of a ResultItem.
    • ๐Ÿ˜„ ResultItem now has a get_country() method for converting between country code formats via pycountry.
    • ๐Ÿ› The country specified in a query is now preserved in any sub-query. Example: Specifying a country via search_artist will now retain that same country when doing a get_albums.
    • ๐Ÿ› Performing lookups and searches does not raise an error anymore if the artist_amg_id or ups is not a str.
    • ๐Ÿ› Fixed cases in which special characters in search terms or other query parameters would not be properly escaped.
    Source code(tar.gz)
    Source code(zip)
  • 1.5.5(Oct 7, 2015)

  • v1.5(Sep 2, 2015)

    • ๐Ÿ˜„ Now you can get a Track time in minutes and hours using get_track_time_minutes() and get_track_time_hours()
    • ๐Ÿ˜„ The function get_tracks() in MusicAlbum now stores all tracks in _track_list if it's empty
    • ๐Ÿ˜„ You can also get the full playing time of an album using get_album_time()
    • ๐Ÿ˜„ search_director and search_movie implemented
    Source code(tar.gz)
    Source code(zip)
  • v1.3(Aug 23, 2015)

    • ๐Ÿ”ฅ Breaking: This new release deprecates the use of artist_genre_name and artist_genre_id in favor of primary_genre_name and primary_genre_id since those properties can be in artists, albums, tracks and more.
    Source code(tar.gz)
    Source code(zip)
Owner
Fran Gonzรกlez
Music, code, repeat.
Fran Gonzรกlez
Instagram boosting

instagram boosting bot This bot can boost your instagram account! Rules and Instruction Use git clone to download this repository Open cmd/terminal an

Eskimo 4 Oct 20, 2022
A jokes api python module

A jokes api python module

Fayas Noushad 3 Nov 28, 2021
Fetch information about a public Google document.

xeuledoc Fetch information about any public Google document. It's working on : Google Docs Google Spreadsheets Google Slides Google Drawning Google My

Malfrats Industries 655 Jan 03, 2023
Grade Notifyer Bot

A bot that automatically crawl the submission platform of montefiore to notify the student when a project has been graded.

Julien Gustin 2 Jun 02, 2022
A python package that fetches tweets and user information in a very pythonic manner.

Tweetsy Tweetsy uses Twitter's underlying API to fetch user information and tweets and present it in a human-friendly way. What makes Tweetsy special

Sakirul Alam 5 Nov 12, 2022
A program that generates discord.py code

discord-py-generator A program that generates discord.py code Setup in cmds.txt file add your user id, client id and bot token you can change the bot

3 Dec 15, 2022
Embed the Duktape JS interpreter in Python

Introduction Pyduktape is a python wrapper around Duktape, an embeddable Javascript interpreter. On top of the interpreter wrapper, pyduktape offers e

Stefano 78 Dec 15, 2022
A Telegram Bot to display Codeforces Contest Ranklist

CFRankListBot A bot that displays the top ranks for a Codeforces contest. Participants' Details All the details of a participant is in the utils/__ini

Code IIEST 5 Dec 25, 2021
A battle-tested Django 2.1 project template with configurations for AWS, Heroku, App Engine, and Docker.

For information on how to use this project template, check out the wiki. {{ project_name }} Table of Contents Requirements Local Setup Local Developme

Lionheart Software 64 Jun 15, 2022
๐Ÿค– A discord bot for Dota2 community

BOTA BOT-A is a free Discord Dota 2 bot which provides comprehensive Information of every Dota 2 characters and exciting features for the community. P

Bendang 23 Jun 29, 2022
use python script to fix vmp dump api in ida

FixVmpDump use python script to fix vmp dump api in ida. support x86 and x64. details in my blog: https://blog.csdn.net/yan_star/article/details/11279

97 Nov 02, 2022
Autofill HZDR Zeitman entries

Zeitman_autofill Filling out Zeitman is boring. This script might make some of the pain go away. Requirements The selenium package and Chrome webdrive

Tim Callow 8 Mar 14, 2022
A bot written in python that send prefilled Google Forms. It supports multithreading for faster execution time.

GoogleFormsBot https://flassy.xyz https://github.com/Shawey/GoogleFormsBot Requirements: os (Default) ast (Default) threading (Default) configparser (

Shawey 1 Jul 10, 2022
BSDotPy, A module to get a bombsquad player's account data.

BSDotPy BSDotPy, A module to get a bombsquad player's account data from bombsquad's servers. Badges Provided By: shields.io Acknowledgements Issues Pu

Rudransh Joshi 3 Feb 17, 2022
GitHub action to deploy serverless functions to YandexCloud

YandexCloud serverless function deploy action Deploy new serverless function version (including function creation if it does not exist). Inputs yc_acc

ะœะฝะพะณะพ ะ›ะพัะพัั 4 Apr 10, 2022
ANKIT-OS/TG-SESSION-GENERATOR-BOTbisTG-SESSION-GENERATOR-BOT a special repository. Its Is A Telegram Bot To Generate String Session

ANKIT-OS/TG-SESSION-GENERATOR-BOTbisTG-SESSION-GENERATOR-BOT a special repository. Its Is A Telegram Bot To Generate String Session

ANKIT KUMAR 1 Dec 26, 2021
The official wrapper for spyse.com API, written in Python, aimed to help developers build their integrations with Spyse.

Python wrapper for Spyse API The official wrapper for spyse.com API, written in Python, aimed to help developers build their integrations with Spyse.

Spyse 15 Nov 22, 2022
Set of classes and tools to communicate with a Noso wallet using NosoP

NosoPy Set of classes and tools to communicate with a Noso wallet using NosoP(Noso Protocol). The data that can be retrieved consist of: Node informat

Noso Project 1 Jan 10, 2022
WhatsApp Multi Device Client

WhatsApp Multi Device Client

23 Nov 18, 2022
An API Wrapper for Gofile API

Gofile2 from gofile2 import Gofile g_a = Gofile() print(g_a.upload(file="/home/itz-fork/photo.png")) An API Wrapper for Gofile API. About API Gofile

I'm Not A Bot #Left_TG 16 Dec 10, 2022