Open Bruce1979 opened 3 years ago
This can definitely be done, just haven't gotten around to it yet.
The documentation is here: https://developer.apple.com/documentation/applemusicapi/
Apple splits the API into either "catalog" or "library" resources. I have done most of the catalog endpoints, but not library which handles user libraries, playlists, etc.
Having read that and doing a bit more investigation online, it doesn't look that simple. Apparently StoreKit is ObjC only, but there's a JavaScript library out there that allows in-browser user login to create/get the user credentials necessary for a user to login and gain a user token. How this would be achieved in Python without direct access to StoreKit I'm a little uncertain about.
I'll do some further investigation, but how exactly we achieve the call to the requestUserToken(forDeveloperToken:completionHandler:)
method from native Python doesn't appear as simple, and may require some additional setup prior (in the same way it's necessary for the developer token).
I have now spent quite a bit of time working through this, and from what I can see it isn't possible to call the necessary StoreKit method i.e. requestUserToken(forDeveloperToken:completionHandler:)
unless you're using Xcode/iOS with an appropriate plist/configuration set up for that app. I can use the Developer Token easily enough to authorise my computer to access StoreKit fine, but I can't find anyway at all to have a user token issued.
Relevant API docs: https://developer.apple.com/documentation/storekit/skcloudservicecontroller/2909079-requestusertokenfordevelopertoke?language=objc
I have tried using pyobjc to call the relevant SKCloudServiceController
class function from the StoreKit API implementation there (which is how I managed to get client authorisation working), but instantiating a SKCloudServiceController object to request the user token doesn't work.
The relevant part of the code I'm currently experimenting with in the AppleMusic
class is:
"""
Generate the user token to be used in library API requests.
Set the class user token parameter
"""
StoreKit.SKCloudServiceController.requestAuthorization_(lambda x: print(x))
self.auth_status = StoreKit.SKCloudServiceController.authorizationStatus()
if self.auth_status == 3:
print("Authorization to Music Library has been granted.")
user_auth_manager = StoreKit.SKCloudServiceController.alloc().init()
user_auth_manager.requestUserTokenForDeveloperToken_completionHandler_(self.token_str, self.completionHandler)
print(self.user_token)
else:
print('Authorise access to Music Library, then try again.')
def completionHandler(self, user_token, error):
self.user_token = user_token
print(f'token: {self.user_token}')
if error:
print('Error: '+error)
else:
print('Token issued')
the auth_status of 3 correctly identifies that the client has been given permission to access the user's Apple Music library (and I get an OS prompt when that gets set), but an attempt to request the user token fails every time, and I can't for the life of me work out how to overcome it.
I'm convinced that there is something on Apple's side that refuses to provide the token unless it is being called natively from iOS 11+
Hey, Did you find a solution, to create a user token even without python or using requests ?
Dealing with the same problem rn. Spent all my time today looking at different possibilities, however, I was not even able to retrieve a valid token using the JS version. All I found was a library called social auth that would allow you to sign in to your apple account via python. However, I hadn't had the time to test it yet. Maybe there is a simpler option?!
There is the MusicKit API which solves this issue. It is a javascript library MusicKit on the Web that you can use to get the Music User Token necessary to access the users library.
I'd really like to see this API extended to allow writing to playlists for authorised users, but I'm not familiar enough with how the Apple APIs work to deal with authentication of current users etc. I assume there must be some way to allow the Developer ID being used for the API Keys to also be authenticated so a user token can be sent alongside the Apple Music token (allowing the developer to write to their own library).
Is this something we may see in the future? I'd be willing to assist where I can to make this happen (i.e. writing methods to send the post requests once the token issue is sorted out).